Bluesky API(XRPC)でビデオアップロードする方法の情報です。2025年2月現在の情報になります。
内容のほとんどは参考情報に挙げている、すぎゃーんさんとSamuelさんと山貂さんの情報に基づいております。すぎゃーんさんとSamuelさんと山貂さんに御礼申し上げます。ただし当記事の編集の責は当方にあります。
概要
ビデオサービス関連のapp.bsky.video.*
で定義されているAPI(XRPC)群を利用します。
APIメソッド | 概要 |
---|---|
app.bsky.video.getUploadLimits | アップロード制限情報取得 |
app.bsky.video.uploadVideo | ビデオアップロード |
app.bsky.video.getJobStatus | ビデオアップロードジョブ状態取得 |
ビデオサービス関連APIでは、他の多くのAPIと異なりリクエスト先はビデオサービスのエンドポイント(公式提供の場合https://video.bsky.app/xrpc/
)となります。
また多くのAPIでは、リクエスト時の認可トークンとしてcom.atproto.server.createSession
によるセッションJWTを指定しますが、ビデオサービスのリクエストではcom.atproto.server.getServiceAuth
によって取得した認可トークンを指定する必要があります。
なおuploadVideo
を除き、atproto-proxyを用いてPDS経由のリクエストとすることも可能です(本稿では説明しません)。
以降にこれらの利用について説明を記します。必要に応じて後半に記載している処理フロー図も合わせて参照すると理解の助けになるかもしれません。
API呼び出しとパラメタ
概要で前述しましたようにリクエスト先エンドポイントについては注意してください。
アップロード制限情報取得 (app.bsky.video.getUploadLimits)
- サービス認可トークン取得
リクエスト先は他の多くのAPIと同じエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
com.atproto.server.getServiceAuth | aud | 'did:web:video.bsky.app' | ビデオサービスを示す識別子 |
exp | 認可有効期限 | 期限を示すUNIX時刻 省略時は60秒後 | |
lxm | 'app.bsky.video.getUploadLimits' | 認可取得対象APIメソッドのlexicon |
- アップロード制限情報取得
リクエスト先はビデオサービスのエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
app.bsky.video.getUploadLimits | Bearer | 取得したサービス認可トークン | HTTP Authorization ヘッダへの設定 |
ビデオアップロード (app.bsky.video.uploadVideo)
- サービス認可トークン取得
リクエスト先は他の多くのAPIと同じエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
com.atproto.server.getServiceAuth | aud | 'did:web:<サービスエンドポイントドメイン>' | 所属PDSサーバDID *1 |
exp | 認可有効期限 | 期限を示すUNIX時刻 省略時は60秒後 | |
lxm | 'com.atproto.repo.uploadBlob' | 認可取得対象APIメソッドのlexicon *2 |
*1: https://plc.directory/<ユーザDID>
へのHTTPリクエストのレスポンス(service[].serviceEndpoint
)に含まれる、(ビデオアップロードする)ユーザが所属するPDS URLのドメイン部
*2: app.bsky.video.uploadVideo
ではないので注意
- ビデオアップロード
リクエスト先はビデオサービスのエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
app.bsky.video.uploadVideo | Bearer | 取得したサービス認可トークン | HTTP Authorization ヘッダへの設定 |
did | (ビデオアップロードする)ユーザDID | ||
name | ビデオ名 | ビデオファイル名など | |
BODY | ビデオデータ | HTTP POSTボディ |
ビデオアップロードジョブ状態取得 (app.bsky.video.getJobStatus)
- サービス認可トークン取得
リクエスト先は他の多くのAPIと同じエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
com.atproto.server.getServiceAuth | aud | 'did:web:video.bsky.app' | ビデオサービスを示す識別子 |
exp | 認可有効期限 | 期限を示すUNIX時刻 省略時は60秒後 | |
lxm | 'app.bsky.video.getJobStatus' | 認可取得対象APIメソッドのlexicon |
- ビデオアップロードジョブ状態取得
リクエスト先はビデオサービスのエンドポイントです。
APIメソッド | パラメタ名 | パラメタ値 | 備考 |
---|---|---|---|
app.bsky.video.getJobStatus | Bearer | 取得したサービス認可トークン | HTTP Authorization ヘッダへの設定 |
jobId | uploadVideo のレスポンスに含まれるjobStats.jobId の値 |
各処理の詳細
詳細:アップロード制限情報取得 (app.bsky.video.getUploadLimits)
サーバ負荷軽減やユーザ体験向上のために可能な処理ですが、アップロードのために必須の処理ではありません。
まず前述の通り、getServiceAuth
を呼び出して認可トークンを取得します。その認可トークンをgetUploadLimits
呼び出し時にHTTP Authorization
ヘッダのBearer
トークンとして指定します。
レスポンスには、アップロード可否、1日当たりの残存アップロードサイズ、1日当たりの残存アップロード数等が含まれるので参考にします。
レスポンス例:
{
"canUpload":true,
"message":"User can upload",
"remainingDailyBytes":40000000000,
"remainingDailyVideos":100
}
なおatproto-proxyを用いてPDS経由でgetUploadLimits
をリクエストする場合は、getServiceAuth
の呼び出しは不要となります。
詳細:ビデオアップロード (app.bsky.video.uploadVideo)
まず前述の通り、getServiceAuth
を呼び出して認可トークンを取得します。その認可トークンをuploadVideo
呼び出し時にHTTP Authorization
ヘッダのBearer
トークンとして指定します。
注意が必要なのは、getServiceAuth
呼び出し時のaud
パラメタとして指定するサービスDIDとして、'did:web:video.bsky.app'
ではなく、ビデオアップロードを行うユーザが所属するPDSのDIDであることです。ユーザのPDS URLはhttps://plc.directory/<ユーザのDID>
にリクエストするとレスポンス(service[].serviceEndpoint
)として得られます。PDS URLからドメインを抽出し、プレフィクスとしてdid:web:
を付与することによって、aud
パラメタに指定するサービスDIDを構成します(did:web:<PDSドメイン>
)。
例:
(PDS URL)
https://verpa.us-west.host.bsky.network
(サービスDID)
did:web:verpa.us-west.host.bsky.network
またlxm
パラメタとして指定するXRPC lexicon文字列が、'app.bsky.video.uploadVideo'
ではなく、'com.atproto.repo.uploadBlob'
であることも注意が必要です。
これらについては、uploadVideo
のリクエストを受けたビデオサービスが、その中でPDSへのアップロード(uploadBlob
)を行うことによります。後述の処理フロー図においてその背景がイメージできるかと思います。
app.bsky.video.uploadVideoのAPIリファレンスでは、特にクエリパラメタは示されていませんが、実際には前述のようにdid
、name
のクエリパラメタを指定する必要があります。did
にはビデオアップロードを行うユーザのDIDを指定し、name
にはビデオの名前(ファイル名でよいでしょう)を指定します。
またAPIリファレンスではレスポンスのjobStatus.state
が取りうる値としてJOB_STATE_COMPLETED
、JOB_STATE_FAILED
が挙げられていますが、正常な場合の多くはJOB_STATE_CREATED
となるようです。この場合は後続のapp.bsky.video.getJobStatus
にて処理完了を待ち合わせてjobStatus.blob
の値を得るようにします。
同じビデオデータをアップロードすると、レスポンスのHTTPステータスコードが409
(Conflict
)となります。その場合レスポンスペイロードのjobStatus.state
がJOB_STATE_COMPLETED
、jobStatus.error
が"already_exists"
、jobStatus.message
が"Video already processed"
という値になるようです。この場合もjobStatus.jobId
にjobIdが入っており、app.bsky.video.getJobStatus
に指定して呼び出すことによって、jobStatus.blob
の値を得ることができます。
なおgetUploadLimits
、getJobStatus
と異なり、uploadVideo
ではatproto-proxyを用いてPDS経由のリクエストをすることはできません。
詳細:ビデオアップロードジョブ状態取得 (app.bsky.video.getJobStatus)
まず前述の通り、getServiceAuth
を呼び出して認可トークンを取得します。その認可トークンをgetJobStatus
呼び出し時にHTTP Authorization
ヘッダのBearer
トークンとして指定します。
app.bsky.video.getJobStatusのAPIリファレンスでは、レスポンスのjobStatus.state
が取りうる値としてJOB_STATE_COMPLETED
、JOB_STATE_FAILED
が挙げられていますが、以下のようなバリエーションがあるようです。
jobStatus.state | 概要 | 備考 |
---|---|---|
JOB_STATE_COMPLETED | ジョブ完了 | jobStatus.blob にポスト(createRecord )での$type:app.bsky.embed.video 配下のvideo に指定するJSONオブジェクトが格納される |
JOB_STATE_FAILED | ジョブ失敗終了 | |
JOB_STATE_ENCODING | エンコード処理中 | jobStatus.progress に進捗割合(%)が格納される |
JOB_STATE_SCANNING | スキャン処理中 | エンコード処理完了後にこの状態になり、スキャン処理の後に処理完了となる |
uploadVideo
後に適切な頻度でgetJobStatus
を呼び出して処理完了を待つことになります。
getJobStatus
に指定する認可トークンは、getServiceAuth
で指定した認可有効期限に依存します。そのため同じ認可トークンを使い続けると、ジョブが認可有効期限を超過した場合にgetJobStatus
呼び出しが(おそらく)失敗します。このため認可有効期限を長めにしたり、適度に認可トークンを再取得することも考えられます。
なおatproto-proxyを用いてPDS経由でgetJobStatus
をリクエストする場合は、getServiceAuth
の呼び出しは不要となります。
処理フロー図
- 簡易版(
getUploadLimits
省略)
- 詳細版(
getUploadLimits
実施、各種補足説明の追記)
ビデオサービス(app.bsky.video.*
)を利用しない方法
当記事の元となる、すぎゃーんさんの解説からリンクされているSamuelさん情報によると、これまでに記載したビデオサービスを利用した方法の他に、com.atproto.repo.uploadBlob
でアップロードする方法もあるようです。
ただしgetJobStatus
を利用した方法では非同期処理を制御できますが、uploadBlob
による方法ではポスト処理との間で制御できないタイムラグが生じるため、推奨されないようです。
参考:ポスト時のaspectRatio
ポスト(createRecord
)での$type:app.bsky.embed.video
配下にアスペクト比(aspectRatio
)要素が存在します。この要素は省略可能ですが、たとえば縦長のビデオではクライアントによっては左右両側に黒い帯が表示されるなど、見た目が最適化されない可能性があります。
参考情報
すぎゃーんさん情報
Samuelさん情報
山貂さん情報
APIリファレンス
- app.bsky.video.getJobStatus
- app.bsky.video.getUploadLimits
- app.bsky.video.uploadVideo
- com.atproto.server.getServiceAuth
lexicon
変更履歴
(2025-02-17)
- 新規作成
(2025-02-21)
- PDS URLについてplc.directoryのレスポンス内パスを追記
- ビデオサービス関連APIのリクエスト先が他の多くのAPIと異なり、ビデオサービスエンドポイント(公式の場合
https://video.bsky.app/xrpc/<API名>
)であることを追記 getUploadLimits
、getJobStatus
の詳細においてatproto-proxyを利用したPDS経由リクエストも可能であることを追記uploadVIdeo
でのgetServiceAuth
パラメタが他のビデオサービス関連APIと異なることの補足を追記uploadVideo
の詳細においてatproto-proxyを利用したPDS経由リクエストができないことを追記- 処理フロー図を追加
- 山貂さん情報を追加
- その他誤字修正