開発ガイド

想定されるエラー

録音・録画機能を利用する際に発生する可能性のあるエラーについて説明します。

SkyWay Recording API のエラーレスポンス

400

リクエストに含まれるパラメータに問題があります。ドキュメントを参照して正しい値をパラメータに入れるように修正してください。

401

有効な SkyWay Admin Auth Token が使用されていません。SkyWay Admin Auth Token のドキュメントを参照して正しいトークンを使用してください。

403

クラウドストレージのクレデンシャルに対応する権限が不足しており、クラウドストレージを正常に利用できません。各クラウドストレージに必要な資格情報の項目を参照して正しいクレデンシャルを使用してください。

404

対象のリソースが存在しません。

429

レートリミットもしくはリソース量の制限に違反しています。制限と割当の項目に記載されている範囲内で利用してください。

500

Recording サーバーにおいてエラーが発生しています。リクエストの処理が完了していない可能性があるため、リクエストを再試行してください。 特に、 DeleteRecordingSession の場合は、録音・録画の処理が停止せず、意図しない料金が発生する可能性があります。 複数回再試行を行なってもエラーが解消しない場合は、SkyWay のサポートに問い合わせてください。

録音・録画中のエラー

録音・録画処理において、各種クラウドストレージに録音・録画ファイルをアップロードする際に、何らかのエラーが発生した場合、再試行して解決可能な場合は自動的に再試行を行います。再試行して解決できなかった場合、録音・録画が中断され、新しい録音・録画ファイルとして一度だけ再開されます。

再試行に失敗した場合、録音・録画ファイルのメタデータの status が FAILED になり、errors フィールドにエラーの内容が追記されます。

格納されるエラーは大きく分けて 2 種類あり、1 つは SkyWay 側のエラー、もう 1 つはクラウドストレージ側のエラーです。

SkyWay 側のエラー

SkyWay のエラーは Internal Server Error: という文字列から始まります。

SkyWay のエラーが発生している場合は、録音・録画の処理が途中で終了している可能性があります。

クラウドストレージ側のエラー

クラウドストレージのエラーは、お使いのクラウドストレージの公式ドキュメントを参照し、原因の特定と対処を行ってください。

エラーの対応方法

検知方法

録音・録画処理中のエラーはメタデータの errors フィールドに出力されます。

よって、以下のいずれかの方法でエラーの検知ができます。

  • GetRecordingSession API を定期的に呼び出し、レスポンスをチェックする
  • 録音・録画終了後にクラウドストレージ上のメタデータファイルの内容をチェックする

再試行

Recording サーバー側で可能な限り再試行を行っています。

再試行で解決ができなかったエラーに関しては、メタデータの errors フィールドや、SkyWay 並びに各種クラウドストレージの障害情報を確認し、エラーがクラウドストレージのものであればクラウドストレージのサポートに問い合わせを行ってください。

エラーとなった場合の録音・録画ファイルの取得

録音・録画ファイルのアップロードが何らかの理由でエラーとなった場合、録音・録画ファイルのステータスは FAILED になります。ここではクラウドストレージごとに修正方法を説明します。

Google Cloud Storage

録音・録画ファイルの構造はステータスが RECORDING の場合と同様になります。 そのため録音・録画ファイルを再生する場合は分割された一時保存ファイルを結合することで再生できるようになります。 手順を次に示します。

  1. 対象の録音・録画ファイルの webm ファイルをすべてダウンロードします。
  2. ダウンロードしたファイルを次のコマンドで結合します。
ls -v *.webm | xargs cat > output.webm

Amazon S3

録音・録画したデータを Amazon S3 に保存する際は、MultipartUpload という仕組みを利用します。MultipartUpload がエラーとなった場合は、Amazon S3 に MultipartUpload のデータが残り続ける可能性があります。

エラー発生時点までのデータをファイルとして保存したい場合は、CompleteMultipartUpload の操作を行い、MultipartUpload の処理を完了させる必要があります。

また、MultipartUpload のデータは課金対象となります。エラー発生時点までのデータが不要な場合は、バケットライフサイクルによる自動削除の設定を行うか、AbortMultipartUpload の操作を行い、MultipartUpload を完全に終了させてください。

本記事では、AWS CLI を用いて、CompleteMultipartUpload の操作を行いエラー発生時点までのデータをファイルとして保存する方法と、AbortMultipartUpload の操作を行い MultipartUpload を完全に終了させる方法について説明します。

バケットライフサイクルによる自動削除の設定については、Amazon S3 のドキュメントを参照してください。

不完全なマルチパートアップロードを削除するためのバケットライフサイクル設定の設定 - Amazon Simple Storage Service

不完全なマルチパートアップロードをクリーンアップするための Amazon S3 ライフサイクル設定ルールを検証する

