録音・録画
概要
クイックスタート
開発ガイド
- 想定されるエラー
- SkyWay Recording API のエラーレスポンス
- 録音・録画中のエラー
- エラーの対応方法
- エラーとなった場合の録音・録画ファイルの取得
- Google Cloud Storage
- Amazon S3
- Wasabi
- 録音・録画ファイルの修正方法
- 安全な実装方法
- サーバサイドで createChannel を行う
- Channel Name から Channel ID を取得する
- サーバサイドアプリケーションで Publication のリストを取得する
- RecordingSession の管理
- 各クラウドストレージで発生するオペレーション・リクエスト
- Google Cloud Storage
- Amazon S3
- Wasabi
- 録音のホワイトノイズを軽減させる方法
- 録音ファイルを合成する際の注意点
Tips
既知の問題
開発ガイド
想定されるエラー
録音・録画機能を利用する際に発生する可能性のあるエラーについて説明します。
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 のエラーが発生している場合は、録音・録画の処理が途中で終了している可能性があります。
クラウドストレージ側のエラー
クラウドストレージのエラーは、お使いのクラウドストレージの公式ドキュメントを参照し、原因の特定と対処を行ってください。
-
Google Cloud Storage
トラブルシューティング | Cloud Storage | Google Cloud
HTTP status and error codes for JSON | Cloud Storage | Google Cloud
-
Amazon S3
-
Wasabi
エラーの対応方法
検知方法
録音・録画処理中のエラーはメタデータの errors フィールドに出力されます。
よって、以下のいずれかの方法でエラーの検知ができます。
- GetRecordingSession API を定期的に呼び出し、レスポンスをチェックする
- 録音・録画終了後にクラウドストレージ上のメタデータファイルの内容をチェックする
再試行
Recording サーバー側で可能な限り再試行を行っています。
再試行で解決ができなかったエラーに関しては、メタデータの errors フィールドや、SkyWay 並びに各種クラウドストレージの障害情報を確認し、エラーがクラウドストレージのものであればクラウドストレージのサポートに問い合わせを行ってください。
エラーとなった場合の録音・録画ファイルの取得
録音・録画ファイルのアップロードが何らかの理由でエラーとなった場合、録音・録画ファイルのステータスは FAILED になります。ここではクラウドストレージごとに修正方法を説明します。
Google Cloud Storage
録音・録画ファイルの構造はステータスが RECORDING の場合と同様になります。 そのため録音・録画ファイルを再生する場合は分割された一時保存ファイルを結合することで再生できるようになります。 手順を次に示します。
- 対象の録音・録画ファイルの webm ファイルをすべてダウンロードします。
- ダウンロードしたファイルを次のコマンドで結合します。
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 の詳細な仕様は次の記事を参照してください。
サーバサイドで 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)が削除される
- RecordingSession は、以下のいずれかのタイミングで削除されます
- 録音・録画対象となっている Publication が unpublish される
- Publication は以下のいずれかのタイミングで unpublish されます
- 明示的に SDK の unpublish の処理を実行する
- 当該の Publication を publish している Member が Room(Channel) から退出する
- 当該の Publication が存在する Room(Channel) が削除される
- Publication は以下のいずれかのタイミングで unpublish されます
- 録音・録画開始から 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.5 | 80 | 70 | 260 | 260 |
1 | 130 | 130 | 510 | 500 |
2 | 250 | 260 | 990 | 1000 |
3 | 370 | 380 | 1480 | 1500 |
4 | 480 | 500 | 1970 | 1990 |
5 | 600 | 600 | 2460 | 2460 |
6 | 710 | 720 | 2950 | 2950 |
7 | 830 | 840 | 3440 | 3450 |
8 | 950 | 970 | 3920 | 3940 |
9 | 1060 | 1060 | 4410 | 4410 |
10 | 1180 | 1190 | 4900 | 4910 |
11 | 1300 | 1310 | 5390 | 5400 |
12 | 1410 | 1430 | 5880 | 5900 |
なお、実際に発生する料金は、バケットの設定などによって異なります。
詳しくは、Google Cloud Storage の料金ページを参照してください。
なお、録音・録画処理では、オブジェクトの書き込みだけでなく、削除の操作も行われます。したがって、Standard ストレージ以外のストレージクラスを利用している場合は、早期削除料金が発生します。録音・録画ファイルの保存先バケットには、Standard ストレージを利用することを強くおすすめします。
Amazon S3
以下の条件で録音、及び録画処理を行った場合、以下の回数の「PUT、COPY、POST、LIST リクエスト」が実行されます。
なお、リクエストの回数はあくまでも概算であり、実際の回数は状況によって増える可能性があります。
- 録音
- ビットレート約 32 kbps
- 録画
- 1920 x 1080 (FHD)
- 30 FPS
- ビットレート約 5 Mbps
録音・録画時間(時間) | 録音に伴うリクエスト回数 | 録画に伴うリクエスト回数 |
---|---|---|
0.5 | 4 | 230 |
1 | 5 | 450 |
2 | 8 | 890 |
3 | 11 | 1330 |
4 | 14 | 1770 |
5 | 17 | 2210 |
6 | 20 | 2650 |
7 | 23 | 3090 |
8 | 26 | 3530 |
9 | 29 | 3970 |
10 | 32 | 4410 |
11 | 35 | 4850 |
12 | 38 | 5290 |
なお、実際に発生する料金は、バケットの設定などによって異なります。
詳しくは、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