From d3a0696535e70cb9c3e9e7d9074c4d9396dbb092 Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Mon, 4 Mar 2024 17:37:38 +0900 Subject: [PATCH 1/6] =?UTF-8?q?multistream=20=E6=8E=A5=E7=B6=9A=E3=82=AA?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AF=20false=20?= =?UTF-8?q?=E3=81=AE=E6=99=82=E3=81=AE=E3=81=BF=20single=20stream=20?= =?UTF-8?q?=E3=81=A8=E3=81=97=E3=81=A6=E6=89=B1=E3=81=86=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/src/publisher.ts | 7 ++++--- packages/sdk/src/sora.ts | 4 +--- packages/sdk/src/subscriber.ts | 14 +++++++------- packages/sdk/src/utils.ts | 3 ++- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/sdk/src/publisher.ts b/packages/sdk/src/publisher.ts index a81a204b..e0a057d4 100644 --- a/packages/sdk/src/publisher.ts +++ b/packages/sdk/src/publisher.ts @@ -19,9 +19,10 @@ export default class ConnectionPublisher extends ConnectionBase { * @public */ async connect(stream: MediaStream): Promise { - if (this.options.multistream) { + // options.multistream が明示的に false を指定した時だけシングルストリームにする + if (this.options.multistream === false) { await Promise.race([ - this.multiStream(stream).finally(() => { + this.singleStream(stream).finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), @@ -30,7 +31,7 @@ export default class ConnectionPublisher extends ConnectionBase { ]) } else { await Promise.race([ - this.singleStream(stream).finally(() => { + this.multiStream(stream).finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), diff --git a/packages/sdk/src/sora.ts b/packages/sdk/src/sora.ts index 68b902b4..499ab0ea 100644 --- a/packages/sdk/src/sora.ts +++ b/packages/sdk/src/sora.ts @@ -82,14 +82,12 @@ class SoraConnection { metadata: JSONType = null, options: ConnectionOptions = { audio: true, video: true }, ): ConnectionPublisher { - // sendrecv の場合、multistream に初期値を指定する - const sendrecvOptions: ConnectionOptions = Object.assign({ multistream: true }, options) return new ConnectionPublisher( this.signalingUrlCandidates, 'sendrecv', channelId, metadata, - sendrecvOptions, + options, this.debug, ) } diff --git a/packages/sdk/src/subscriber.ts b/packages/sdk/src/subscriber.ts index f1dfaf7e..0090d483 100644 --- a/packages/sdk/src/subscriber.ts +++ b/packages/sdk/src/subscriber.ts @@ -17,9 +17,10 @@ export default class ConnectionSubscriber extends ConnectionBase { */ // biome-ignore lint/suspicious/noConfusingVoidType: stream が なのでどうしようもない async connect(): Promise { - if (this.options.multistream) { - await Promise.race([ - this.multiStream().finally(() => { + // options.multistream が明示的に false を指定した時だけシングルストリームにする + if (this.options.multistream === false) { + const stream = await Promise.race([ + this.singleStream().finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), @@ -28,10 +29,10 @@ export default class ConnectionSubscriber extends ConnectionBase { ]) this.monitorWebSocketEvent() this.monitorPeerConnectionState() - return + return stream } - const stream = await Promise.race([ - this.singleStream().finally(() => { + await Promise.race([ + this.multiStream().finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), @@ -40,7 +41,6 @@ export default class ConnectionSubscriber extends ConnectionBase { ]) this.monitorWebSocketEvent() this.monitorPeerConnectionState() - return stream } /** diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 7809ab03..7b70aa4a 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -146,7 +146,8 @@ export function createSignalingMessage( video: true, } // role: sendrecv で multistream: false の場合は例外を発生させる - if (role === 'sendrecv' && options.multistream !== true) { + // options.multistream === undefined は multistream として扱う + if (role === 'sendrecv' && options.multistream === false) { throw new Error( "Failed to parse options. Options multistream must be true when connecting using 'sendrecv'", ) From 657ca61fc009adddb86fca352c130ddfefaffc75 Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Mon, 4 Mar 2024 17:40:19 +0900 Subject: [PATCH 2/6] =?UTF-8?q?signalingMessage=20=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=20multis?= =?UTF-8?q?tream=20=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=AB=E5=90=88=E3=82=8F=E3=81=9B=E3=81=A6?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=A8=E4=BF=AE=E6=AD=A3=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/tests/utils.test.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/sdk/tests/utils.test.ts b/packages/sdk/tests/utils.test.ts index cd7a4772..34352ef9 100644 --- a/packages/sdk/tests/utils.test.ts +++ b/packages/sdk/tests/utils.test.ts @@ -1,6 +1,6 @@ -import { test, expect } from 'vitest' -import { createSignalingMessage } from '../src/utils' +import { expect, test } from 'vitest' import { type AudioCodecType, DataChannelDirection, VideoCodecType } from '../src/types' +import { createSignalingMessage } from '../src/utils' const channelId = '7N3fsMHob' const metadata = 'PG9A6RXgYqiqWKOVO' @@ -47,6 +47,15 @@ test('createSignalingMessage simple sendrecv', () => { ).toEqual(expectedMessage) }) +test('createSignalingMessage sendrecv and undefined multistream', () => { + const expectedMessage = Object.assign({}, baseExpectedMessage, { + role: 'sendrecv', + }) + expect(createSignalingMessage(sdp, 'sendrecv', channelId, undefined, {}, false)).toEqual( + expectedMessage, + ) +}) + test('createSignalingMessage invalid role', () => { expect(() => { createSignalingMessage(sdp, 'test', channelId, metadata, {}, false) @@ -55,7 +64,7 @@ test('createSignalingMessage invalid role', () => { test('createSignalingMessage sendrecv and multistream: false', () => { expect(() => { - createSignalingMessage(sdp, 'sendrecv', channelId, metadata, {}, false) + createSignalingMessage(sdp, 'sendrecv', channelId, metadata, { multistream: false }, false) }).toThrow( Error( "Failed to parse options. Options multistream must be true when connecting using 'sendrecv'", @@ -140,6 +149,14 @@ test('createSignalingMessage multistream: true', () => { ) }) +test('createSignalingMessage undefined multistream', () => { + const options = {} + const expectedMessage = Object.assign({}, baseExpectedMessage, {}) + expect(createSignalingMessage(sdp, 'sendonly', channelId, undefined, options, false)).toEqual( + expectedMessage, + ) +}) + test('createSignalingMessage multistream: false', () => { const options = { multistream: false } const expectedMessage = Object.assign({}, baseExpectedMessage, { From f28cc818bde438197eef1edc48364a0ad3cf54f9 Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Mon, 4 Mar 2024 17:44:26 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=B1=A5=E6=AD=B4?= =?UTF-8?q?=E3=81=AB=E8=BF=BD=E8=A8=98=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 30fd6c84..d0ad5424 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,9 @@ ## develop +- [CHANGE] シグナリングオプションの `multistream` は false の時のみシングルストリームを使用する + - シングルストリームを使用したい場合は `multistream: false` の指定が必須となる + - @tnamao - [CHANGE] stopAudioTrack と stopVideoTrack を非推奨にする - 代わりに名前を変えただけの removeAudioTrack と removeVideoTrack を用意する - @voluntas From a65eca678434f4051a12d6c701013849278f5740 Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Tue, 5 Mar 2024 10:36:43 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E5=86=85=E9=83=A8=E3=81=AE=20singleStream?= =?UTF-8?q?=20=E3=82=92=20legacyStream=20=E3=81=AB=E6=94=B9=E5=90=8D?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/src/publisher.ts | 8 ++++---- packages/sdk/src/subscriber.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/sdk/src/publisher.ts b/packages/sdk/src/publisher.ts index e0a057d4..7333ef3d 100644 --- a/packages/sdk/src/publisher.ts +++ b/packages/sdk/src/publisher.ts @@ -19,10 +19,10 @@ export default class ConnectionPublisher extends ConnectionBase { * @public */ async connect(stream: MediaStream): Promise { - // options.multistream が明示的に false を指定した時だけシングルストリームにする + // options.multistream が明示的に false を指定した時だけレガシーストリームにする if (this.options.multistream === false) { await Promise.race([ - this.singleStream(stream).finally(() => { + this.legacyStream(stream).finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), @@ -45,11 +45,11 @@ export default class ConnectionPublisher extends ConnectionBase { } /** - * シングルストリームで Sora へ接続するメソッド + * レガシーストリームで Sora へ接続するメソッド * * @param stream - メディアストリーム */ - private async singleStream(stream: MediaStream): Promise { + private async legacyStream(stream: MediaStream): Promise { await this.disconnect() this.setupE2EE() const ws = await this.getSignalingWebSocket(this.signalingUrlCandidates) diff --git a/packages/sdk/src/subscriber.ts b/packages/sdk/src/subscriber.ts index 0090d483..68b21f44 100644 --- a/packages/sdk/src/subscriber.ts +++ b/packages/sdk/src/subscriber.ts @@ -17,10 +17,10 @@ export default class ConnectionSubscriber extends ConnectionBase { */ // biome-ignore lint/suspicious/noConfusingVoidType: stream が なのでどうしようもない async connect(): Promise { - // options.multistream が明示的に false を指定した時だけシングルストリームにする + // options.multistream が明示的に false を指定した時だけレガシーストリームにする if (this.options.multistream === false) { const stream = await Promise.race([ - this.singleStream().finally(() => { + this.legacyStream().finally(() => { this.clearConnectionTimeout() this.clearMonitorSignalingWebSocketEvent() }), @@ -44,9 +44,9 @@ export default class ConnectionSubscriber extends ConnectionBase { } /** - * シングルストリームで Sora へ接続するメソッド + * レガシーストリームで Sora へ接続するメソッド */ - private async singleStream(): Promise { + private async legacyStream(): Promise { await this.disconnect() this.setupE2EE() const ws = await this.getSignalingWebSocket(this.signalingUrlCandidates) From 4da90cc312565de12e8458966424311c37305a3a Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Tue, 5 Mar 2024 10:38:58 +0900 Subject: [PATCH 5/6] =?UTF-8?q?check.html=20=E3=81=AE=20single=20=E3=82=82?= =?UTF-8?q?=20legacy=20=E3=81=AB=E7=BD=AE=E3=81=8D=E6=8F=9B=E3=81=88?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/check.html | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/check.html b/examples/check.html index 7ececf39..716ce47e 100644 --- a/examples/check.html +++ b/examples/check.html @@ -21,7 +21,7 @@

リリース前の動作確認用サンプル

※ クエリストリングの signalingUrl パラメータでも指定可能
-

チャネル ID: sora-js-sdk:check:singlestream

+

チャネル ID: sora-js-sdk:check:legacystream

要確認ブラウザ:
    @@ -30,14 +30,14 @@

    チャネル ID: sora-js-sdk:check:singlestream

  • Firefox: Linux or macOS or Windows
- - + +

sendonly, Opus

-
+

recvonly

-
+

チャネル ID: sora-js-sdk:check:multistream

@@ -183,23 +183,23 @@

multistream, E2EE, recvonly

document.querySelectorAll('.multistream').forEach(x => x.innerHTML = null); } - let singlestreamCheckConnections = []; - async function startSinglestreamCheck() { - stopSinglestreamCheck(); + let legacystreamCheckConnections = []; + async function startLegacystreamCheck() { + stopLegacystreamCheck(); - const channelId = 'sora-js-sdk:check:singlestream'; - singlestreamCheckConnections = [ - await connect(channelId, 'singlestream-sendonly-videos', 'sendonly', + const channelId = 'sora-js-sdk:check:legacystream'; + legacystreamCheckConnections = [ + await connect(channelId, 'legacystream-sendonly-videos', 'sendonly', {multistream: false}), - await connect(channelId, 'singlestream-recvonly-videos', 'recvonly', + await connect(channelId, 'legacystream-recvonly-videos', 'recvonly', {multistream: false}), ]; } - async function stopSinglestreamCheck() { - singlestreamCheckConnections.forEach(x => x.disconnect()); - singlestreamCheckConnections = []; - document.querySelectorAll('.singlestream').forEach(x => x.innerHTML = null); + async function stopLegacystreamCheck() { + legacystreamCheckConnections.forEach(x => x.disconnect()); + legacystreamCheckConnections = []; + document.querySelectorAll('.legacystream').forEach(x => x.innerHTML = null); } function initLyra() { From 693c73e945ef25344ecd8a71d73bae74572d861e Mon Sep 17 00:00:00 2001 From: Takeshi NAMAO Date: Tue, 5 Mar 2024 10:39:25 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=B1=A5=E6=AD=B4?= =?UTF-8?q?=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d0ad5424..b96a545e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,8 +11,8 @@ ## develop -- [CHANGE] シグナリングオプションの `multistream` は false の時のみシングルストリームを使用する - - シングルストリームを使用したい場合は `multistream: false` の指定が必須となる +- [CHANGE] シグナリングオプションの `multistream` は false の時のみレガシーストリームを使用する + - レガシーストリームを使用したい場合は `multistream: false` の指定が必須となる - @tnamao - [CHANGE] stopAudioTrack と stopVideoTrack を非推奨にする - 代わりに名前を変えただけの removeAudioTrack と removeVideoTrack を用意する