また、本記事で説明している内容は、変更されている可能性があります。

必要に応じて、Amazon S3 の公式ドキュメントを参照してください。

マルチパートアップロードを使用したオブジェクトのアップロードとコピー - Amazon Simple Storage Service

エラー発生時点までのデータをファイルとして保存する方法

  • 以下のコマンドを実行し、MultipartUpload のリストを取得します。 aws s3api list-multipart-uploads --bucket <bucket name>
  • 実行結果の Uploads の中から、対象の Key と UploadId を選択します。
  • 次に、以下のコマンドを実行し、MultipartUpload に含まれる Parts のリストを取得します。 aws s3api list-parts --bucket <bucket name> --key <Key> --upload-id <UploadId>
  • 実行結果の Parts の中から、PartNumber と ETag の組を全て選択します。
  • 次に、以下のコマンドを実行し、エラー発生時点までの MultipartUpload のデータをファイルとして保存します。 aws s3api complete-multipart-upload --multipart-upload 'Parts=[{ETag="<ETag_1>",PartNumber=<PartNumber_1>},{ETag="<ETag_2>",PartNumber=<PartNumber_2>}, ... ]' --bucket <bucket name> --key <Key> --upload-id <UploadId>

なお、Parts には、list-parts で取得した Parts を全て指定してください。

MultipartUpload を完全に終了させる方法

  • 以下のコマンドを実行し、MultipartUpload のリストを取得します。 aws s3api list-multipart-uploads --bucket <bucket name>
  • 実行結果の Uploads の中から、対象の Key と UploadId を選択します。
  • 以下のコマンドを実行し、MultipartUpload を完全に終了させます。これにより、MultipartUpload のデータが削除されます。 aws s3api abort-multipart-upload --bucket <bucket name> --key <Key> --upload-id <UploadId>

Wasabi

録音・録画したデータを Wasabi に保存する際は、MultipartUpload という仕組みを利用します。MultipartUpload がエラーとなった場合は、Wasabi に MultipartUpload のデータが残り続ける可能性があります。

エラー発生時点までのデータをファイルとして保存したい場合は、CompleteMultipartUpload の操作を行い、MultipartUpload の処理を完了させる必要があります。

また、MultipartUpload のデータは課金対象となります。エラー発生時点までのデータが不要な場合は、AbortMultipartUpload の操作を行い、MultipartUpload を完全に終了させてください。

なお、Wasabi では、中断された MultipartUpload のデータは30 日後に自動で削除されます。

本記事では、AWS CLI を用いて、CompleteMultipartUpload の操作を行いエラー発生時点までのデータをファイルとして保存する方法と、AbortMultipartUpload の操作を行い MultipartUpload を完全に終了させる方法について説明します。

また、本記事で説明している内容は、変更されている可能性があります。

必要に応じて、Wasabi の公式ドキュメントを参照してください。

How do I clean up my failed multipart uploads? – Wasabi Knowledge Base

エラー発生時点までのデータをファイルとして保存する方法

  • 以下のコマンドを実行し、MultipartUpload のリストを取得します。 aws s3api list-multipart-uploads --bucket <bucket name> --endpoint-url=<wasabi endpoint>
  • 実行結果の Uploads の中から、対象の Key と UploadId を選択します。
  • 次に、以下のコマンドを実行し、MultipartUpload に含まれる Parts のリストを取得します。 aws s3api list-parts --bucket <bucket name> --key <Key> --upload-id <UploadId> --endpoint-url=<wasabi endpoint>
  • 実行結果の Parts の中から、PartNumber と ETag の組を全て選択します。
  • 次に、以下のコマンドを実行し、エラー発生時点までの MultipartUpload のデータをファイルとして保存します。 aws s3api complete-multipart-upload --multipart-upload 'Parts=[{ETag="<ETag_1>",PartNumber=<PartNumber_1>},{ETag="<ETag_2>",PartNumber=<PartNumber_2>}, ... ]' --bucket <bucket name> --key <Key> --upload-id <UploadId> --endpoint-url=<wasabi endpoint>

なお、Parts には、list-parts で取得した Parts を全て指定してください。

MultipartUpload を完全に終了させる方法

  • 以下のコマンドを実行し、MultipartUpload のリストを取得します。 aws s3api list-multipart-uploads --bucket <bucket name> --endpoint-url=<wasabi endpoint>
  • 実行結果の Uploads の中から、対象の Key と UploadId を選択します。
  • 以下のコマンドを実行し、MultipartUpload を完全に終了させます。これにより、MultipartUpload のデータが削除されます。 aws s3api abort-multipart-upload --bucket <bucket name> --key <Key> --upload-id <UploadId> --endpoint-url=<wasabi endpoint>

