diff --git a/CHANGES.md b/CHANGES.md
index 30fd6c84..b96a545e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,6 +11,9 @@
## develop
+- [CHANGE] シグナリングオプションの `multistream` は false の時のみレガシーストリームを使用する
+ - レガシーストリームを使用したい場合は `multistream: false` の指定が必須となる
+ - @tnamao
- [CHANGE] stopAudioTrack と stopVideoTrack を非推奨にする
- 代わりに名前を変えただけの removeAudioTrack と removeVideoTrack を用意する
- @voluntas
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() {
diff --git a/packages/sdk/src/publisher.ts b/packages/sdk/src/publisher.ts
index a81a204b..7333ef3d 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.legacyStream(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()
}),
@@ -44,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/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..68b21f44 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.legacyStream().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,13 +41,12 @@ export default class ConnectionSubscriber extends ConnectionBase {
])
this.monitorWebSocketEvent()
this.monitorPeerConnectionState()
- return stream
}
/**
- * シングルストリームで Sora へ接続するメソッド
+ * レガシーストリームで Sora へ接続するメソッド
*/
- private async singleStream(): Promise {
+ private async legacyStream(): Promise {
await this.disconnect()
this.setupE2EE()
const ws = await this.getSignalingWebSocket(this.signalingUrlCandidates)
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'",
)
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, {