Skip to content

Commit 340ee2f

Browse files
committed
fix E2EE for FireFox.
1 parent ceb2849 commit 340ee2f

File tree

2 files changed

+53
-51
lines changed

2 files changed

+53
-51
lines changed

lib/src/e2ee.worker/e2ee.cryptor.dart

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,11 @@ enum CryptorError {
120120

121121
class FrameInfo {
122122
FrameInfo({
123-
required this.mimeType,
124123
required this.ssrc,
125124
required this.timestamp,
126125
required this.buffer,
127126
required this.frameType,
128127
});
129-
String? mimeType;
130128
String frameType;
131129
int ssrc;
132130
int timestamp;
@@ -144,7 +142,6 @@ class FrameCryptor {
144142
String? participantIdentity;
145143
String? trackId;
146144
String? codec;
147-
String? mineType;
148145
ParticipantKeyHandler keyHandler;
149146
KeyOptions get keyOptions => keyHandler.keyOptions;
150147
late String kind;
@@ -282,8 +279,7 @@ class FrameCryptor {
282279
data = obj.data.toDart.asUint8List();
283280
if (obj.hasProperty('type'.toJS).toDart) {
284281
frameType = obj.type;
285-
logger.finer(
286-
'frameType: $frameType, mineTye ${obj.getMetadata().mimeType}');
282+
logger.finer('frameType: $frameType');
287283
}
288284
}
289285

@@ -318,33 +314,40 @@ class FrameCryptor {
318314
}
319315

320316
FrameInfo readFrameInfo(JSObject frameObj) {
321-
Uint8List buffer;
317+
var buffer = Uint8List(0);
322318
var synchronizationSource = 0;
323319
var timestamp = 0;
324320
var frameType = '';
325321
if (frameObj is web.RTCEncodedVideoFrame) {
326322
buffer = frameObj.data.toDart.asUint8List();
327323
if (frameObj.hasProperty('type'.toJS).toDart) {
328324
frameType = frameObj.type;
329-
logger.finer(
330-
'frameType: $frameType, mineTye ${frameObj.getMetadata().mimeType}');
325+
logger.finer('frameType: $frameType');
331326
}
332327
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+
}
335334
} else if (frameObj is web.RTCEncodedAudioFrame) {
336335
buffer = frameObj.data.toDart.asUint8List();
337336
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+
}
340344
frameType = 'audio';
341345
} else {
342346
throw Exception(
343347
'encodeFunction: frame is not a RTCEncodedVideoFrame or RTCEncodedAudioFrame');
344348
}
345349

346350
return FrameInfo(
347-
mimeType: mineType,
348351
ssrc: synchronizationSource,
349352
timestamp: timestamp,
350353
buffer: buffer,
@@ -366,43 +369,44 @@ class FrameCryptor {
366369
JSObject frameObj,
367370
web.TransformStreamDefaultController controller,
368371
) 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);
380383
return;
381384
}
382-
controller.enqueue(frameObj);
383-
return;
384-
}
385385

386-
var secretKey = keyHandler.getKeySet(currentKeyIndex)?.encryptionKey;
387-
var keyIndex = currentKeyIndex;
386+
var srcFrame = readFrameInfo(frameObj);
388387

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;
401408
}
402-
return;
403-
}
404409

405-
try {
406410
var headerLength =
407411
kind == 'video' ? getUnencryptedBytes(frameObj, codec) : 1;
408412

@@ -476,11 +480,9 @@ class FrameCryptor {
476480
web.TransformStreamDefaultController controller,
477481
) async {
478482
var srcFrame = readFrameInfo(frameObj);
479-
mineType ??= srcFrame.mimeType;
480483
var ratchetCount = 0;
481484

482-
logger.finer(
483-
'decodeFunction: frame ${srcFrame.buffer.length} mineType $mineType');
485+
logger.fine('decodeFunction: frame ${srcFrame.buffer.length}');
484486

485487
ByteBuffer? decrypted;
486488
KeySet? initialKeySet;
@@ -681,8 +683,8 @@ class FrameCryptor {
681683
});
682684
}
683685

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');
686+
logger.fine(
687+
'decrypt kind $kind, headerLength: $headerLength, timestamp: ${srcFrame.timestamp}, ssrc: ${srcFrame.ssrc}, data length: ${srcFrame.buffer.length}, decrypted length: ${finalBuffer.toBytes().length}, keyindex $keyIndex iv $iv');
686688
} catch (e) {
687689
if (lastError != CryptorError.kDecryptError) {
688690
lastError = CryptorError.kDecryptError;

lib/src/e2ee.worker/e2ee.worker.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void main() async {
6868
var kind = options.getProperty('kind'.toJS) as JSString;
6969
var participantId = options.getProperty('participantId'.toJS) as JSString;
7070
var trackId = options.getProperty('trackId'.toJS) as JSString;
71-
var codec = options.getProperty('codec'.toJS) as JSString;
71+
var codec = options.getProperty('codec'.toJS) as JSString?;
7272
var msgType = options.getProperty('msgType'.toJS) as JSString;
7373
var keyProviderId = options.getProperty('keyProviderId'.toJS) as JSString;
7474

@@ -88,7 +88,7 @@ void main() async {
8888
writable: transformer.writable,
8989
trackId: trackId.toDart,
9090
kind: kind.toDart,
91-
codec: codec.toDart);
91+
codec: codec?.toDart);
9292
}.toJS;
9393
}
9494

0 commit comments

Comments
 (0)