録音・録画ファイルの修正方法

保存先クラウドストレージとして Amazon S3、または Wasabi を利用し、保存された録音・録画ファイルを再生する際に次のような事象が発生します。

  • ファイルの総再生時間が実際の録音・録画時間と大きく異なる
    • 総再生時間が 1 時間と表示される
  • シーク機能が適切に機能しない

また、ファイルが破損していると表示されることがあります。

これは、録音・録画の処理に起因するもので、メディアデータ自体は正常に保存されています。

録音・録画ファイルを正常に再生するためには、ffmpeg というツールを用いて、記録された録音・録画ファイルに対して以下の処理を実行することで、正常に再生できるようになります。

ffmpeg -i original.webm -c copy -y fixed.webm

なお、ffmpeg のインストール方法については、ffmpeg の公式ドキュメントを参照してください。

映像のコーデックにH264を利用している場合は、ffmpegが直接処理できないので次のように拡張子を一旦変更してから処理してください。

mv original.webm original.mkv ffmpeg -i original.mkv -c copy -y fixed.mkv mv fixed.mkv fixed.webm

安全な実装方法

録音・録画機能を安全に利用するための注意事項について説明します。

録音・録画機能を利用する際に扱う ID として以下があります。

  • Channel ID
  • Publication ID

これらの ID をクライアントサイドからサーバーサイドアプリケーションへ送信して録音・録画を開始する場合、送信者が ID を差し替えることで意図しない Publication が録音・録画される可能性があります。

これらの ID をクライアントサイドから取得する代わりに次の手法を採用することを検討してください。なお、ここで使用する SkyWay Channel API の詳細な仕様は次の記事を参照してください。

SkyWay Channel API

サーバサイドで createChannel を行う

createChannel をクライアントサイドではなくサーバーサイドアプリケーションで SkyWay Channel API を用いて実行することで常に正しい Channel ID を得る事ができます。

次のようにして SkyWay Channel API で createChannel を行うことができます。

curl -X POST https://channel.skyway.ntt.com/v1/json-rpc \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_SKYWAY_ADMIN_AUTH_TOKEN" \ -d '{ "jsonrpc": "2.0", "id": "YOUR_RANDOM_UUID", "method": "createChannel", "params": { "name": "YOUR_CHANNEL_NAME" }}'

Channel Name から Channel ID を取得する

サーバーサイドアプリケーションで Channel Name を払い出している場合に有効な手法です。

Channel Name はサーバーサイドアプリケーションで払い出すことができるため、 SkyWay Auth Token でその Channel Name を指定していれば、Channel Name は信用できる情報として扱うことができます。 また、SkyWay Channel API の findChannel で name として Channel Name を指定することで、Channel ID を取得できます。

次のようにして SkyWay Channel API で Channel Name から Channel ID を取得できます。

curl -X POST https://channel.skyway.ntt.com/v1/json-rpc \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_SKYWAY_ADMIN_AUTH_TOKEN" \ -d '{ "jsonrpc": "2.0", "id": "YOUR_RANDOM_UUID", "method": "findChannel", "params": { "name": "YOUR_CHANNEL_NAME" }}'\ | jq -r '.result.channel.id'

サーバサイドアプリケーションで Publication のリストを取得する

録音・録画対象の Publication の ID を指定する場合はクライアントサイドからサーバーサイドアプリケーションに Publication の ID を送信するのではなく、SkyWay Channel API を用いて信用できる Publication のリストを取得することをおすすめします。

次のようにして SkyWay Channel API で Publication のリストを取得できます。

curl -X POST https://channel.skyway.ntt.com/v1/json-rpc \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_SKYWAY_ADMIN_AUTH_TOKEN" \ -d '{ "jsonrpc": "2.0", "id": "YOUR_RANDOM_UUID", "method": "findChannel", "params": { "name": "YOUR_CHANNEL_NAME" }}' \ | jq -r '.result.channel.publications'

RecordingSession の管理

RecordingSession が作成されると、以下のいずれかの状況になるまでは録音・録画の処理が継続され、指定されたクラウドストレージに対して録音・録画ファイルの送信が行われます。

  • RecordingSession が削除される
    • RecordingSession は、以下のいずれかのタイミングで削除されます
      • DeleteRecordingSession API を呼び出す
      • RecordingSession 作成から 7 日間が経過する
      • RecordingSession と紐づく Room(Channel)が削除される
  • 録音・録画対象となっている Publication が unpublish される
    • Publication は以下のいずれかのタイミングで unpublish されます
      • 明示的に SDK の unpublish の処理を実行する
      • 当該の Publication を publish している Member が Room(Channel) から退出する
      • 当該の Publication が存在する Room(Channel) が削除される
  • 録音・録画開始から 12 時間経過する

