音声通話
ゲーム向け(声で話すアプリにも使えます)。音声通話はリアルタイムの部屋の中で使います。voiceを付けて部屋を作ると、その部屋のプレイヤー同士で声をやり取りできます。パーティー、チーム、対戦、大人数の集まりなどに使えます。1回の通話は100人までです。8人まではプレイヤー同士をつなぎ(P2P)、9人以上はKUMODeckの中継サーバー(SFU)を通します。どちらになるかは部屋の人数で自動で決まり、使い方は同じです。ONにするまではOFFで、リアルタイムの部屋もONにする必要があります。
kumodeck features on realtimeChannels voice
kumodeck config push --env developmentKUMODeckは通話を録音しません。 声は聴く人へ届けるだけで、つなぐための合図のメッセージも中継したら捨てます。KUMODeckが持つのは、今だれが通話にいるかと、入った時刻だけです。
通話を始める#
const party = await kumo.realtime.create({ voice: true, maxMembers: 4, join: 'invited' });
await party.invite(playerId); // 入れる人(party.name をその人に渡す)
// join() はボタンから呼ぶ: ブラウザがマイクの許可を聞き、音はタップやクリックの後でないと鳴らせないため
await party.voice.join(); // { mic: false } = 聴くだけ
party.voice.mute(); // 自分のマイク
party.voice.unmute();
party.voice.on('speaking', ({ playerId, speaking }) => { … }); // 話している人を光らせる
await party.voice.leave(); // 通話から出る(部屋には残る)大人数の通話も同じ書き方です。
const hall = await kumo.realtime.create({ voice: true, maxMembers: 60 }); // 9人以上 = 中継サーバー
hall.voice.mode; // 'sfu'通話があるのはvoiceを付けて作った部屋だけです。ほかの部屋ではch.voiceはnullです。ほかのプレイヤーはいつもどおり部屋に入り(kumo.realtime.join(party.name))、そのあとch.voice.join()を呼びます。接続が切れたときは、SDKが部屋と通話に自動で入り直します。
人数と方式#
| 部屋の作り方 | 方式(ch.voice.mode) | |
|---|---|---|
voice: true、maxMembersが8以下(既定は8) | 'p2p' | プレイヤー同士をつなぐ。声は中継を通るので、相手のIPアドレスは見えない |
voice: true、maxMembersが9〜100 | 'sfu' | 自動で中継サーバーを通す |
voice: { mode: 'sfu' } | 'sfu' | 少人数でも中継サーバーを通す(maxMembersの既定は50)。ミュートを確実にしたい部屋向け(下を参照) |
maxMembersが100より多い | — | voice_too_large |
方式は部屋を作るときに決まり、通話の途中では変わりません。
中継サーバー('sfu')の部屋の決まり
- 聴こえるのは、自分以外で最近話した上位8人です。 大勢が同時に話しても聞き取れるのは数人までなので、聴く量(料金)が人数の2乗で増えないようにしています。
ch.voice.peersは今聴いている人(8人まで)で、speakingもその人たちについて届きます。通話にいる全員はch.voice.membersで分かります。 - ミュートはサーバーが強制します。 持ち主や自分のサーバーがミュートした人、話せる人の名簿に無い人の声は、中継サーバーが誰にも配りません。改造したクライアントでも聴けません。
- 相手のIPアドレスは見えません(声は中継サーバーから届きます)。
状態・イベント・エラー#
| 状態 | |
|---|---|
ch.voice.mode | 'p2p'か'sfu'(読むだけ) |
ch.voice.joined | 自分が通話に入っている |
ch.voice.muted | 自分のマイクをミュートしている |
ch.voice.canSpeak | 自分の声がほかの人に聞こえる(持ち主や自分のサーバーにミュートされた・話せる人の名簿に無いときはfalse) |
ch.voice.members | 通話にいる人: [{ id, canSpeak }] |
ch.voice.peers | 声が届く相手: { playerId, state, canSpeak, speaking, relayed }('sfu'では今聴いている上位8人) |
| イベント | 中身 |
|---|---|
peer | つながりが変わった: { playerId, state, canSpeak, speaking, relayed } |
speaking | { playerId, speaking } |
members | 通話にいる人の一覧(変わるたびに全体) |
playerJoined / playerLeft | { id, canSpeak } / { playerId }(自分以外) |
self | { canSpeak } — 自分がミュートされた・解除された |
closed | { reason } — 下の表 |
closedのreason | どんなとき | 部屋には |
|---|---|---|
left | 自分で通話から出た | 残る |
kicked / banned | 部屋から外された | 外れる |
time_limit | 1回の通話が4時間を過ぎた | 残る(入り直せる) |
suspended | KUMODeckの運営がこの部屋かゲームの音声通話を止めた(悪用への対応など)。解除されるまで通話に入れない。文字のやり取りは続けられる | 残る |
unavailable | 今は通話を続けられない(前払いの残高がなくなった など) | 残る |
connection_lost | 回線が切れて入り直せなかった | — |
| エラー | どんなとき |
|---|---|
webrtc_unavailable | ブラウザにWebRTCが無い |
mic_denied | プレイヤーがマイクを許可しなかった({ mic: false }で聴くだけにはできる) |
voice_disabled | この部屋はvoiceを付けて作られていない |
voice_too_large | maxMembersが100より多い(P2Pを指定した部屋では8より多い) |
voice_suspended | KUMODeckの運営がこの部屋かゲームの音声通話を止めている |
voice_unavailable | 今は中継サーバーの通話を使えない。少し待って入り直す |
voice_not_joined | join()の前に通話の操作をした |
feature_disabled | features.voiceがOFF |
player_required | プレイヤーIDの無いプレイヤー(下を参照) |
rate_limited | 通話への入り直しが多すぎる(1時間あたりの回数の上限) |
自分のサーバーから(秘密鍵)#
自分のサーバーからも通話のある部屋を用意できます。PUT /v1/realtime/channels/@nameに{ "voice": true }を送ります(いつものjoin、send、maxMembers、allow、speakersも一緒に使えます)。人数による方式の決まりは上と同じで、{ "voice": { "mode": "sfu" } }で少人数でも中継サーバーにできます。{ "voice": { "mode": "p2p" } }は8人までの部屋にだけ使えます(9人以上はvoice_too_large)。すでにあるP2Pの部屋を9人以上に広げるときは、maxMembersと一緒に{ "voice": { "mode": "sfu" } }を送ってください(maxMembersだけでは方式は変わらず、voice_too_largeになります)。GETでvoice(modeを含む)と通話にいる人が分かります。通話に人がいる間は、音声の設定を変えられません(409 voice_in_use)。
P2Pの部屋では、既定で声はすべて中継を通るので、プレイヤーに相手のIPアドレスは見えません。これを外せるのは自分のサーバーだけで、部屋ごとに{ "voice": { "relayOnly": false } }とします(直接つながった組は中継の費用がかかりません)。13歳未満のプレイヤーは常に中継を通ります。中継サーバーの部屋ではこの設定は効きません。
ミュート・キック・BAN#
部屋の決まりがそのまま通話に効きます。持ち主(または自分のサーバー)のmute、send: 'invited'の部屋の話せる人の名簿、kick、banです。
- キックとBANは通信そのものを止めます。 そのプレイヤーは部屋と通話から外れ、中継を使う資格もすぐに取り消されます。ゲームからBANしたプレイヤーは、どの部屋にも入れません。キックした人は、部屋が入れる相手ならまた入れます。入らせたくないときはBANしてください。
- ミュートの効き方は方式で違います。 中継サーバー(
'sfu')では、サーバーがその人の声を配るのをやめます。P2P('p2p')では、KUMODeckが全員に「この人は話せない」と伝え、聴く人それぞれのSDKがその声の再生を止めます。声そのものはほかの人に届いているので、改造したクライアントなら再生できてしまいます。確実にミュートしたい部屋(知らない人どうしの通話など)はvoice: { mode: 'sfu' }で作るか、キックしてください。 - 表示名は誰かの証明になりません。 誰でもほかの人と同じ名前や「運営」のような名前を付けられます。持ち主や運営の印は、表示名ではなくプレイヤーID(
ownerId)で出してください。 - 発言の中身の見張りは、クリエイターの責任です。 誰が話せるかを決め、困ったときにすぐ動けるようにしておいてください(ミュート・キック・BAN)。悪用があったときは、KUMODeckの運営が部屋やゲームの音声通話だけを止めることもあります(
suspended)。
上限#
| 1回の通話の人数 | 100人。P2Pは8人まで(voice: trueのmaxMembersの既定は8、{ mode: 'sfu' }は50) |
| 聴こえる人 | P2Pは通話の全員。中継サーバーは自分以外で最近話した上位8人 |
| 1回の通話の時間 | 4時間。過ぎるとclosed(time_limit)。部屋には残り、通話に入り直せる |
| 入れる人 | プレイヤーIDのある人(既定。SDKがゲストとして自動でログインさせる)。openの部屋では使えない |
| 部屋 | voiceを付けて作った@の部屋だけ(プレイヤーか自分のサーバーが作る)。@の無い部屋では使えない |
前払いの残高がなくなると、ほかのプレイヤー向けの機能と同じく、新しい通話は始められず、通話中の人も通話から外れます(closedのunavailable)。
料金#
KUMODeckの利用料(原価どおり)として、前払いの残高から差し引きます。費用がかかるのは、聴く人それぞれへ届けた声の量です。黙っている人はほとんど送りません(無音の間はSDKが送らない)。P2Pで直接つながった組は費用がかかりません。
P2P(8人まで):
| 1時間あたり | 1度に1人が話す | 全員がずっと話す |
|---|---|---|
| 2人 | 約0.13セント | 約0.26セント |
| 4人 | 約0.4セント | 約1.5セント |
| 8人 | 約0.9セント | 約7.2セント |
中継サーバー(9人以上)。1人が聴くのは8人までなので、費用は人数にほぼ比例します:
| 1時間あたり | 同時に話すのは平均2人 | 全員がずっと話す |
|---|---|---|
| 16人 | 約4セント | 約16セント |
| 50人 | 約13セント | 約51セント |
| 100人 | 約26セント | 約1ドル |