diff --git a/lib/src/participant/local.dart b/lib/src/participant/local.dart index f1490ae5..ea409058 100644 --- a/lib/src/participant/local.dart +++ b/lib/src/participant/local.dart @@ -193,7 +193,7 @@ class LocalParticipant extends Participant { 'Compute encodings with resolution: ${dimensions}, options: ${publishOptions}'); // Video encodings and simulcasts - final encodings = Utils.computeVideoEncodings( + var encodings = Utils.computeVideoEncodings( isScreenShare: track.source == TrackSource.screenShareVideo, dimensions: dimensions, options: publishOptions, @@ -202,6 +202,21 @@ class LocalParticipant extends Participant { logger.fine('Using encodings: ${encodings?.map((e) => e.toMap())}'); + var simulcastCodecs = [ + lk_rtc.SimulcastCodec( + codec: publishOptions.videoCodec, + cid: track.getCid(), + ), + ]; + + if (publishOptions.backupCodec != null && + publishOptions.backupCodec!.codec != publishOptions.videoCodec) { + simulcastCodecs.add(lk_rtc.SimulcastCodec( + codec: publishOptions.backupCodec!.codec.toLowerCase(), + cid: '', + )); + } + final layers = Utils.computeVideoLayers( dimensions, encodings, @@ -209,28 +224,6 @@ class LocalParticipant extends Participant { ); logger.fine('Video layers: ${layers.map((e) => e)}'); - var simulcastCodecs = []; - - if (publishOptions.backupCodec != null && - publishOptions.backupCodec!.codec != publishOptions.videoCodec) { - simulcastCodecs = [ - lk_rtc.SimulcastCodec( - codec: publishOptions.videoCodec, - cid: track.getCid(), - ), - lk_rtc.SimulcastCodec( - codec: publishOptions.backupCodec!.codec.toLowerCase(), - cid: '', - ), - ]; - } else { - simulcastCodecs = [ - lk_rtc.SimulcastCodec( - codec: publishOptions.videoCodec, - cid: track.getCid(), - ), - ]; - } final trackInfo = await room.engine.addTrack( cid: track.getCid(), @@ -250,6 +243,30 @@ class LocalParticipant extends Participant { await track.start(); + String? primaryCodecMime; + for (var codec in trackInfo.codecs) { + primaryCodecMime ??= codec.mimeType; + } + + if (primaryCodecMime != null) { + final updatedCodec = mimeTypeToVideoCodecString(primaryCodecMime); + if (updatedCodec != publishOptions.videoCodec) { + logger.fine( + 'requested a different codec than specified by serverRequested: ${publishOptions.videoCodec}, server: ${updatedCodec}', + ); + publishOptions = publishOptions.copyWith( + videoCodec: updatedCodec, + ); + // recompute encodings since bitrates/etc could have changed + encodings = Utils.computeVideoEncodings( + isScreenShare: track.source == TrackSource.screenShareVideo, + dimensions: dimensions, + options: publishOptions, + codec: publishOptions.videoCodec, + ); + } + } + final transceiverInit = rtc.RTCRtpTransceiverInit( direction: rtc.TransceiverDirection.SendOnly, sendEncodings: encodings, diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 7c2cc255..cb72ba62 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -620,3 +620,14 @@ class ScalabilityMode { return 'L${spatial}T${temporal}${suffix ?? ''}'; } } + +String mimeTypeToVideoCodecString(String mimeType) { + if (!mimeType.contains('/') && mimeType.split('/').length != 2) { + throw Exception('Invalid mimeType: $mimeType'); + } + final codec = mimeType.split('/')[1].toLowerCase(); + if (!videoCodecs.contains(codec)) { + throw Exception('Video codec not supported: $codec'); + } + return codec; +}