本文にスキップする

グループ通話のメディアサブスクリプション

Planet Cloudプラットフォームにグループ通話のメディアサブスクリプションをリクエストし、メディアデータを受信するための連携方法について説明します。

概要

グループ通話のメディアサブスクリプションをリクエストするためには、サブスクリプションクライアント(WebSocketクライアント)を実装する必要があります。グループ通話のメディアサブスクリプションは、以下のように動作します。

  1. サブスクリプションクライアントがグループ通話のメディアサブスクリプションをリクエストするために、Planet Cloudのゲートウェイサーバーに認証をリクエストします。
  2. ゲートウェイサーバーは、認証後にサブスクリプショントークンを作成し、サブスクリプションクライアントに送ります。
  3. サブスクリプションクライアントがPlanet Cloudのサブスクリプションサーバーにグループ通話のメディアサブスクリプションをリクエストします。
  4. サブスクリプションサーバーは、サブスクリプションクライアントからのリクエストによって設定されたWebSocketの接続を使用して、グループ通話のメディアをサブスクリプションクライアントに送ります。

下図は、グループ通話のメディアサブスクリプションの連携構造を示しています。

グループ通話のメディアサブスクリプションの連携構造図

Note

アプリサーバーにサブスクリプションクライアントの機能を含める実装も可能です。この場合、アプリサーバーがゲートウェイサーバーやサブスクリプションサーバーと直接相互作用することになります。

このドキュメントでは、アプリサーバーとサブスクリプションクライアントが別々に実装されていることを前提に連携方法を説明します。

APIの呼び出し順

下図は、グループ通話のメディアサブスクリプションをリクエストし、メディアデータを受信するためのAPIの呼び出し順を示しています。

グループ通話のメディアサブスクリプションAPIの呼び出し順

ゲートウェイサーバーAPIの仕様

ここでは、認証のためにゲートウェイサーバーからサブスクリプショントークンを取得するAPIについて説明します。

アクセス情報

環境基準URL
Evaluationhttps://vpnx-stn-api.line-apps-rc.com

認証について詳しくは、基本プロトコルを参照してください。

API説明

サブスクリプションサーバーに接続するためのサブスクリプショントークンを取得します。

トークンの有効期間は、以下のとおりです。

環境トークンの有効期間
Evaluation1日
Real1日

メソッドとエンドポイント

  • メソッド:GET

  • エンドポイント

    /tas/v1/gcall/{serviceId}/{roomId}/subs/token

ヘッダー

  • AuthorizationBasic {your credential}
  • Content-Type:text/plain

パスパラメーター

パラメーター説明
serviceIdサービスID
roomIdルームID

クエリ

なし

レスポンス

サブスクリプショントークン

サンプルコード

curl --location --request GET 'https://vpnx-stn-api.line-apps-rc.com/tas/v1/gcall/planetkit-inhouse/1024/subs/token' \
--header 'Authorization: Basic em45eEkxRnROYlZwYlNXWFo1U2ZCWmhucF85dHFGaXBod2h0TjdNLTdTWHlFbllQalB2dUVKRXBDdkx5OU1tRWlHUEI2clpITjdvSVA3UXVWSE5sN3BmeHlObkxlRld0dkFCT2p4MkpCbXBROFZPVXZmMU11dVZ3QWtfdGU2cUh0OFVpV250TzZaZzZqdWIteWdtRnNBOjc4YTQwN2JjOGM0NjljZjE3MjI2MWVmY2E0MWJmODBlYzY5ODM1ZTY1MDk0YTJjZjc2YzAxYWE5N2U5Y2Q1MWU=' \
--header 'Content-Type: text/plain'

eea3091e49674a13a3091e49671a13c7

発生し得るHTTPステータスコード

発生する可能性のあるHTTPステータスコードは、以下のとおりです。詳しくは、エラー処理を参照してください。

  • 400、401、403、404、429、500、503

サブスクリプションサーバーAPIの仕様

ここでは、グループ通話のメディアサブスクリプションを処理するAPIについて説明します。

アクセス情報

環境基準URL
Evaluationwss://voipnx-rhea.line-apps-rc.com

API説明

session_idをパスパラメーターとしてWebSocketの接続をリクエストします。

  • WebSocket接続後、1秒以内に有効なメッセージが受信されない場合、接続が終了します。
  • サブスクリプションクライアントがサーバーからPING(opcode 0x09)メッセージを受信したら、接続を維持するためにサブスクリプションクライアントは、即時にPONG(opcode 0x0a)メッセージでレスポンスしなければなりません。
Warning

