@@ -6,6 +6,7 @@ import '../../exceptions/exceptions.dart';
6
6
import '../../extensions/helpers_extension.dart' ;
7
7
import '../../js/js_engine.dart' ;
8
8
import '../../retry.dart' ;
9
+ import '../../reverse_engineering/cipher/chiper_new.dart' ;
9
10
import '../../reverse_engineering/cipher/cipher_manifest.dart' ;
10
11
import '../../reverse_engineering/heuristics.dart' ;
11
12
import '../../reverse_engineering/models/stream_info_provider.dart' ;
@@ -212,6 +213,19 @@ class StreamClient {
212
213
}
213
214
214
215
String ? _playerScript;
216
+ String ? _globalVar;
217
+
218
+ String ? _getGlobalVar (String playerScript) {
219
+ // Adapted from https://github.com/yt-dlp/yt-dlp/blob/7794374de8afb20499b023107e2abfd4e6b93ee4/yt_dlp/extractor/youtube/_video.py#L2295
220
+ return _globalVar ?? = _matchPatterns (playerScript, [
221
+ (
222
+ r'''
223
+ (["\'])use\s+strict\1;\s*(var\s+[a-zA-Z0-9_$]+\s*=\s*((["\'])(?:(?!(\4)).|\\.)+\4\.split\((["\'])(?:(?!(\6)).)+\6\)|\[\s*(?:(["\'])(?:(?!(\8)).|\\.)*\8\s*,?\s*)+\]))[;,]
224
+ ''' ,
225
+ 2
226
+ ),
227
+ ]);
228
+ }
215
229
216
230
Future <String > _getPlayerScript ([WatchPage ? page]) async {
217
231
page ?? = await WatchPage .get (_httpClient, '' );
@@ -248,15 +262,7 @@ class StreamClient {
248
262
'Could not find the decipher function in the player script.' );
249
263
}
250
264
251
- // Adapted from https://github.com/yt-dlp/yt-dlp/blob/7794374de8afb20499b023107e2abfd4e6b93ee4/yt_dlp/extractor/youtube/_video.py#L2295
252
- final globalVar = _matchPatterns (playerScript, [
253
- (
254
- r'''
255
- (["\'])use\s+strict\1;\s*(var\s+[a-zA-Z0-9_$]+\s*=\s*((["\'])(?:(?!(\4)).|\\.)+\4\.split\((["\'])(?:(?!(\6)).)+\6\)|\[\s*(?:(["\'])(?:(?!(\8)).|\\.)*\8\s*,?\s*)+\]))[;,]
256
- ''' ,
257
- 2
258
- ),
259
- ]);
265
+ final globalVar = _getGlobalVar (playerScript);
260
266
261
267
final func = funcMatch.replaceFirst ('function' , 'function main' );
262
268
@@ -299,16 +305,28 @@ class StreamClient {
299
305
url = url.setQueryParam ('n' , deciphered);
300
306
}
301
307
if (stream.signatureParameter != null ) {
302
- cipherManifest ?? =
303
- CipherManifest .decode (await _getPlayerScript (watchPage) );
308
+ final playerScript = await _getPlayerScript (watchPage);
309
+ cipherManifest ?? = CipherManifest .decode (playerScript );
304
310
final sig = stream.signature! ;
305
311
final sigParam = stream.signatureParameter! ;
306
312
if (cipherManifest != null ) {
307
313
final sigDeciphered = cipherManifest.decipher (sig);
308
314
url = url.setQueryParam (sigParam, sigDeciphered);
309
315
_logger.fine ('Deciphered signature: $sig -> $sigDeciphered ' );
310
316
} else {
311
- _logger.warning ('Could not decipher signature: $sig ' );
317
+ final globalVar = _getGlobalVar (playerScript);
318
+
319
+ final deciphererFunc =
320
+ getDecipherSignatureFunc (globalVar, playerScript);
321
+ final deciphered = deciphererFunc? .call (sig);
322
+ if (deciphered != null ) {
323
+ url = url.setQueryParam (sigParam, deciphered);
324
+ _logger.fine ('[2] Deciphered signature: $sig -> $deciphered ' );
325
+ } else {
326
+ // If we cannot decipher the signature, we log a warning
327
+ // and continue with the original URL.
328
+ _logger.warning ('Could not decipher signature: $sig ' );
329
+ }
312
330
}
313
331
}
314
332
0 commit comments