piixishstream 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client/Streamer.js
CHANGED
|
@@ -82,33 +82,47 @@ export class Streamer {
|
|
|
82
82
|
reject("cannot start stream without first joining voice channel");
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
this.
|
|
86
|
-
|
|
85
|
+
if (this.voiceConnection.streamConnection?.webRtcConn?.ready) {
|
|
86
|
+
resolve(this.voiceConnection.streamConnection.webRtcConn);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const { guildId: clientGuildId, channelId: clientChannelId, session_id } = this.voiceConnection;
|
|
87
90
|
const { id: clientUserId } = this.client.user;
|
|
88
|
-
if (!session_id)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
this.voiceConnection.streamConnection = streamConn;
|
|
94
|
-
this._gatewayEmitter.on("STREAM_CREATE", (d) => {
|
|
91
|
+
if (!session_id) throw new Error("Session doesn't exist yet");
|
|
92
|
+
|
|
93
|
+
let done = false;
|
|
94
|
+
const onStreamCreate = (d) => {
|
|
95
95
|
const { channelId, guildId, userId } = parseStreamKey(d.stream_key);
|
|
96
|
-
if (clientGuildId !== guildId ||
|
|
97
|
-
clientChannelId !== channelId ||
|
|
98
|
-
clientUserId !== userId)
|
|
99
|
-
return;
|
|
96
|
+
if (clientGuildId !== guildId || clientChannelId !== channelId || clientUserId !== userId) return;
|
|
100
97
|
streamConn.serverId = d.rtc_server_id;
|
|
101
98
|
streamConn.streamKey = d.stream_key;
|
|
102
99
|
streamConn.setSession(session_id);
|
|
103
|
-
}
|
|
104
|
-
|
|
100
|
+
};
|
|
101
|
+
const onStreamServerUpdate = (d) => {
|
|
105
102
|
const { channelId, guildId, userId } = parseStreamKey(d.stream_key);
|
|
106
|
-
if (clientGuildId !== guildId ||
|
|
107
|
-
clientChannelId !== channelId ||
|
|
108
|
-
clientUserId !== userId)
|
|
109
|
-
return;
|
|
103
|
+
if (clientGuildId !== guildId || clientChannelId !== channelId || clientUserId !== userId) return;
|
|
110
104
|
streamConn.setTokens(d.endpoint, d.token);
|
|
105
|
+
};
|
|
106
|
+
const cleanup = () => {
|
|
107
|
+
if (done) return;
|
|
108
|
+
done = true;
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
this._gatewayEmitter.off("STREAM_CREATE", onStreamCreate);
|
|
111
|
+
this._gatewayEmitter.off("STREAM_SERVER_UPDATE", onStreamServerUpdate);
|
|
112
|
+
};
|
|
113
|
+
const timer = setTimeout(() => {
|
|
114
|
+
cleanup();
|
|
115
|
+
reject(new Error("Timeout en attente de la passerelle Discord Go-Live"));
|
|
116
|
+
}, 10000);
|
|
117
|
+
|
|
118
|
+
this.signalStream();
|
|
119
|
+
const streamConn = new StreamConnection(this, clientGuildId, clientUserId, clientChannelId, (conn) => {
|
|
120
|
+
cleanup();
|
|
121
|
+
resolve(conn);
|
|
111
122
|
});
|
|
123
|
+
this.voiceConnection.streamConnection = streamConn;
|
|
124
|
+
this._gatewayEmitter.on("STREAM_CREATE", onStreamCreate);
|
|
125
|
+
this._gatewayEmitter.on("STREAM_SERVER_UPDATE", onStreamServerUpdate);
|
|
112
126
|
});
|
|
113
127
|
}
|
|
114
128
|
async setStreamPreview(image) {
|
|
@@ -60,6 +60,25 @@ export class WebRtcConnWrapper {
|
|
|
60
60
|
get webRtcConn() {
|
|
61
61
|
return this._webRtcConn;
|
|
62
62
|
}
|
|
63
|
+
waitUntilReady(timeoutMs = 5000) {
|
|
64
|
+
if (this.ready) return Promise.resolve();
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
let done = false;
|
|
67
|
+
const finish = () => {
|
|
68
|
+
if (!done) {
|
|
69
|
+
done = true;
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
resolve();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
75
|
+
this._webRtcConn?.onStateChange((state) => {
|
|
76
|
+
if (state === "connected") {
|
|
77
|
+
finish();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
63
82
|
get ready() {
|
|
64
83
|
return this._webRtcConn?.state() === "connected";
|
|
65
84
|
}
|
package/dist/media/newApi.js
CHANGED
|
@@ -274,6 +274,7 @@ export async function playStream(input, streamer, options = {}, cancelSignal) {
|
|
|
274
274
|
? opts.readrateInitialBurst
|
|
275
275
|
: defaultOptions.readrateInitialBurst,
|
|
276
276
|
streamPreview: opts.streamPreview ?? defaultOptions.streamPreview,
|
|
277
|
+
keepConnection: opts.keepConnection ?? false,
|
|
277
278
|
};
|
|
278
279
|
}
|
|
279
280
|
const mergedOptions = mergeOptions(options);
|
|
@@ -297,12 +298,12 @@ export async function playStream(input, streamer, options = {}, cancelSignal) {
|
|
|
297
298
|
let stopStream;
|
|
298
299
|
if (mergedOptions.type === "go-live") {
|
|
299
300
|
conn = await streamer.createStream();
|
|
300
|
-
stopStream = () => streamer.stopStream();
|
|
301
|
+
stopStream = () => { if (!mergedOptions.keepConnection) streamer.stopStream(); };
|
|
301
302
|
}
|
|
302
303
|
else {
|
|
303
304
|
conn = streamer.voiceConnection.webRtcConn;
|
|
304
305
|
streamer.signalVideo(true);
|
|
305
|
-
stopStream = () => streamer.signalVideo(false);
|
|
306
|
+
stopStream = () => { if (!mergedOptions.keepConnection) streamer.signalVideo(false); };
|
|
306
307
|
}
|
|
307
308
|
conn.setPacketizer(videoCodecMap[video.codec]);
|
|
308
309
|
conn.mediaConnection.setSpeaking(true);
|
|
@@ -383,8 +384,10 @@ export async function playStream(input, streamer, options = {}, cancelSignal) {
|
|
|
383
384
|
return new Promise((resolve, reject) => {
|
|
384
385
|
cleanupFuncs.push(() => {
|
|
385
386
|
stopStream();
|
|
386
|
-
|
|
387
|
-
|
|
387
|
+
if (!mergedOptions.keepConnection) {
|
|
388
|
+
conn.mediaConnection.setSpeaking(false);
|
|
389
|
+
conn.mediaConnection.setVideoAttributes(false);
|
|
390
|
+
}
|
|
388
391
|
});
|
|
389
392
|
let cleanedUp = false;
|
|
390
393
|
const cleanup = () => {
|
package/package.json
CHANGED
package/src/client/Streamer.ts
CHANGED
|
@@ -104,63 +104,58 @@ export class Streamer {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
public createStream(): Promise<WebRtcConnWrapper> {
|
|
108
|
-
return new Promise<WebRtcConnWrapper>((resolve, reject) => {
|
|
109
|
-
if (!this.client.user) {
|
|
110
|
-
reject("Client not logged in");
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (!this.voiceConnection) {
|
|
114
|
-
reject("cannot start stream without first joining voice channel");
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return;
|
|
160
|
-
|
|
161
|
-
streamConn.setTokens(d.endpoint, d.token);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
107
|
+
public createStream(): Promise<WebRtcConnWrapper> {
|
|
108
|
+
return new Promise<WebRtcConnWrapper>((resolve, reject) => {
|
|
109
|
+
if (!this.client.user) {
|
|
110
|
+
reject("Client not logged in");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!this.voiceConnection) {
|
|
114
|
+
reject("cannot start stream without first joining voice channel");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (this.voiceConnection.streamConnection?.webRtcConn?.ready) {
|
|
118
|
+
resolve(this.voiceConnection.streamConnection.webRtcConn);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { guildId: clientGuildId, channelId: clientChannelId, session_id } = this.voiceConnection;
|
|
122
|
+
const { id: clientUserId } = this.client.user;
|
|
123
|
+
if (!session_id) throw new Error("Session doesn't exist yet");
|
|
124
|
+
|
|
125
|
+
let done = false;
|
|
126
|
+
const onStreamCreate = (d: any) => {
|
|
127
|
+
const { channelId, guildId, userId } = parseStreamKey(d.stream_key);
|
|
128
|
+
if (clientGuildId !== guildId || clientChannelId !== channelId || clientUserId !== userId) return;
|
|
129
|
+
streamConn.serverId = d.rtc_server_id;
|
|
130
|
+
streamConn.streamKey = d.stream_key;
|
|
131
|
+
streamConn.setSession(session_id);
|
|
132
|
+
};
|
|
133
|
+
const onStreamServerUpdate = (d: any) => {
|
|
134
|
+
const { channelId, guildId, userId } = parseStreamKey(d.stream_key);
|
|
135
|
+
if (clientGuildId !== guildId || clientChannelId !== channelId || clientUserId !== userId) return;
|
|
136
|
+
streamConn.setTokens(d.endpoint, d.token);
|
|
137
|
+
};
|
|
138
|
+
const cleanup = () => {
|
|
139
|
+
if (done) return;
|
|
140
|
+
done = true;
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
this._gatewayEmitter.off("STREAM_CREATE", onStreamCreate);
|
|
143
|
+
this._gatewayEmitter.off("STREAM_SERVER_UPDATE", onStreamServerUpdate);
|
|
144
|
+
};
|
|
145
|
+
const timer = setTimeout(() => {
|
|
146
|
+
cleanup();
|
|
147
|
+
reject(new Error("Timeout en attente de la passerelle Discord Go-Live"));
|
|
148
|
+
}, 10000);
|
|
149
|
+
|
|
150
|
+
this.signalStream();
|
|
151
|
+
const streamConn = new StreamConnection(this, clientGuildId, clientUserId, clientChannelId, (conn) => {
|
|
152
|
+
cleanup();
|
|
153
|
+
resolve(conn);
|
|
154
|
+
});
|
|
155
|
+
this.voiceConnection.streamConnection = streamConn;
|
|
156
|
+
this._gatewayEmitter.on("STREAM_CREATE", onStreamCreate);
|
|
157
|
+
this._gatewayEmitter.on("STREAM_SERVER_UPDATE", onStreamServerUpdate);
|
|
158
|
+
});
|
|
164
159
|
}
|
|
165
160
|
|
|
166
161
|
public async setStreamPreview(image: Buffer): Promise<void> {
|
|
@@ -93,7 +93,26 @@ export class WebRtcConnWrapper {
|
|
|
93
93
|
return this._webRtcConn;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
public
|
|
96
|
+
public waitUntilReady(timeoutMs = 5000) {
|
|
97
|
+
if (this.ready) return Promise.resolve();
|
|
98
|
+
return new Promise((resolve) => {
|
|
99
|
+
let done = false;
|
|
100
|
+
const finish = () => {
|
|
101
|
+
if (!done) {
|
|
102
|
+
done = true;
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
resolve();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
108
|
+
this._webRtcConn?.onStateChange((state) => {
|
|
109
|
+
if (state === "connected") {
|
|
110
|
+
finish();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
get ready() {
|
|
97
116
|
return this._webRtcConn?.state() === "connected";
|
|
98
117
|
}
|
|
99
118
|
|
package/src/media/newApi.ts
CHANGED
|
@@ -492,7 +492,8 @@ export async function playStream(
|
|
|
492
492
|
? opts.readrateInitialBurst
|
|
493
493
|
: defaultOptions.readrateInitialBurst,
|
|
494
494
|
|
|
495
|
-
streamPreview: opts.streamPreview ?? defaultOptions.streamPreview,
|
|
495
|
+
streamPreview: opts.streamPreview ?? defaultOptions.streamPreview,
|
|
496
|
+
keepConnection: opts.keepConnection ?? false,
|
|
496
497
|
} satisfies PlayStreamOptions;
|
|
497
498
|
}
|
|
498
499
|
|
|
@@ -520,11 +521,11 @@ export async function playStream(
|
|
|
520
521
|
let stopStream: () => unknown;
|
|
521
522
|
if (mergedOptions.type === "go-live") {
|
|
522
523
|
conn = await streamer.createStream();
|
|
523
|
-
stopStream = () => streamer.stopStream();
|
|
524
|
+
stopStream = () => { if (!mergedOptions.keepConnection) streamer.stopStream(); };
|
|
524
525
|
} else {
|
|
525
526
|
conn = streamer.voiceConnection.webRtcConn;
|
|
526
527
|
streamer.signalVideo(true);
|
|
527
|
-
stopStream = () => streamer.signalVideo(false);
|
|
528
|
+
stopStream = () => { if (!mergedOptions.keepConnection) streamer.signalVideo(false); };
|
|
528
529
|
}
|
|
529
530
|
conn.setPacketizer(videoCodecMap[video.codec]);
|
|
530
531
|
conn.mediaConnection.setSpeaking(true);
|