サブスクリプションサーバーは、高可用性をサポートしていません。サブスクライブ中にネットワークやサーバーのトラブルによりWebSocketの接続が切断した場合、サブスクリプションクライアントはWebSocketの接続を再設定し、サブスクリプションを再度リクエストしなければなりません。

メソッドとエンドポイント

  • メソッド:GET

  • エンドポイント

    /subs_gcall/{session-id}

制御メッセージ

制御メッセージは、WebSocketのテキストopcodeを使用して転送されます。制御メッセージには、以下のような特徴があります。

  • JSON形式を使用する
  • ヘッダーと本文とで構成される

ヘッダー

フィールドデータ型説明
msg_idNumber- SubscribeGroupcallMediaReq = 1
- SubscribeGroupcallMediaRsp = 2
- UnsubscribeGroupcallMediaReq = 3
- UnsubscribeGroupcallMediaRsp = 4
- AbortGroupcallMediaSubscriptionRpt = 5
- ChangeGroupcallMediaSubscriptionReq = 6
- ChangeGroupcallMediaSubscriptionRsp = 7
- UpdateGroupcallMediaContributorsRpt = 8
- NotifyGroupcallUserStatusRpt = 9
sess_idStringサブスクリプションクライアントが作成したセッションID

SubscribeGroupcallMediaReqmsg_id:1)

このメッセージは、Planet Cloudにグループ通話のメディアデータをサブスクライブするようリクエストします。

このメッセージでリクエストする前に、Planet Cloudゲートウェイサーバーに認証をリクエストし、subsTokenを取得する必要があります。

メッセージ本文
フィールドデータ型説明備考
service_idStringサービスID
room_idStringルームID
credentialStringBase64でエンコードされた文字列
media_typeArray(String要素)メディアタイプのリスト、Aはオーディオ、Vはビデオを示す対応可能な値は、以下のとおりです。
- A
- A, V
ビデオのみのモードには対応していません。
stream_typeString受信するストリームのタイプ
- MIX:リクエストした対象に対する混合ストリームを提供
- MULTI:リクエストした対象に対し、IDごとのストリームを提供
media_typeによる対応の可否は、以下のとおりです。
- AMIXMULTI
- A, VMIX
target_typeStringサブスクリプション対象タイプ
- MAIN_ROOM:メインルームのサブスクリプション
- SUBGROUP:サブグループのサブスクリプション
- TRANSLATE:翻訳ルームおよびサブグループのサブスクリプション
このフィールドは、stream_typeMIXのときのみ有効になります。
subgroup_nameStringサブスクライブするサブグループの名前このフィールドは、target_typeSUBGROUPのときのみ有効になります。
target_user_idsArray(String要素)サブスクライブするユーザーIDリストtarget_user_idsフィールドが存在しない、または該当フィールドに項目がない場合、すべての参加者がサブスクリプションの対象になります。
target_typeMAIN_ROOMの場合はメインルームの参加者が選択されます。SUBGROUPの場合は、サブグループの参加者が選択されます。
target_typeTRANSLATEの場合、target_user_idsは許可されません。
target_user_idsに設定できる最大の要素数は16です。
layout_typeStringビデオミキシングのためのレイアウトタイプ。詳しくは、レイアウトタイプを参照してください。このフィールドは、media_typeV(ビデオ)が含まれているときのみ有効になります。
max_display_numNumber- グリッドビュー:116
- フォーカスビュー:1
8
- プレゼンテーションビュー:1~8
ビデオに表示できる参加者の最大数は、レイアウトタイプによって異なります。グリッドビューの場合、最大で16です。
auto_screenshareBool画面共有を開始する際に自動でプレゼンテーションビューに切り替えるかどうか
no_target_users_timeoutNumbertarget_user_idsパラメーターが設定されている場合、ルームに対象ユーザーが存在しなかったときにサブスクリプションのセッションを維持する最大時間(秒単位)サブスクリプションクライアントがこの値を設定しなかった場合、サブスクリプションセッションはシステム設定によって終了されます。
target_typeSUBGROUPの場合の注意事項

1つのサブスクリプションセッションでは、1つのサブグループのみをサブスクライブできます。

メインルームに作成された他のサブグループをサブスクライブするためには、新しいサブスクリプションセッションを設定し、そのサブグループに対してサブスクリプションをリクエストする必要があります。

レイアウトタイプ

layout_typeフィールドに使用できる値は、以下のとおりです。

