djs-selfbot-v13 3.7.32 → 3.7.33
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/package.json +1 -1
- package/src/client/Client.js +74 -1
- package/src/client/voice/ClientVoiceManager.js +84 -17
- package/src/client/voice/StreamSession.js +168 -0
- package/src/client/voice/VoiceConnection.js +265 -19
- package/src/client/voice/dispatcher/AnnexBDispatcher.js +64 -11
- package/src/client/voice/dispatcher/BaseDispatcher.js +13 -9
- package/src/client/voice/dispatcher/VideoDispatcher.js +33 -0
- package/src/client/voice/networking/DAVESession.js +234 -0
- package/src/client/voice/networking/VoiceWebSocket.js +284 -24
- package/src/client/voice/player/MediaPlayer.js +3 -1
- package/src/client/voice/player/processing/AnnexBBitstreamReaderWriter.js +137 -0
- package/src/client/voice/player/processing/SPSVUIRewriter.js +203 -0
- package/src/client/voice/receiver/PacketHandler.js +11 -4
- package/src/errors/Messages.js +6 -1
- package/src/util/Constants.js +12 -0
- package/typings/index.d.ts +29 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class AnnexBBitstreamReader {
|
|
4
|
+
constructor(buffer) {
|
|
5
|
+
this._buffer = buffer;
|
|
6
|
+
this._byteOffset = 0;
|
|
7
|
+
this._bitOffset = 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
readBits(count) {
|
|
11
|
+
if (count === 0) return 0;
|
|
12
|
+
let result = 0;
|
|
13
|
+
while (count > 0) {
|
|
14
|
+
if (this._byteOffset >= this._buffer.length) throw new Error('Bad byte offset');
|
|
15
|
+
if (
|
|
16
|
+
this._bitOffset === 0 &&
|
|
17
|
+
this._byteOffset >= 2 &&
|
|
18
|
+
this._buffer[this._byteOffset - 2] === 0 &&
|
|
19
|
+
this._buffer[this._byteOffset - 1] === 0 &&
|
|
20
|
+
this._buffer[this._byteOffset] === 3
|
|
21
|
+
) {
|
|
22
|
+
this._byteOffset++;
|
|
23
|
+
}
|
|
24
|
+
if (this._bitOffset === 0 && count >= 8) {
|
|
25
|
+
result = (result << 8) | this._buffer[this._byteOffset++];
|
|
26
|
+
count -= 8;
|
|
27
|
+
} else {
|
|
28
|
+
const numBitsToRead = Math.min(count, 8 - this._bitOffset);
|
|
29
|
+
const mask = (1 << numBitsToRead) - 1;
|
|
30
|
+
const newBits = (this._buffer[this._byteOffset] >> (8 - this._bitOffset - numBitsToRead)) & mask;
|
|
31
|
+
result = (result << numBitsToRead) | newBits;
|
|
32
|
+
count -= numBitsToRead;
|
|
33
|
+
this._bitOffset += numBitsToRead;
|
|
34
|
+
if (this._bitOffset === 8) {
|
|
35
|
+
this._bitOffset = 0;
|
|
36
|
+
this._byteOffset++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
readUnsigned(bits) {
|
|
44
|
+
return this.readBits(bits);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
readSigned(bits) {
|
|
48
|
+
const unsigned = this.readUnsigned(bits);
|
|
49
|
+
if (unsigned & (1 << (bits - 1))) return unsigned - (1 << bits);
|
|
50
|
+
return unsigned;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
readUnsignedExpGolomb() {
|
|
54
|
+
let leading0 = 0;
|
|
55
|
+
while (this.readBits(1) === 0) leading0++;
|
|
56
|
+
return (1 << leading0) + this.readBits(leading0) - 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
readSignedExpGolomb() {
|
|
60
|
+
const unsigned = this.readUnsignedExpGolomb();
|
|
61
|
+
if (unsigned % 2 === 0) return unsigned / -2;
|
|
62
|
+
return (unsigned + 1) / 2;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
class AnnexBBitstreamWriter {
|
|
67
|
+
constructor() {
|
|
68
|
+
this._arr = [];
|
|
69
|
+
this._pendingByte = 0;
|
|
70
|
+
this._bitOffset = 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
toBuffer() {
|
|
74
|
+
return Buffer.from(this._arr);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
flush() {
|
|
78
|
+
if (this._pendingByte <= 3 && this._arr.at(-1) === 0 && this._arr.at(-2) === 0) this._arr.push(3);
|
|
79
|
+
this._arr.push(this._pendingByte);
|
|
80
|
+
this._pendingByte = 0;
|
|
81
|
+
this._bitOffset = 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
writeBits(bits, count) {
|
|
85
|
+
while (count > 0) {
|
|
86
|
+
if (this._bitOffset === 0) {
|
|
87
|
+
if (count >= 8) {
|
|
88
|
+
this._pendingByte = (bits >> (count - 8)) & 0xff;
|
|
89
|
+
count -= 8;
|
|
90
|
+
this.flush();
|
|
91
|
+
} else {
|
|
92
|
+
const mask = (1 << count) - 1;
|
|
93
|
+
this._pendingByte |= (bits & mask) << (8 - count);
|
|
94
|
+
this._bitOffset = count;
|
|
95
|
+
count = 0;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
const numBitsToWrite = Math.min(8 - this._bitOffset, count);
|
|
99
|
+
const bitsToWrite = (bits >> (count - numBitsToWrite)) & ((1 << numBitsToWrite) - 1);
|
|
100
|
+
this._pendingByte |= bitsToWrite << (8 - this._bitOffset - numBitsToWrite);
|
|
101
|
+
count -= numBitsToWrite;
|
|
102
|
+
this._bitOffset += numBitsToWrite;
|
|
103
|
+
if (this._bitOffset === 8) {
|
|
104
|
+
this._bitOffset = 0;
|
|
105
|
+
this.flush();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
writeUnsigned(num, count) {
|
|
112
|
+
if (num < 0) throw new Error('Expected a non-negative number');
|
|
113
|
+
this.writeBits(num, count);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
writeSigned(num, count) {
|
|
117
|
+
if (count <= 0) return;
|
|
118
|
+
if (count > 32) throw new Error('writeSigned supports up to 32 bits');
|
|
119
|
+
const mask = count === 32 ? 0xffffffff >>> 0 : (((1 << count) >>> 0) - 1) >>> 0;
|
|
120
|
+
this.writeBits((num & mask) >>> 0, count);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
writeUnsignedExpGolomb(num) {
|
|
124
|
+
if (num < 0) throw new Error('Expected a non-negative number');
|
|
125
|
+
num++;
|
|
126
|
+
const bitCount = 32 - Math.clz32(num >>> 0);
|
|
127
|
+
this.writeBits(0, bitCount - 1);
|
|
128
|
+
this.writeBits(num, bitCount);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
writeSignedExpGolomb(num) {
|
|
132
|
+
if (num < 0) this.writeUnsignedExpGolomb(-2 * num);
|
|
133
|
+
else this.writeUnsignedExpGolomb(2 * num - 1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = { AnnexBBitstreamReader, AnnexBBitstreamWriter };
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { AnnexBBitstreamReader, AnnexBBitstreamWriter } = require('./AnnexBBitstreamReaderWriter');
|
|
4
|
+
|
|
5
|
+
function rewriteSPSVUI(buffer) {
|
|
6
|
+
const reader = new AnnexBBitstreamReader(buffer.subarray(1));
|
|
7
|
+
const writer = new AnnexBBitstreamWriter();
|
|
8
|
+
|
|
9
|
+
const readBit = (n = 1) => reader.readBits(n);
|
|
10
|
+
const writeBit = (v, n = 1) => writer.writeBits(v, n);
|
|
11
|
+
const readU = n => reader.readUnsigned(n);
|
|
12
|
+
const writeU = (v, n) => writer.writeUnsigned(v, n);
|
|
13
|
+
const readUE = () => reader.readUnsignedExpGolomb();
|
|
14
|
+
const writeUE = v => writer.writeUnsignedExpGolomb(v);
|
|
15
|
+
const readSE = () => reader.readSignedExpGolomb();
|
|
16
|
+
const writeSE = v => writer.writeSignedExpGolomb(v);
|
|
17
|
+
|
|
18
|
+
writeU(buffer[0], 8);
|
|
19
|
+
|
|
20
|
+
const profile_idc = readU(8);
|
|
21
|
+
writeU(profile_idc, 8);
|
|
22
|
+
const constraint_flags = readU(8);
|
|
23
|
+
writeU(constraint_flags, 8);
|
|
24
|
+
const level_idc = readU(8);
|
|
25
|
+
writeU(level_idc, 8);
|
|
26
|
+
const seq_parameter_set_id = readUE();
|
|
27
|
+
writeUE(seq_parameter_set_id);
|
|
28
|
+
|
|
29
|
+
const highProfiles = new Set([100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 144]);
|
|
30
|
+
if (highProfiles.has(profile_idc)) {
|
|
31
|
+
const chroma_format_idc = readUE();
|
|
32
|
+
writeUE(chroma_format_idc);
|
|
33
|
+
if (chroma_format_idc === 3) writeBit(readBit(1), 1);
|
|
34
|
+
writeUE(readUE());
|
|
35
|
+
writeUE(readUE());
|
|
36
|
+
writeBit(readBit(1), 1);
|
|
37
|
+
const seq_scaling_matrix_present_flag = readBit(1);
|
|
38
|
+
writeBit(seq_scaling_matrix_present_flag, 1);
|
|
39
|
+
if (seq_scaling_matrix_present_flag) {
|
|
40
|
+
const scalingCount = chroma_format_idc !== 3 ? 8 : 12;
|
|
41
|
+
for (let i = 0; i < scalingCount; i++) {
|
|
42
|
+
const seq_scaling_list_present_flag = readBit(1);
|
|
43
|
+
writeBit(seq_scaling_list_present_flag, 1);
|
|
44
|
+
if (seq_scaling_list_present_flag) {
|
|
45
|
+
const size = i < 6 ? 16 : 64;
|
|
46
|
+
let lastScale = 8;
|
|
47
|
+
for (let j = 0; j < size; j++) {
|
|
48
|
+
const delta = readSE();
|
|
49
|
+
writeSE(delta);
|
|
50
|
+
const nextScale = (lastScale + delta + 256) % 256;
|
|
51
|
+
if (nextScale !== 0) lastScale = nextScale;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
writeUE(readUE());
|
|
59
|
+
const pic_order_cnt_type = readUE();
|
|
60
|
+
writeUE(pic_order_cnt_type);
|
|
61
|
+
if (pic_order_cnt_type === 0) writeUE(readUE());
|
|
62
|
+
else if (pic_order_cnt_type === 1) {
|
|
63
|
+
writeBit(readBit(1), 1);
|
|
64
|
+
writeSE(readSE());
|
|
65
|
+
writeSE(readSE());
|
|
66
|
+
const num_ref_frames_in_pic_order_cnt_cycle = readUE();
|
|
67
|
+
writeUE(num_ref_frames_in_pic_order_cnt_cycle);
|
|
68
|
+
for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) writeSE(readSE());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const max_num_ref_frames = readUE();
|
|
72
|
+
writeUE(max_num_ref_frames);
|
|
73
|
+
writeBit(readBit(1), 1);
|
|
74
|
+
writeUE(readUE());
|
|
75
|
+
writeUE(readUE());
|
|
76
|
+
const frame_mbs_only_flag = readBit(1);
|
|
77
|
+
writeBit(frame_mbs_only_flag, 1);
|
|
78
|
+
if (frame_mbs_only_flag === 0) writeBit(readBit(1), 1);
|
|
79
|
+
writeBit(readBit(1), 1);
|
|
80
|
+
const frame_cropping_flag = readBit(1);
|
|
81
|
+
writeBit(frame_cropping_flag, 1);
|
|
82
|
+
if (frame_cropping_flag) {
|
|
83
|
+
writeUE(readUE());
|
|
84
|
+
writeUE(readUE());
|
|
85
|
+
writeUE(readUE());
|
|
86
|
+
writeUE(readUE());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function addBitstreamRestriction() {
|
|
90
|
+
writeBit(1, 1);
|
|
91
|
+
writeUE(2);
|
|
92
|
+
writeUE(1);
|
|
93
|
+
writeUE(16);
|
|
94
|
+
writeUE(16);
|
|
95
|
+
writeUE(0);
|
|
96
|
+
writeUE(max_num_ref_frames);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const vui_parameters_present_flag = readBit(1);
|
|
100
|
+
writeBit(1, 1);
|
|
101
|
+
if (!vui_parameters_present_flag) {
|
|
102
|
+
writeBit(0, 2);
|
|
103
|
+
writeBit(0, 1);
|
|
104
|
+
writeBit(0, 5);
|
|
105
|
+
writeBit(1, 1);
|
|
106
|
+
addBitstreamRestriction();
|
|
107
|
+
} else {
|
|
108
|
+
const aspect_ratio_info_present_flag = readBit(1);
|
|
109
|
+
writeBit(aspect_ratio_info_present_flag, 1);
|
|
110
|
+
if (aspect_ratio_info_present_flag) {
|
|
111
|
+
const aspect_ratio_idc = readU(8);
|
|
112
|
+
writeU(aspect_ratio_idc, 8);
|
|
113
|
+
if (aspect_ratio_idc === 255) {
|
|
114
|
+
writeU(readU(16), 16);
|
|
115
|
+
writeU(readU(16), 16);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const overscan_info_present_flag = readBit(1);
|
|
119
|
+
writeBit(overscan_info_present_flag, 1);
|
|
120
|
+
if (overscan_info_present_flag) writeBit(readBit(1), 1);
|
|
121
|
+
const video_signal_type_present_flag = readBit(1);
|
|
122
|
+
writeBit(0, 1);
|
|
123
|
+
if (video_signal_type_present_flag) {
|
|
124
|
+
readBit(3);
|
|
125
|
+
readBit(1);
|
|
126
|
+
const colour_description_present_flag = readBit(1);
|
|
127
|
+
if (colour_description_present_flag) {
|
|
128
|
+
readU(8);
|
|
129
|
+
readU(8);
|
|
130
|
+
readU(8);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const chroma_loc_info_present_flag = readBit(1);
|
|
134
|
+
writeBit(chroma_loc_info_present_flag, 1);
|
|
135
|
+
if (chroma_loc_info_present_flag) {
|
|
136
|
+
writeUE(readUE());
|
|
137
|
+
writeUE(readUE());
|
|
138
|
+
}
|
|
139
|
+
const timing_info_present_flag = readBit(1);
|
|
140
|
+
writeBit(timing_info_present_flag, 1);
|
|
141
|
+
if (timing_info_present_flag) {
|
|
142
|
+
writeU(readU(32), 32);
|
|
143
|
+
writeU(readU(32), 32);
|
|
144
|
+
writeBit(readBit(1), 1);
|
|
145
|
+
}
|
|
146
|
+
const nal_hrd_parameters_present_flag = readBit(1);
|
|
147
|
+
writeBit(nal_hrd_parameters_present_flag, 1);
|
|
148
|
+
if (nal_hrd_parameters_present_flag) {
|
|
149
|
+
const cpb_cnt_minus1 = readUE();
|
|
150
|
+
writeUE(cpb_cnt_minus1);
|
|
151
|
+
writeBit(readBit(4), 4);
|
|
152
|
+
writeBit(readBit(4), 4);
|
|
153
|
+
for (let i = 0; i <= cpb_cnt_minus1; i++) {
|
|
154
|
+
writeUE(readUE());
|
|
155
|
+
writeUE(readUE());
|
|
156
|
+
writeBit(readBit(1), 1);
|
|
157
|
+
}
|
|
158
|
+
writeBit(readBit(5), 5);
|
|
159
|
+
writeBit(readBit(5), 5);
|
|
160
|
+
writeBit(readBit(5), 5);
|
|
161
|
+
writeBit(readBit(5), 5);
|
|
162
|
+
}
|
|
163
|
+
const vcl_hrd_parameters_present_flag = readBit(1);
|
|
164
|
+
writeBit(vcl_hrd_parameters_present_flag, 1);
|
|
165
|
+
if (vcl_hrd_parameters_present_flag) {
|
|
166
|
+
const cpb_cnt_minus1 = readUE();
|
|
167
|
+
writeUE(cpb_cnt_minus1);
|
|
168
|
+
writeBit(readBit(4), 4);
|
|
169
|
+
writeBit(readBit(4), 4);
|
|
170
|
+
for (let i = 0; i <= cpb_cnt_minus1; i++) {
|
|
171
|
+
writeUE(readUE());
|
|
172
|
+
writeUE(readUE());
|
|
173
|
+
writeBit(readBit(1), 1);
|
|
174
|
+
}
|
|
175
|
+
writeBit(readBit(5), 5);
|
|
176
|
+
writeBit(readBit(5), 5);
|
|
177
|
+
writeBit(readBit(5), 5);
|
|
178
|
+
writeBit(readBit(5), 5);
|
|
179
|
+
}
|
|
180
|
+
if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) writeBit(readBit(1), 1);
|
|
181
|
+
writeBit(readBit(1), 1);
|
|
182
|
+
const bitstream_restriction_flag = readBit(1);
|
|
183
|
+
writeBit(1, 1);
|
|
184
|
+
if (!bitstream_restriction_flag) addBitstreamRestriction();
|
|
185
|
+
else {
|
|
186
|
+
writeBit(readBit(1), 1);
|
|
187
|
+
writeUE(readUE());
|
|
188
|
+
writeUE(readUE());
|
|
189
|
+
writeUE(readUE());
|
|
190
|
+
writeUE(readUE());
|
|
191
|
+
readUE();
|
|
192
|
+
writeUE(0);
|
|
193
|
+
readUE();
|
|
194
|
+
writeUE(max_num_ref_frames);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
writeBit(1, 1);
|
|
199
|
+
writer.flush();
|
|
200
|
+
return writer.toBuffer();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = { rewriteSPSVUI };
|
|
@@ -72,7 +72,7 @@ class PacketHandler extends EventEmitter {
|
|
|
72
72
|
return stream;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
parseBuffer(buffer) {
|
|
75
|
+
parseBuffer(buffer, userId) {
|
|
76
76
|
const { secret_key, mode } = this.receiver.connection.authentication;
|
|
77
77
|
// Open packet
|
|
78
78
|
if (!secret_key) return new Error('secret_key cannot be null or undefined');
|
|
@@ -129,7 +129,14 @@ class PacketHandler extends EventEmitter {
|
|
|
129
129
|
}
|
|
130
130
|
*/
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
const rtp = RtpPacket.deSerialize(Buffer.concat([header, packet]));
|
|
133
|
+
const dave = this.connection.dave;
|
|
134
|
+
if (dave && userId && rtp.payload) {
|
|
135
|
+
const decrypted = dave.decrypt(rtp.payload, userId);
|
|
136
|
+
if (decrypted === null) return new Error('DAVE_DECRYPT_FAILED');
|
|
137
|
+
rtp.payload = decrypted;
|
|
138
|
+
}
|
|
139
|
+
return rtp;
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
audioReceiver(ssrc, userStat, opusPacket) {
|
|
@@ -233,12 +240,12 @@ class PacketHandler extends EventEmitter {
|
|
|
233
240
|
let userStat, packet;
|
|
234
241
|
if (this.connection.ssrcMap.has(ssrc)) {
|
|
235
242
|
userStat = this.connection.ssrcMap.get(ssrc); // Audio_ssrc
|
|
236
|
-
packet = this.parseBuffer(buffer);
|
|
243
|
+
packet = this.parseBuffer(buffer, userStat.userId);
|
|
237
244
|
this.audioReceiver(ssrc, userStat, packet);
|
|
238
245
|
this.audioReceiverForStream(ssrc, userStat, packet);
|
|
239
246
|
} else if (this.connection.ssrcMap.has(ssrc - 1)) {
|
|
240
247
|
userStat = this.connection.ssrcMap.get(ssrc - 1); // Video_ssrc
|
|
241
|
-
packet = this.parseBuffer(buffer);
|
|
248
|
+
packet = this.parseBuffer(buffer, userStat.userId);
|
|
242
249
|
this.videoReceiver(ssrc, userStat, packet);
|
|
243
250
|
}
|
|
244
251
|
if (userStat && !(packet instanceof Error)) this.receiver.emit('receiverData', userStat, packet);
|
package/src/errors/Messages.js
CHANGED
|
@@ -186,7 +186,9 @@ const Messages = {
|
|
|
186
186
|
VOICE_USER_MISSING: "Couldn't resolve the user to create stream.",
|
|
187
187
|
VOICE_JOIN_CHANNEL: (full = false) =>
|
|
188
188
|
`You do not have permission to join this voice channel${full ? '; it is full.' : '.'}`,
|
|
189
|
-
VOICE_CONNECTION_TIMEOUT: 'Connection not established within
|
|
189
|
+
VOICE_CONNECTION_TIMEOUT: 'Connection not established within 30 seconds.',
|
|
190
|
+
VOICE_DAVE_REQUIRED: '%s',
|
|
191
|
+
VOICE_SESSION_EXPIRED: 'Voice session is no longer valid.',
|
|
190
192
|
VOICE_TOKEN_ABSENT: 'Token not provided from voice server packet.',
|
|
191
193
|
VOICE_SESSION_ABSENT: 'Session ID not supplied.',
|
|
192
194
|
VOICE_INVALID_ENDPOINT: 'Invalid endpoint received.',
|
|
@@ -208,6 +210,9 @@ const Messages = {
|
|
|
208
210
|
|
|
209
211
|
STREAM_CONNECTION_READONLY: 'Cannot send data to a read-only stream',
|
|
210
212
|
STREAM_CANNOT_JOIN: 'Cannot join a stream to itself',
|
|
213
|
+
STREAM_URL_REQUIRED: 'A url is required to start a stream.',
|
|
214
|
+
STREAM_CHANNEL_REQUIRED: 'guildId and channelId are required to start a stream.',
|
|
215
|
+
STREAM_CHANNEL_NOT_FOUND: 'The specified voice channel could not be found.',
|
|
211
216
|
VOICE_USER_NOT_STREAMING: 'User is not streaming',
|
|
212
217
|
POLL_ALREADY_EXPIRED: 'This poll has already expired.',
|
|
213
218
|
METHOD_WARNING:
|
package/src/util/Constants.js
CHANGED
|
@@ -284,6 +284,18 @@ exports.VoiceOpcodes = {
|
|
|
284
284
|
MEDIA_SINK_WANTS: 15,
|
|
285
285
|
VOICE_BACKEND_VERSION: 16,
|
|
286
286
|
CHANNEL_OPTIONS_UPDATE: 17,
|
|
287
|
+
CLIENTS_CONNECT: 11,
|
|
288
|
+
DAVE_PREPARE_TRANSITION: 21,
|
|
289
|
+
DAVE_EXECUTE_TRANSITION: 22,
|
|
290
|
+
DAVE_TRANSITION_READY: 23,
|
|
291
|
+
DAVE_PREPARE_EPOCH: 24,
|
|
292
|
+
DAVE_MLS_EXTERNAL_SENDER: 25,
|
|
293
|
+
DAVE_MLS_KEY_PACKAGE: 26,
|
|
294
|
+
DAVE_MLS_PROPOSALS: 27,
|
|
295
|
+
DAVE_MLS_COMMIT_WELCOME: 28,
|
|
296
|
+
DAVE_MLS_ANNOUNCE_COMMIT_TRANSITION: 29,
|
|
297
|
+
DAVE_MLS_WELCOME: 30,
|
|
298
|
+
DAVE_MLS_INVALID_COMMIT_WELCOME: 31,
|
|
287
299
|
};
|
|
288
300
|
|
|
289
301
|
/**
|
package/typings/index.d.ts
CHANGED
|
@@ -918,6 +918,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
|
|
|
918
918
|
}
|
|
919
919
|
>
|
|
920
920
|
>;
|
|
921
|
+
public startStream(options: StartStreamOptions): Promise<StreamSession>;
|
|
921
922
|
|
|
922
923
|
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => Awaitable<void>): this;
|
|
923
924
|
public on<S extends string | symbol>(
|
|
@@ -1189,6 +1190,34 @@ export class BaseDispatcher extends Writable {
|
|
|
1189
1190
|
public once(event: string, listener: (...args: any[]) => void): this;
|
|
1190
1191
|
}
|
|
1191
1192
|
|
|
1193
|
+
export interface StartStreamOptions {
|
|
1194
|
+
guildId: Snowflake;
|
|
1195
|
+
channelId: Snowflake;
|
|
1196
|
+
url: string;
|
|
1197
|
+
fps?: number;
|
|
1198
|
+
height?: number;
|
|
1199
|
+
bitrate?: number;
|
|
1200
|
+
audioBitrate?: number;
|
|
1201
|
+
videoCodec?: 'H264' | 'VP8';
|
|
1202
|
+
preset?: string;
|
|
1203
|
+
audio?: boolean;
|
|
1204
|
+
/** Enable webcam. Default false (screenshare only). */
|
|
1205
|
+
video?: boolean;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
export class StreamSession extends EventEmitter {
|
|
1209
|
+
public readonly client: Client;
|
|
1210
|
+
public readonly voiceConnection: VoiceConnection;
|
|
1211
|
+
public readonly streamConnection: StreamConnection;
|
|
1212
|
+
public pause(): void;
|
|
1213
|
+
public resume(): void;
|
|
1214
|
+
public stop(): void;
|
|
1215
|
+
public replay(): VideoDispatcher;
|
|
1216
|
+
public disconnect(): void;
|
|
1217
|
+
public on(event: 'finish', listener: () => void): this;
|
|
1218
|
+
public once(event: 'finish', listener: () => void): this;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1192
1221
|
export class AudioDispatcher extends VolumeMixin(BaseDispatcher) {
|
|
1193
1222
|
constructor(player: object, options?: StreamOptions, streams?: object);
|
|
1194
1223
|
public readonly bitrateEditable: boolean;
|