Bluesky API(XRPC)でビデオアップロード

@bills-appworks.blue

Contents changed

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)

  1. サービス認可トークン取得

リクエスト先は他の多くのAPIと同じエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
com.atproto.server.getServiceAuthaud'did:web:video.bsky.app'ビデオサービスを示す識別子
exp認可有効期限期限を示すUNIX時刻
省略時は60秒後
lxm'app.bsky.video.getUploadLimits'認可取得対象APIメソッドのlexicon
  1. アップロード制限情報取得

リクエスト先はビデオサービスのエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
app.bsky.video.getUploadLimitsBearer取得したサービス認可トークンHTTP Authorizationヘッダへの設定

ビデオアップロード (app.bsky.video.uploadVideo)

  1. サービス認可トークン取得

リクエスト先は他の多くのAPIと同じエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
com.atproto.server.getServiceAuthaud'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ではないので注意

  1. ビデオアップロード

リクエスト先はビデオサービスのエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
app.bsky.video.uploadVideoBearer取得したサービス認可トークンHTTP Authorizationヘッダへの設定
did(ビデオアップロードする)ユーザDID
nameビデオ名ビデオファイル名など
BODYビデオデータHTTP POSTボディ

ビデオアップロードジョブ状態取得 (app.bsky.video.getJobStatus)

  1. サービス認可トークン取得

リクエスト先は他の多くのAPIと同じエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
com.atproto.server.getServiceAuthaud'did:web:video.bsky.app'ビデオサービスを示す識別子
exp認可有効期限期限を示すUNIX時刻
省略時は60秒後
lxm'app.bsky.video.getJobStatus'認可取得対象APIメソッドのlexicon
  1. ビデオアップロードジョブ状態取得

リクエスト先はビデオサービスのエンドポイントです。

APIメソッドパラメタ名パラメタ値備考
app.bsky.video.getJobStatusBearer取得したサービス認可トークンHTTP Authorizationヘッダへの設定
jobIduploadVideoのレスポンスに含まれる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リファレンスでは、特にクエリパラメタは示されていませんが、実際には前述のようにdidnameのクエリパラメタを指定する必要があります。didにはビデオアップロードを行うユーザのDIDを指定し、nameにはビデオの名前(ファイル名でよいでしょう)を指定します。

またAPIリファレンスではレスポンスのjobStatus.stateが取りうる値としてJOB_STATE_COMPLETEDJOB_STATE_FAILEDが挙げられていますが、正常な場合の多くはJOB_STATE_CREATEDとなるようです。この場合は後続のapp.bsky.video.getJobStatusにて処理完了を待ち合わせてjobStatus.blobの値を得るようにします。

同じビデオデータをアップロードすると、レスポンスのHTTPステータスコードが409(Conflict)となります。その場合レスポンスペイロードのjobStatus.stateJOB_STATE_COMPLETEDjobStatus.error"already_exists"jobStatus.message"Video already processed"という値になるようです。この場合もjobStatus.jobIdにjobIdが入っており、app.bsky.video.getJobStatusに指定して呼び出すことによって、jobStatus.blobの値を得ることができます。

なおgetUploadLimitsgetJobStatusと異なり、uploadVideoではatproto-proxyを用いてPDS経由のリクエストをすることはできません。

詳細:ビデオアップロードジョブ状態取得 (app.bsky.video.getJobStatus)

まず前述の通り、getServiceAuthを呼び出して認可トークンを取得します。その認可トークンをgetJobStatus呼び出し時にHTTP AuthorizationヘッダのBearerトークンとして指定します。

app.bsky.video.getJobStatusのAPIリファレンスでは、レスポンスのjobStatus.stateが取りうる値としてJOB_STATE_COMPLETEDJOB_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省略)

image

  • 詳細版(getUploadLimits実施、各種補足説明の追記)

image

ビデオサービス(app.bsky.video.*)を利用しない方法

当記事の元となる、すぎゃーんさんの解説からリンクされているSamuelさん情報によると、これまでに記載したビデオサービスを利用した方法の他に、com.atproto.repo.uploadBlobでアップロードする方法もあるようです。

ただしgetJobStatusを利用した方法では非同期処理を制御できますが、uploadBlobによる方法ではポスト処理との間で制御できないタイムラグが生じるため、推奨されないようです。

参考:ポスト時のaspectRatio

ポスト(createRecord)での$type:app.bsky.embed.video配下にアスペクト比(aspectRatio)要素が存在します。この要素は省略可能ですが、たとえば縦長のビデオではクライアントによっては左右両側に黒い帯が表示されるなど、見た目が最適化されない可能性があります。

参考情報

すぎゃーんさん情報

Samuelさん情報

山貂さん情報

APIリファレンス

lexicon


変更履歴

(2025-02-17)

  • 新規作成

(2025-02-21)

  • PDS URLについてplc.directoryのレスポンス内パスを追記
  • ビデオサービス関連APIのリクエスト先が他の多くのAPIと異なり、ビデオサービスエンドポイント(公式の場合https://video.bsky.app/xrpc/<API名>)であることを追記
  • getUploadLimitsgetJobStatusの詳細においてatproto-proxyを利用したPDS経由リクエストも可能であることを追記
  • uploadVIdeoでのgetServiceAuthパラメタが他のビデオサービス関連APIと異なることの補足を追記
  • uploadVideoの詳細においてatproto-proxyを利用したPDS経由リクエストができないことを追記
  • 処理フロー図を追加
  • 山貂さん情報を追加
  • その他誤字修正
bills-appworks.blue
びるず

@bills-appworks.blue

https://bills-appworks.net/
シェルスクリプト実装版Bluesky CLIクライアント bsky-sh-cli (Bluesky in the shell)を開発しています: https://github.com/bills-appworks/bsky-sh-cli
bsky-sh-cli広報アカウント: @bsky-sh-cli.bills-appworks.net
Linkat: https://linkat.blue/bills-appworks.blue

Post reaction in Bluesky

*To be shown as a reaction, include article link in the post or add link card

Reactions from everyone (0)