layout_typeの値target_user_ids値の有無説明
TALKER_GRID_VIEWN新しい発言者が優先になるグリッドビューです。
新しい発言者がレイアウトに入る必要がある状況で、スペースがない場合、最も長い間発言していない参加者が除外されます。
Ytarget_user_idsが指定されている場合、該当ユーザーのみレイアウトに含まれます。
ORDERED_GRID_VIEWN使用不可
Ytarget_user_ids要素の順番によって、レイアウト順が決まるグリッドビューです。
TALKER_FOCUS_VIEWN新しい発言者が優先になるフォーカスビューです。
新しい発言者は全画面領域に表示され、以前の発言者は1番目のサムネイル領域に移動します。
サムネイルビューがいっぱいになった場合は、最も長い間発言していない参加者が除外されます。
Ytarget_user_idsが指定されている場合、該当ユーザーのみレイアウトに含まれます。
新しい発言者は全画面領域に表示され、以前の発言者は1番目のサムネイル領域に移動します。
ORDERED_FOCUS_VIEWN使用不可
Ytarget_user_ids要素の順番によって、レイアウト順が決まるフォーカスビューです。
target_user_idsの1番目のユーザーが全画面領域に表示され、以前の発言者は1番目のサムネイル領域へ移動します。
サンプルコード
{
"header": {
"msg_id": 1,
"sess_id": "sid343213"
},
"body": {
"service_id": "planet",
"room_id": "RID_xlkjds",
"credential": "YW55IGNhcm5hbCBwbGVhcw==",
"media_type": ["A"],
"stream_type": "MULTI",
"target_type": "MAIN_ROOM"
}
}
{
"header": {
"msg_id": 1,
"sess_id": "sid343213"
},
"body": {
"service_id": "planet",
"room_id": "RID_xlkjds",
"credential": "YW55IGNhcm5hbCBwbGVhcw==",
"media_type": ["A", "V"],
"stream_type": "MIX",
"target_type": "MAIN_ROOM",
"layout_type": "TALKER_GRID_VIEW"
}
}
サブスクリプションリクエストの認証情報の計算

グループ通話のメディアサブスクリプションをリクエストする際には、リクエスト本文にcredentialフィールドの値として、以下の計算値を含める必要があります。

  • credential値:Planetゲートウェイサーバーで作成されたsubsToken値とグループ通話関連の情報を入力値とし、SHA-256ハッシュアルゴリズムで計算した値

サブスクリプションサーバーは、リクエスト本文のcredential値を使用して、認証されたサブスクリプションリクエストであるかどうかを確認します。

入力値
  • serviceID
  • roomID
  • subsToken
実装サンプルの擬似コード
credential calculation
#define AUTH_DELIM "::"
#define SHA256_HASHLEN 32
typedef unsigned char SHA256_HASH[SHA256_HASHLEN];

SHA256_CTX ctx;
SHA256_HASH SHA256_HA;
SHA256_Init(&ctx);
SHA256_Update(&ctx, svc_id, strlen(svc_id));
SHA256_Update(&ctx, AUTH_DELIM, strlen(AUTH_DELIM));
SHA256_Update(&ctx, room_id, strlen(room_id));
SHA256_Update(&ctx, AUTH_DELIM, strlen(AUTH_DELIM));
SHA256_Update(&ctx, subs_token, strlen(subs_token));
SHA256_Final(SHA256_HA, &ctx)
Javaサンプルコード
import java.nio.charset.StandardCharsets;

import org.apache.commons.codec.binary.Base64;

import com.google.common.hash.Hashing;

public class SubsUtils {
public static final String del = "::";

public static String makeCredential(String svcId, String roomId, String subsToken) {
byte[] hash = Hashing.sha256()
.newHasher()
.putString(svcId, StandardCharsets.UTF_8)
.putString(del, StandardCharsets.UTF_8)
.putString(roomId, StandardCharsets.UTF_8)
.putString(del, StandardCharsets.UTF_8)
.putString(subsToken, StandardCharsets.UTF_8)
.hash()
.asBytes();
String base64EncodedCredential = new String(Base64.encodeBase64(hash));
return base64EncodedCredential;
}
}

SubscribeGroupcallMediaRspmsg_id:2)

グループ通話のメディアサブスクリプションのリクエストに対するレスポンスメッセージです。サブスクリプションサーバーで作成されたsubs_idと、転送可能なメディアフォーマットの詳細情報が含まれています。メディアデータがWebSocketのバイナリopcodeを通じて転送される際には、メディアデータメッセージ形式で渡されます。

