@@ -120,13 +120,11 @@ enum CryptorError {
120
120
121
121
class FrameInfo {
122
122
FrameInfo({
123
- required this.mimeType,
124
123
required this.ssrc,
125
124
required this.timestamp,
126
125
required this.buffer,
127
126
required this.frameType,
128
127
});
129
- String? mimeType;
130
128
String frameType;
131
129
int ssrc;
132
130
int timestamp;
@@ -144,7 +142,6 @@ class FrameCryptor {
144
142
String? participantIdentity;
145
143
String? trackId;
146
144
String? codec;
147
- String? mineType;
148
145
ParticipantKeyHandler keyHandler;
149
146
KeyOptions get keyOptions => keyHandler.keyOptions;
150
147
late String kind;
@@ -282,8 +279,7 @@ class FrameCryptor {
282
279
data = obj.data.toDart.asUint8List();
283
280
if (obj.hasProperty('type'.toJS).toDart) {
284
281
frameType = obj.type;
285
- logger.finer(
286
- 'frameType: $frameType, mineTye ${obj.getMetadata().mimeType}');
282
+ logger.finer('frameType: $frameType');
287
283
}
288
284
}
289
285
@@ -318,33 +314,40 @@ class FrameCryptor {
318
314
}
319
315
320
316
FrameInfo readFrameInfo(JSObject frameObj) {
321
- Uint8List buffer;
317
+ var buffer = Uint8List(0) ;
322
318
var synchronizationSource = 0;
323
319
var timestamp = 0;
324
320
var frameType = '';
325
321
if (frameObj is web.RTCEncodedVideoFrame) {
326
322
buffer = frameObj.data.toDart.asUint8List();
327
323
if (frameObj.hasProperty('type'.toJS).toDart) {
328
324
frameType = frameObj.type;
329
- logger.finer(
330
- 'frameType: $frameType, mineTye ${frameObj.getMetadata().mimeType}');
325
+ logger.finer('frameType: $frameType');
331
326
}
332
327
synchronizationSource = frameObj.getMetadata().synchronizationSource;
333
- timestamp = frameObj.getMetadata().rtpTimestamp.toInt();
334
- mineType ??= frameObj.getMetadata().mimeType;
328
+ if (frameObj.getMetadata().hasProperty('rtpTimestamp'.toJS).toDart) {
329
+ timestamp = frameObj.getMetadata().rtpTimestamp.toInt();
330
+ } else if (frameObj.hasProperty('timestamp'.toJS).toDart) {
331
+ timestamp =
332
+ (frameObj.getProperty('timestamp'.toJS) as JSNumber).toDartInt;
333
+ }
335
334
} else if (frameObj is web.RTCEncodedAudioFrame) {
336
335
buffer = frameObj.data.toDart.asUint8List();
337
336
synchronizationSource = frameObj.getMetadata().synchronizationSource;
338
- timestamp = frameObj.getMetadata().rtpTimestamp.toInt();
339
- mineType ??= frameObj.getMetadata().mimeType;
337
+
338
+ if (frameObj.getMetadata().hasProperty('rtpTimestamp'.toJS).toDart) {
339
+ timestamp = frameObj.getMetadata().rtpTimestamp.toInt();
340
+ } else if (frameObj.hasProperty('timestamp'.toJS).toDart) {
341
+ timestamp =
342
+ (frameObj.getProperty('timestamp'.toJS) as JSNumber).toDartInt;
343
+ }
340
344
frameType = 'audio';
341
345
} else {
342
346
throw Exception(
343
347
'encodeFunction: frame is not a RTCEncodedVideoFrame or RTCEncodedAudioFrame');
344
348
}
345
349
346
350
return FrameInfo(
347
- mimeType: mineType,
348
351
ssrc: synchronizationSource,
349
352
timestamp: timestamp,
350
353
buffer: buffer,
@@ -366,43 +369,44 @@ class FrameCryptor {
366
369
JSObject frameObj,
367
370
web.TransformStreamDefaultController controller,
368
371
) async {
369
- var srcFrame = readFrameInfo(frameObj);
370
-
371
- mineType ??= srcFrame.mimeType;
372
-
373
- logger.finer(
374
- 'encodeFunction: frame ${srcFrame.buffer.length}, synchronizationSource ${srcFrame.ssrc} mineType $mineType frameType ${srcFrame.frameType}');
375
-
376
- if (!enabled ||
377
- // skip for encryption for empty dtx frames
378
- srcFrame.buffer.isEmpty) {
379
- if (keyOptions.discardFrameWhenCryptorNotReady) {
372
+ try {
373
+ if (!enabled ||
374
+ // skip for encryption for empty dtx frames
375
+ ((frameObj is web.RTCEncodedVideoFrame &&
376
+ frameObj.data.toDart.lengthInBytes == 0) ||
377
+ (frameObj is web.RTCEncodedAudioFrame &&
378
+ frameObj.data.toDart.lengthInBytes == 0))) {
379
+ if (keyOptions.discardFrameWhenCryptorNotReady) {
380
+ return;
381
+ }
382
+ controller.enqueue(frameObj);
380
383
return;
381
384
}
382
- controller.enqueue(frameObj);
383
- return;
384
- }
385
385
386
- var secretKey = keyHandler.getKeySet(currentKeyIndex)?.encryptionKey;
387
- var keyIndex = currentKeyIndex;
386
+ var srcFrame = readFrameInfo(frameObj);
388
387
389
- if (secretKey == null) {
390
- if (lastError != CryptorError.kMissingKey) {
391
- lastError = CryptorError.kMissingKey;
392
- postMessage({
393
- 'type': 'cryptorState',
394
- 'msgType': 'event',
395
- 'participantId': participantIdentity,
396
- 'trackId': trackId,
397
- 'kind': kind,
398
- 'state': 'missingKey',
399
- 'error': 'Missing key for track $trackId',
400
- });
388
+ logger.fine(
389
+ 'encodeFunction: buffer ${srcFrame.buffer.length}, synchronizationSource ${srcFrame.ssrc} frameType ${srcFrame.frameType}');
390
+
391
+ var secretKey = keyHandler.getKeySet(currentKeyIndex)?.encryptionKey;
392
+ var keyIndex = currentKeyIndex;
393
+
394
+ if (secretKey == null) {
395
+ if (lastError != CryptorError.kMissingKey) {
396
+ lastError = CryptorError.kMissingKey;
397
+ postMessage({
398
+ 'type': 'cryptorState',
399
+ 'msgType': 'event',
400
+ 'participantId': participantIdentity,
401
+ 'trackId': trackId,
402
+ 'kind': kind,
403
+ 'state': 'missingKey',
404
+ 'error': 'Missing key for track $trackId',
405
+ });
406
+ }
407
+ return;
401
408
}
402
- return;
403
- }
404
409
405
- try {
406
410
var headerLength =
407
411
kind == 'video' ? getUnencryptedBytes(frameObj, codec) : 1;
408
412
@@ -426,7 +430,7 @@ class FrameCryptor {
426
430
.toDart as JSArrayBuffer;
427
431
428
432
logger.finer(
429
- 'encodeFunction, buffer: ${srcFrame.buffer.length}, cipherText: ${cipherText.toDart.asUint8List().length}');
433
+ 'encodeFunction: encrypted buffer: ${srcFrame.buffer.length}, cipherText: ${cipherText.toDart.asUint8List().length}');
430
434
var finalBuffer = BytesBuilder();
431
435
432
436
finalBuffer
@@ -436,8 +440,6 @@ class FrameCryptor {
436
440
finalBuffer.add(frameTrailer.buffer.asUint8List());
437
441
438
442
enqueueFrame(frameObj, controller, finalBuffer);
439
- logger.finer(
440
- 'encodeFunction: ssrc ${srcFrame.ssrc} buffer length ${srcFrame.buffer.length}, encrypted: ${finalBuffer.length}, headerLength $headerLength cipherText ${cipherText.toDart.asUint8List().length} iv ${iv.length} frameTrailer ${frameTrailer.buffer.asUint8List().length}');
441
443
442
444
if (lastError != CryptorError.kOk) {
443
445
lastError = CryptorError.kOk;
@@ -453,7 +455,7 @@ class FrameCryptor {
453
455
}
454
456
455
457
logger.finer(
456
- 'encrypto kind $kind,codec $codec headerLength: $headerLength, timestamp: ${srcFrame.timestamp}, ssrc: ${srcFrame.ssrc}, data length: ${srcFrame.buffer.length}, encrypted length: ${finalBuffer.toBytes().length}, iv $iv');
458
+ 'encodeFunction[CryptorError.kOk]: frame enqueued kind $kind,codec $codec headerLength: $headerLength, timestamp: ${srcFrame.timestamp}, ssrc: ${srcFrame.ssrc}, data length: ${srcFrame.buffer.length}, encrypted length: ${finalBuffer.toBytes().length}, iv $iv');
457
459
} catch (e) {
458
460
logger.warning('encodeFunction encrypt: e ${e.toString()}');
459
461
if (lastError != CryptorError.kEncryptError) {
@@ -476,11 +478,9 @@ class FrameCryptor {
476
478
web.TransformStreamDefaultController controller,
477
479
) async {
478
480
var srcFrame = readFrameInfo(frameObj);
479
- mineType ??= srcFrame.mimeType;
480
481
var ratchetCount = 0;
481
482
482
- logger.finer(
483
- 'decodeFunction: frame ${srcFrame.buffer.length} mineType $mineType');
483
+ logger.fine('decodeFunction: frame lenght ${srcFrame.buffer.length}');
484
484
485
485
ByteBuffer? decrypted;
486
486
KeySet? initialKeySet;
@@ -510,17 +510,18 @@ class FrameCryptor {
510
510
if (sifGuard.isSifAllowed()) {
511
511
var frameType =
512
512
srcFrame.buffer.sublist(srcFrame.buffer.length - 1)[0];
513
- logger.finer('skip uncrypted frame, type $frameType');
513
+ logger
514
+ .finer('ecodeFunction: skip uncrypted frame, type $frameType');
514
515
var finalBuffer = BytesBuilder();
515
516
finalBuffer.add(Uint8List.fromList(srcFrame.buffer
516
517
.sublist(0, srcFrame.buffer.length - (magicBytes.length + 1))));
517
518
enqueueFrame(frameObj, controller, finalBuffer);
518
- logger.fine('enqueing silent frame');
519
+ logger.fine('ecodeFunction: enqueing silent frame');
519
520
controller.enqueue(frameObj);
520
521
} else {
521
- logger.finer('SIF limit reached, dropping frame');
522
+ logger.finer('ecodeFunction: SIF limit reached, dropping frame');
522
523
}
523
- logger.finer('enqueing silent frame');
524
+ logger.finer('ecodeFunction: enqueing silent frame');
524
525
controller.enqueue(frameObj);
525
526
return;
526
527
} else {
@@ -545,9 +546,6 @@ class FrameCryptor {
545
546
logger.finer(
546
547
'decodeFunction: start decrypting frame headerLength $headerLength ${srcFrame.buffer.length} frameTrailer $frameTrailer, ivLength $ivLength, keyIndex $keyIndex, iv $iv');
547
548
548
- logger.finer(
549
- 'decodeFunction: ssrc ${srcFrame.ssrc} buffer length ${srcFrame.buffer.length}, encrypted: ${srcFrame.buffer.length}, headerLength $headerLength cipherText ${srcFrame.buffer.sublist(headerLength, srcFrame.buffer.length - ivLength - 2).length} iv ${iv.length} frameTrailer ${frameTrailer.buffer.asUint8List().length}');
550
-
551
549
/// missingKey flow:
552
550
/// tries to decrypt once, fails, tries to ratchet once and decrypt again,
553
551
/// fails (does not save ratcheted key), bumps _decryptionFailureCount,
@@ -589,15 +587,16 @@ class FrameCryptor {
589
587
.toDart) as JSArrayBuffer)
590
588
.toDart;
591
589
logger.finer(
592
- 'decodeFunction: decryptFrameInternal: decrypted: ${decrypted!.asUint8List().length}');
590
+ 'decodeFunction:: decryptFrameInternal: decrypted: ${decrypted!.asUint8List().length}');
593
591
594
592
if (decrypted == null) {
595
593
throw Exception('[decryptFrameInternal] could not decrypt');
596
594
}
597
595
logger.finer(
598
- 'decryptFrameInternal: decrypted: ${decrypted!.asUint8List().length}');
596
+ 'decodeFunction:: decryptFrameInternal: decrypted: ${decrypted!.asUint8List().length}');
599
597
if (currentkeySet != initialKeySet) {
600
- logger.fine('ratchetKey: decryption ok, newState: kKeyRatcheted');
598
+ logger.fine(
599
+ 'decodeFunction::decryptFrameInternal: ratchetKey: decryption ok, newState: kKeyRatcheted');
601
600
await keyHandler.setKeySetFromMaterial(
602
601
currentkeySet, initialKeyIndex);
603
602
}
@@ -606,9 +605,9 @@ class FrameCryptor {
606
605
lastError != CryptorError.kKeyRatcheted &&
607
606
ratchetCount > 0) {
608
607
logger.finer(
609
- 'KeyRatcheted: ssrc ${srcFrame.ssrc} timestamp ${srcFrame.timestamp} ratchetCount $ratchetCount participantId: $participantIdentity');
608
+ 'decodeFunction::decryptFrameInternal: KeyRatcheted: ssrc ${srcFrame.ssrc} timestamp ${srcFrame.timestamp} ratchetCount $ratchetCount participantId: $participantIdentity');
610
609
logger.finer(
611
- 'ratchetKey: lastError != CryptorError.kKeyRatcheted, reset state to kKeyRatcheted');
610
+ 'decodeFunction::decryptFrameInternal: ratchetKey: lastError != CryptorError.kKeyRatcheted, reset state to kKeyRatcheted');
612
611
613
612
lastError = CryptorError.kKeyRatcheted;
614
613
postMessage({
@@ -659,7 +658,7 @@ class FrameCryptor {
659
658
keyHandler.decryptionSuccess();
660
659
661
660
logger.finer(
662
- 'decodeFunction: buffer length ${srcFrame.buffer.length}, decrypted: ${decrypted!.asUint8List().length}');
661
+ 'decodeFunction: decryption success, buffer length ${srcFrame.buffer.length}, decrypted: ${decrypted!.asUint8List().length}');
663
662
664
663
var finalBuffer = BytesBuilder();
665
664
@@ -681,8 +680,8 @@ class FrameCryptor {
681
680
});
682
681
}
683
682
684
- logger.finer (
685
- 'decrypto kind $kind, codec $mineType headerLength: $headerLength, timestamp: ${srcFrame.timestamp}, ssrc: ${srcFrame.ssrc}, data length: ${srcFrame.buffer.length}, decrypted length: ${finalBuffer.toBytes().length}, keyindex $keyIndex iv $iv');
683
+ logger.fine (
684
+ 'decodeFunction[CryptorError.kOk]: decryption success kind $kind, headerLength: $headerLength, timestamp: ${srcFrame.timestamp}, ssrc: ${srcFrame.ssrc}, data length: ${srcFrame.buffer.length}, decrypted length: ${finalBuffer.toBytes().length}, keyindex $keyIndex iv $iv');
686
685
} catch (e) {
687
686
if (lastError != CryptorError.kDecryptError) {
688
687
lastError = CryptorError.kDecryptError;
0 commit comments