これらのうち、サーバーサイドアプリケーションから録音・録画処理を停止させる方法は、DeleteRecordingSession API を利用し、RecordingSession の削除を行うことです。

したがって、DeleteRecordingSession API を利用するための、以下の情報は適切に管理・記録する必要があります。

  • Channel ID
  • RecordingSession ID

これらの情報を紛失してしまうと、録音・録画開始から 12 時間が経過するか、Publication が unpublish されるまでは録音・録画の処理が行われ、課金が発生し続けてしまいます。サーバーサイドアプリケーションから録音・録画処理を停止させたい場合は、上記の情報を適切に管理・記録するようにしてください。

各クラウドストレージで発生するオペレーション・リクエスト

SkyWay の録音・録画機能では、録音・録画ファイルのアップロード先としてユーザーのクラウドストレージを使用します。したがって、ユーザー側でクラウドストレージのオペレーション・リクエストに伴う料金が発生します。オペレーション・リクエストに伴う料金は、その種類と回数によって決まります。

本記事では、録音・録画機能を利用する際に発生するオペレーション・リクエストの種類と回数について説明します。

Google Cloud Storage

以下の条件で録音、及び録画処理を行った場合、以下の回数のオペレーションが実行されます。

なお、オペレーションの回数はあくまでも概算であり、実際の回数は状況によって増える可能性があります。

  • 録音
    • ビットレート約 32 kbps
  • 録画
    • 1920 x 1080 (FHD)
    • 30 FPS
    • ビットレート約 5 Mbps
録音・録画時間(時間)録音に伴うクラス A オペレーション回数録音に伴うクラス B オペレーション回数録画に伴うクラス A オペレーション回数録画に伴うクラス B オペレーション回数
0.58070260260
1130130510500
22502609901000
337038014801500
448050019701990
560060024602460
671072029502950
783084034403450
895097039203940
91060106044104410
101180119049004910
111300131053905400
121410143058805900

なお、実際に発生する料金は、バケットの設定などによって異なります。

詳しくは、Google Cloud Storage の料金ページを参照してください。

なお、録音・録画処理では、オブジェクトの書き込みだけでなく、削除の操作も行われます。したがって、Standard ストレージ以外のストレージクラスを利用している場合は、早期削除料金が発生します。録音・録画ファイルの保存先バケットには、Standard ストレージを利用することを強くおすすめします。

Amazon S3

以下の条件で録音、及び録画処理を行った場合、以下の回数の「PUT、COPY、POST、LIST リクエスト」が実行されます。

なお、リクエストの回数はあくまでも概算であり、実際の回数は状況によって増える可能性があります。

  • 録音
    • ビットレート約 32 kbps
  • 録画
    • 1920 x 1080 (FHD)
    • 30 FPS
    • ビットレート約 5 Mbps
録音・録画時間(時間)録音に伴うリクエスト回数録画に伴うリクエスト回数
0.54230
15450
28890
3111330
4141770
5172210
6202650
7233090
8263530
9293970
10324410
11354850
12385290

なお、実際に発生する料金は、バケットの設定などによって異なります。

詳しくは、Amazon S3 の料金ページを参照してください。

Wasabi

Wasabi では、リクエスト回数に伴う料金は発生しません。

録音のホワイトノイズを軽減させる方法

Opus DTX を有効化した状態で録音を行うと、録音ファイルにホワイトノイズが含まれる場合があります。

Opus DTX は、音声が無音に近い状態の場合に、送信されるデータ量を大幅に削減するための機能です。 Recording サーバーでは、 Opus DTX が有効になっている場合でも正常にファイルを保存できるようにするための処理を行っています。 これにより、特に音声が無音に近い状態となっていた箇所でホワイトノイズが含まれる可能性があります。

Opus DTX はデフォルトで有効となっているため、Opus DTX を無効化する際は Publication の publish 時に明示的に設定する必要があります。 Opus DTX を無効化する方法は、各 SDK のドキュメントを参照してください。

録音ファイルを合成する際の注意点

FFmpeg などのツールで録音ファイルを合成すると、 Opus の仕様により音ズレが発生する可能性があります。

次のようにリサンプリングを行うことでこの問題を回避できます。

ffmpeg \ -i audio_1.webm \ -i audio_2.webm \ -i audio_3.webm \ -filter_complex \ "[0:a]aresample=async=1:first_pts=0, aformat=channel_layouts=stereo[a0]; \ [1:a]aresample=async=1:first_pts=0, aformat=channel_layouts=stereo[a1]; \ [2:a]aresample=async=1:first_pts=0, aformat=channel_layouts=stereo[a2]; \ [a0][a1][a2]amerge=inputs=3[out]" \ -map "[out]" \ -ac 2 \ output.m4a