メッセージ本文
フィールドデータ型説明備考
resultStringAPIの結果
- success
- fail
subs_idNumberサブスクリプションサーバーによって作成されたサブスクリプションIDresultsuccessの場合に値が存在します。
audio_payload_infoArray(Audio PayloadInfo Object要素)オーディオパケットを示すpt(ペイロードタイプ)値に関する詳細情報resultsuccessの場合に値が存在します。
video_payload_infoArray(Video PayloadInfo Object 要素)オーディオパケットを示すpt値に関する詳細情報resultsuccessの場合に値が存在します。
error_codeNumberエラーコード。詳しくは、エラーコードを参照してください。resultfailの場合に値が存在します。
error_descStringエラーに関する詳細な説明resultfailの場合に値が存在します。
Audio PayloadInfo Object
名前タイプ説明例示
ptNumberペイロードタイプID120
codecStringオーディオコーデック名"opus"
clock_rateNumberクロックレート48000
channelsNumberオーディオチャネル数1
ptimeNumberパケット化の間隔時間(ミリ秒)20
Video PayloadInfo Object
名前タイプ説明例示
ptNumberペイロードタイプID121
codecStringビデオコーデック名"H264"
clock_rateNumberクロックレート90000
サンプルコード
{
"header": {
"msg_id": 2,
"sess_id": "sid343213"
},
"body": {
"result": "success",
"subs_id": 2394872139847981,
"audio_payload_info": [
{
"pt": 120,
"codec": "opus",
"clock_rate": 48000,
"channels": 1,
"ptime": 20
}
]
}
}
{
"header": {
"msg_id": 2,
"sess_id": "sid343213"
},
"body": {
"result": "success",
"subs_id": 2394872139847981,
"audio_payload_info": [
{
"pt": 120,
"codec": "opus",
"clock_rate": 48000,
"channels": 1,
"ptime": 20
}
],
"video_payload_info": [
{
"pt": 121,
"codec": "H264",
"clock_rate": 90000
}
]
}
}
{
"header": {
"msg_id": 2,
"sess_id": "sid343213"
},
"body": {
"result": "fail",
"error_code": 100,
"error_desc": "Authentication failed"
}
}

UnsubscribeGroupcallMediaReqmsg_id:3)

グループ通話のメディアサブスクリプションの中断をリクエストするメッセージです。

メッセージ本文
フィールドデータ型説明
service_idStringサービスID
room_idStringルームID
subs_idNumberサブスクリプションサーバーで作成されたサブスクリプションID
サンプルコード
{
"header": {
"msg_id": 3,
"sess_id": "sid343213"
},
"body": {
"service_id": "planet",
"room_id": "RID_xlkjds",
"subs_id": 2394872139847981
}
}

UnsubscribeGroupcallMediaRspmsg_id:4)

グループ通話のメディアサブスクリプションの中断リクエストに対するレスポンスメッセージです。

メッセージ本文
フィールドデータ型説明備考
resultStringAPIの結果
- success
- fail
error_codeNumberエラーコード。詳しくは、エラーコードを参照してください。resultfailの場合に値が存在します。
error_descStringエラーに関する詳細な説明resultfailの場合に値が存在します。
サンプルコード
{
"header": {
"msg_id": 4,
"sess_id": "sid343213"
},
"body": {
"result": "success",
}
}

AbortGroupcallMediaSubscriptionRptmsg_id:5)

Planet Cloud GroupCallサーバーで発生したイベントによってサブスクリプションが中断された場合、サブスクリプションクライアントにそれを通知するためのメッセージです。

メッセージ本文
フィールドデータ型説明
error_codeNumberエラーコード。詳しくは、エラーコードを参照してください。
error_descStringエラーの詳細な説明
サンプルコード
{
"header": {
"msg_id": 5,
"sess_id": "sid343213"
},
"body": {
"error_code": 2,
"error_desc": "Group call has been ended"
}
}

ChangeGroupcallMediaSubscriptionReqmsg_id:6)

このメッセージは、メディアサブスクリプション情報を変更する際に使用されます。以下の項目をアップデートできます。

  • ビデオミキシングのレイアウトタイプ
メッセージ本文
フィールドデータ型説明備考
service_idStringサービスID
room_idStringルームID
subs_idNumberサブスクリプションサーバーで作成されたサブスクリプションID
layout_typeStringビデオミキシングのためのレイアウトタイプこのフィールドは、media_typeV(ビデオ)が含まれている場合のみ有効となります。
サンプルコード
{
"header": {
"msg_id": 6,
"sess_id": "sid343213"
},
"body": {
"service_id": "planet",
"room_id": "RID_xlkjds",
"subs_id": 2394872139847981,
"layout_type": "TALKER_FOCUS_VIEW"
}
}

