この文書では、RICOH Live Streaming を利用して配信した映像・音声を録画してクラウドストレージに保存するクラウド録画機能について紹介します。
クラウド録画機能は RICOH Live Streaming Conference によるブラウザで録画してローカル環境にダウンロードする機能とは異なる機能です。 この機能では、クライアントアプリによって、 RoomInstance に参加している各 Connection の映像・音声を録画を制御し、クラウドストレージに保存できます。
クラウド録画機能は、SFU 型の RoomType でのみ利用可能で、P2P 型の RoomType では利用できません。 RoomInstance に参加している各 Connection の映像・音声を録画し、クライアントアプリによって指定されたコーデックなどの設定に基づいて変換し、クラウドストレージに保存します。 録画の形態には以下の 2 パターンがあり、1 つの RoomInstance に対してそれぞれ独立・同時に実行できます。
クラウド録画機能を利用するには、クライアントアプリ側で以下の環境を準備し、これらを RICOH Live Streaming に登録する必要があります。
上記が完了していることを前提として、録画のシーケンスは以下のようになります。
これを実現するために必要な作業について以下に説明します。
RICOH Live Streaming のクラウド録画機能では、クライアントアプリ開発者の用意した AWS の S3 バケットに録画ファイルを保存します。 ここでは、以下のステップによって、録画保存用の S3 バケットの設定を RICOH Live Streaming に登録するまでの流れについて説明します。 なお、クライアントアプリ開発者が AWS のアカウントを所持している前提とします。
AWS 上で行う手順です。
S3 バケットの作成
公式のバケットの名前付けルールに従って任意の名前のバケットを作成してください。 RICOH Live Streaming の保存先として利用する S3 バケットについて、リージョンやバケット名の制約はありません。
登録用 URL の作成
RICOH Live Streaming に登録する際には、仮想ホスティング形式の URL を利用する必要があります。
https://<bucket-name>.s3.<region-code>.amazonaws.com/<key-name>
仮想ホスティング形式の仕様に従って、録画保存用の URL を作成してください。
bucket-example
バケットのrecording
以下に録画ファイルを保存する場合の URL
https://bucket-example.s3.ap-northeast-1.amazonaws.com/recording
AWS 上で行う手順です。
RICOH Live Streaming は、上記の S3 バケットにアクセスするのに、IAM ユーザーのアクセスキー ID とシークレットアクセスキーを利用します。 RICOH Live Streaming が録画ファイルを保存するために最低限必要な権限を持った IAM ユーザとアクセスキーの作成について、マネジメントコンソールを利用する方法を例に説明します。
IAM ユーザー作 成については AWS アカウント での IAM ユーザーの作成を参照し、以降の手順に従ってください。
IAM ユーザの作成を開始し、任意の IAM ユーザー名を設定して[次へ]を押します
[ポリシーを直接アタッチする]を選択し、[ポリシーの作成]ボタンからユーザーの権限を設定します
[ポリシーの作成]の画面が開くので、[JSON]を選んで JSON エディタをにポリシー設定を入力して[次へ]を押します
Resource
の<bucket-name>
および<key-name>
は置き換えてくださいResource
の最後の*
は必要です{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3Upload",
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
"Resource": ["arn:aws:s3:::<bucket-name>/<key-name>/*"]
}
]
}
任意のポリシー名を入力し[ポリシーの作成]を実行します
元の IAM ユーザーの[許可を設定]の画面に戻り、更新ボタンを押したあと、4.で入力したポリシー名を検索し、選択して[次へ]を押します
[IAM ユーザーを確認して作成]画面が表示されるので、[ユーザーの作成]を押してユーザーを作成します
作成した IAM ユーザーの画面を開き、[セキュリティ認証情報]を選択し、[アクセスキーを作成]を押します
[ユースケース]で[その他]を選択して[次へ]を押します
[説明タグを設定]は特に不要なので、そのまま[アクセスキーを作成]を押します
アクセスキーが発行されるので、アクセスキーとシークレットアクセスキーを保存しておきます
上記の手順で、S3 バケットの仮想ホスティング形式の URL と、バケットにアクセスするためのアクセスキーが作成されました。 これらを RICOH Live Streaming に登録して、録画ファイルの保存ができるようにします。
以下のような JSON ファイルを作成し、任意の名前で保存します
recording_s3_config.json
という名前で保存したとします{
"s3_url": "<S3 バケットの仮想ホスティング形式の URL>",
"access_key_id": "<アクセスキーID>",
"secret_access_key": "<シークレットアクセスキー>"
}
上記の設定を RICOH Live Streaming の録画ストレージ設定 API に登録します
curl
を利用して登録する例です<client_id>
/<client_secret>
は ClientID/ClientSecret に置き換えてくださいcurl \
-u <client_id>:<client_secret> \
-X POST \
"https://api.livestreaming.mw.smart-integration.ricoh.com/v1/clients/<client_id>/recording_storages/aws_s3/register" \
-d @recording_s3_config.json
録画ファイルの作成は、RoomInstance の終了後、非同期に行われ、長時間かかることがあります。 アプリケーションサーバーで Webhook API を実装して、この URL を Live Streaming に登録することで、録画の完了/失敗時に通知を受け取ることができます。
Webhook URL の登録はオプションで、対応しなくてもクラウド録画機能を使うことができます。 録画の完了のタイミングを正確に知る必要があったり、録画失敗の通知を受け取る必要がある場合は Webhook に対応してください。
Webhook API やそれの登録に関する仕様は アクティビティ API を参照してください。
Webhook API では以下の機能が必要です。
以下は、node.js と typescript を利用した Webhook API の実装例です。
POST /webhook
に対してリクエストを受け取ります。
サーバーのライブラリとして fastify を利用しています。
録画の完了/失敗通知メッセージの型は ActivityRecordingCompleted
および ActivityRecordingFailed
で、 API 仕様に説明があります。
import crypto from 'crypto';
import fastify from 'fastify';
import rawBody from 'fastify-raw-body';
// Webhook サーバを起動する
async function startWebhookServer(params: {
port: number;
clientSecret: string;
}) {
const { port, clientSecret } = params;
const server = fastify();
await server.register(rawBody);
// POST /webhook でリクエストを受ける
server.post('/webhook', async (req, reply) => {
console.log('webhook api is called');
const msg = req.body as any;
// RICOH Live Streaming への Webhook URL 設定の登録時に API が呼び出されるので
// 正当なクライアントアプリであることを検証するためのレスポンスを返す
if (msg.type === 'webhook.verification') {
console.log('verification event:', msg);
// チャレンジシグネチ ャの返却
return {
challenge_signature: createSignature(clientSecret, msg.challenge),
};
}
// 以降は通常の Webhook 通知時の処理
// RICOH Live Streaming からの正当な通知であることを検証
const sig = req.headers['x-ricoh-ls-signature'];
if (sig !== createSignature(clientSecret, req.rawBody as string)) {
console.error('invalid signature');
reply.status(400);
return 'invalid signature';
}
switch (msg.type) {
case 'recording.completed':
handleRecordingCompleted(msg);
break;
case 'recording.failed':
handleRecordingFailed(msg);
break;
default:
// それ以外のイベント
break;
}
return 'ok';
});
await server.listen({ port });
}
function handleRecordingCompleted(msg: any) {
// 録画完了時の処理を実行
// メッセージの型は ActivityRecordingCompleted
}
function handleRecordingFailed(msg: any) {
// 録画失敗時の処理を実行
// メッセージの型は ActivityRecordingFailed
}
// 正当性検証のためのシグネチャを作成する
function createSignature(key: string, data: string) {
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
return `sha256=${hmac.digest('hex')}`;
}
async function main() {
console.log('start webhook server');
await startWebhookServer({
port: 8000,
clientSecret: 'CLIENT_SECRET',
});
}
main();
なお、RICOH Live Streaming に登録する Webhook URL は、https://
から開始している必要があります。
すなわち、信頼された認証局によって発行された証明書を利用して TLS を終端するロードバランサーをアプリケーションサーバーの前段に配置するなどの構成が必要です。
作成した Webhook API の URL を RICOH Live Streaming に登録します。
以下のような JSON ファイルを作成し、任意の名前で保存します
webhook_config.json
という名前で保存したとします{
"webhook_url": "https://<アプリケーションサーバーのホスト名>/webhook"
}
webhook_url
のパスに /webhook
をつけているのは、上記のサンプルコードで /webhook
のパスでリクエストを受けるようにしているからです。
上記の設定を RICOH Live Streaming のアクティビティ Webhook 設定登録 API に登録します
curl
を利用して登録する例です<client_id>
/<client_secret>
は ClientID/ClientSecret に置き換えてくださいcurl \
-u <client_id>:<client_secret> \
-X POST \
"https://api.livestreaming.mw.smart-integration.ricoh.com/v1/clients/<client_id>/activity/webhook/register" \
-d @webhook_config.json
これまでに説明した準備ができている状態で、Access Token に録画の設定をすると、RoomInstance を録画できます。 Access Token の仕様の詳細については Access Token 外部仕様 を参照してください。
Connection ごとの単一拠点録画の設定と、合成録画の設定をそれぞれ独立に行うことができます。
以下では、Access Token の JWT Claims の録画設定について説明します。 クラウド録画機能以外の JWT Claims の設定に関する説明はここでは省略します。
録画するのに最低限必要な JWT Claims の設定は以下です。
room_spec
type
: sfu
または sfu_large
が必要で、P2P 型の Room では録画できませんrecording_on_start
: RoomInstance の開始とともに録画を開始する設定で、現状はこれを true
にすることによってのみ録画できますstorage
: 録画ファイルの保存先の設定で、現状は aws_s3
にする必要があります例
{
"room_spec": {
"type": "sfu", // または "sfu_large"
"recording": {
"recording_on_start": true,
"storage": "aws_s3"
}
}
}
各 Connection ごとの単一拠点録画の JWT Claims の設定は以下です。
connection_spec
recording
store
: その Connection の録画ファイルを保存するかどうかの設定で、デフォルトは true
ですformat
: 録画ファイルのフォーマットで、現状は mp4
のみサポートしており、デフォルトは mp4
ですvideo
:
codec
: ビデオコーデックの設定で、h264
と vp9
から選択でき、デフォルトは h264
ですaudio
:
codec
: オーディオコーデックの設定で、aac
と opus
から選択でき、デフォルトは aac
です例
{
"connection_spec": {
"recording": {
"store": true,
"format": "mp4",
"video": {
"codec": "h264"
},
"audio": {
"codec": "aac"
}
}
}
}
合成録画の JWT Claims の設定は以下です。
room_spec
recording
composition_recording
enabled
: 合成録画を有効にするかどうかで、デフォルトは false
ですformat
: 録画ファイルのフォーマットで、現状は mp4
のみサポートしており、デフォルトは mp4
ですvideo
:
resolution
: 合成録画の解像度を指定、詳細は Access Token 外部仕様 を参照してくださいmax_bitrate_kbps
: 合成録画のビットレートの最大値を指定、詳細は Access Token 外部仕様 を参照してくださいaudio
:
codec
: オーディオコーデックの設定で、aac
と opus
から選択でき、デフォルトは aac
ですconnection_spec
recording
composition
use_video
: 合成録画にその Connection の映像を含めるかどうかの設定で、デフォルトは true
ですuse_audio
: 合成録画にその Connection の音声を含めるかどうかの設定で、デフォルトは true
です制約として、全ての Connection の connection_spec.recording.composition.use_video
が false
の場合、合成録画は失敗します
例
{
"room_spec": {
"type": "sfu",
"recording": {
"recording_on_start": true,
"storage": "aws_s3",
"composition_recording": {
"enabled": true,
"format": "mp4",
"video": {
"resolution": "auto",
"max_bitrate_kbps": "auto"
},
"audio": {
"codec": "aac"
}
}
}
},
"connection_spec": {
"recording": {
"composition": {
"use_video": true,
"use_audio": true
}
}
}
}
正しい Access Token が設定されて RoomInstance が実行されると、RoomInstance の終了後に、登録された AWS S3 バケットに録画ファイルが出力されます。 ただし、録画ファイルの作成は、RoomInstance の終了後、非同期に行われ、長時間かかることがあります。
出力されるファイルパスの仕様は、録画 API 仕様のディレクトリ構成仕様を参照してください。 出力されるファイルは、各 Connection ごとの単一拠点録画ファイルと合成録画ファイル、および、それらの録画ファイルの情報が記載されたメタデータファイル (JSON) です。
また、録画 API 仕様に記載の通り、保存先の S3 オブジェクトのキー名に room_id
が含まれます。
room_id
の仕様は IDString なので、S3 のオブジェクトキー名に使用しないほうが良い文字の一部を利用でき、指定された room_id
を含むキー名に対して録画ファイルが保存されます。
その場合、AWS のドキュメントに記載されているように、S3 オブジェクトの取り扱いにはクライアントアプリ側で特殊な処理が必要になる可能性があります。
クライアントアプリでの特殊な処理を避けたい場合は、これらの文字を含めずに room_id
を作成してください。
この情報は役に立ちましたか?