ChangeGroupcallMediaSubscriptionRspmsg_id:7)

サブスクリプション情報の変更結果を返すメッセージです。

メッセージ本文
フィールドデータ型説明備考
resultStringAPIの結果
- success
- fail
error_codeNumberエラーコード。詳しくは、エラーコードを参照してください。resultfailの場合に値が存在します。
error_descStringエラーに関する詳細な説明resultfailの場合に値が存在します。
サンプルコード
{
"header": {
"msg_id": 7,
"sess_id": "sid343213"
},
"body": {
"result": "success",
}
}

UpdateGroupcallMediaContributorsRptmsg_id:8)

stream_typeMIXで、混合メディアに含まれているuser_idリストに変更がある場合、アップデートされたuser_idリストが、このメッセージを通じてサブスクリプションクライアントに転送されます。

メッセージ本文
フィールドデータ型説明
ptNumberペイロードタイプID120(オーディオ)または121(ビデオ)
tsNumberRTPタイムスタンプ
seqNumberRTPシーケンス番号
user_idsArray(String要素)user_idリスト
サンプルコード
{
"header": {
"msg_id": 8,
"sess_id": "sid343213"
},
"body": {
"pt": 120,
"ts": 3475364964,
"seq": 30968,
"user_ids": ["user1", "user2", "user3"]
}
}

NotifyGroupcallUserStatusRptmsg_id:9)

サブスクリプションをリクエスト(SubscribeGroupcallMediaReq)する際にtarget_user_idsパラメーターが設定されている場合、このパラメーターに含まれているユーザーがルームに参加またはルームから退出すると、ユーザーのステータス情報がこのメッセージを通じてサブスクリプションクライアントに転送されます。

メッセージ本文
フィールドデータ型説明
enterArray(String要素)ルームに参加したユーザーのIDリスト
leaveArray(String要素)ルームから退出したユーザーのIDリスト
サンプルコード
{
"header": {
"msg_id": 9,
"sess_id": "sid343213"
},
"body": {
"enter": ["user1", "user2", "user3"],
"leave": ["user4", "user5"]
}
}

エラーコード

エラーコード原因備考
0UNDEFINED
1NO_ERROR
2GROUPCALL_END
100AUTHENTICATION_FAIL
101ROOM_NOT_FOUND
102SUBSCRIPTION_NOT_SUPPORT
103INVALID_PARAMETER
104SUBSCRIPTION_NOT_FOUND
105INVALID_STATE
106INVALID_MSG_FORMAT
107SUBS_CAPA_FULL
200INTERNAL_SERVER_ERROR
201WS_DISCONNECTED_BY_PEER
202WS_PING_PONG_FAIL
203WS_INITIAL_REQUEST_TIMEOUT
1000UNKNOWN

メディアデータメッセージ

メディアデータメッセージは、WebSocketのバイナリopcodeを使用して転送されます。リクエストされたstream_typeによって、以下の2つのタイプで転送されます。

メディアデータメッセージの形式

メディアデータメッセージの形式は、以下のとおりです。

順番プロパティサイズ説明
1type1バイトデータ型
1:RTP(混合オーディオまたはビデオ)
2:user_idが含まれているRTP
2data可変長

タイプ1:混合オーディオまたはビデオRTP

  • 対象stream_typeMIX
  • 対象media_typeA(オーディオ)またはA, V(オーディオおよびビデオ)
  • 混合されたオーディオとビデオは、接続されたWebSocketのセッションを通じて、RTP形式のデータで転送されます。
  • オーディオとビデオは、転送されたRTPヘッダーのpt(ペイロードタイプ)で区別します。

タイプ1のメディアデータメッセージの形式は、以下のとおりです。

順番プロパティサイズ
1オーディオまたはビデオRTP可変長

タイプ2:特定ユーザーのオーディオRTP

  • 対象stream_typeMULTI
  • 対象media_typeA(オーディオ)
  • グループ通話に参加する各ユーザーのオーディオデータは、user_id情報(ヘッダー)とRTPの形式でサブスクリプションクライアントに転送されます。

タイプ2のメディアデータメッセージの形式は、以下のとおりです。

順番プロパティサイズ
1user_id_length1バイト
2user_id可変長
3オーディオRTP可変長
Warning

特定ユーザー(グループ通話の参加者)のRTPコンテキスト(タイムスタンプ、シーケンス)は、次の場合に再開されることがあります。

  • ユーザーが一定時間発話を中断し、その後発話を再開したとき
  • ユーザーが通話ルームに参加、または退出後に再参加し発話を始めたとき