Skip to content

Commit

Permalink
move codec selection to the receiver for more samples
Browse files Browse the repository at this point in the history
follow-up to #1640 which got copy-pasted quite a bit.
  • Loading branch information
fippo committed Nov 25, 2023
1 parent 9b9b4d6 commit 00bdcc3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 70 deletions.
32 changes: 15 additions & 17 deletions src/content/extensions/svc/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ async function start() {
alert(`getUserMedia() error: ${e.name}`);
}
if (supportsSetCodecPreferences) {
const {codecs} = RTCRtpSender.getCapabilities('video');
const {codecs} = RTCRtpReceiver.getCapabilities('video');
codecs.forEach(codec => {
if (['video/red', 'video/ulpfec', 'video/rtx'].includes(codec.mimeType)) {
if (['video/red', 'video/ulpfec', 'video/rtx', 'video/flexfec-03'].includes(codec.mimeType)) {
return;
}
const option = document.createElement('option');
Expand Down Expand Up @@ -215,21 +215,6 @@ async function call() {
}
});
console.log('Added local stream to pc1');
if (supportsSetCodecPreferences) {
const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
if (preferredCodec.value !== '') {
const [mimeType, sdpFmtpLine] = preferredCodec.value.split(' ');
const {codecs} = RTCRtpSender.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === mimeType && c.sdpFmtpLine === sdpFmtpLine);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
console.log(codecs);
const transceiver = pc1.getTransceivers().find(t => t.sender && t.sender.track === localStream.getVideoTracks()[0]);
transceiver.setCodecPreferences(codecs);
console.log('Preferred video codec', selectedCodec);
}
}
codecPreferences.disabled = true;
scalabilityMode.disabled = true;

Expand Down Expand Up @@ -293,6 +278,19 @@ function gotRemoteStream(e) {
remoteVideo.srcObject = e.streams[0];
console.log('pc2 received remote stream');
}
if (supportsSetCodecPreferences) {
const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
if (preferredCodec.value !== '') {
const [mimeType, sdpFmtpLine] = preferredCodec.value.split(' ');
const {codecs} = RTCRtpReceiver.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === mimeType && c.sdpFmtpLine === sdpFmtpLine);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
e.transceiver.setCodecPreferences(codecs);
console.log('Preferred video codec', selectedCodec);
}
}
}

async function onCreateAnswerSuccess(desc) {
Expand Down
51 changes: 26 additions & 25 deletions src/content/insertable-streams/endtoend-encryption/js/videopipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
//
// The usage of this abstraction:
// var pipe = new VideoPipe(mediastream, handlerFunction);
// handlerFunction = function(mediastream) {
// handlerFunction = function(MediaStreamTrackEvent) {
// do_something
// }
// pipe.close();
//
// The VideoPipe will set up 2 PeerConnections, connect them to each
// other, and call HandlerFunction when the stream is available in the
// second PeerConnection.
// other, and call HandlerFunction when the stream's track is available
// in the second PeerConnection.
//
'use strict';

Expand All @@ -36,36 +36,37 @@ function VideoPipe(stream, forceSend, forceReceive, handler) {
this.pc2 = new RTCPeerConnection({
encodedInsertableStreams: forceReceive,
});
this.pc2.ontrack = handler;
stream.getTracks().forEach((track) => this.pc1.addTrack(track, stream));

if (preferredAudioCodecMimeType && 'setCodecPreferences' in window.RTCRtpTransceiver.prototype) {
const {codecs} = RTCRtpSender.getCapabilities('audio');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredAudioCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
const transceiver = this.pc1.getTransceivers()
.find(t => t.sender && t.sender.track === stream.getAudioTracks()[0]);
transceiver.setCodecPreferences(codecs);
}
if (preferredVideoCodecMimeType && 'setCodecPreferences' in window.RTCRtpTransceiver.prototype) {
const {codecs} = RTCRtpSender.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredVideoCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
const transceiver = this.pc1.getTransceivers()
.find(t => t.sender && t.sender.track === stream.getVideoTracks()[0]);
transceiver.setCodecPreferences(codecs);
if ('setCodecPreferences' in window.RTCRtpTransceiver.prototype) {
this.pc2.ontrack = (e) => {
if (e.track.kind === 'audio' && preferredAudioCodecMimeType ) {
const {codecs} = RTCRtpReceiver.getCapabilities('audio');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredAudioCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
e.transceiver.setCodecPreferences(codecs);
} else if (e.track.kind === 'video' && preferredVideoCodecMimeType) {
const {codecs} = RTCRtpReceiver.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredVideoCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
e.transceiver.setCodecPreferences(codecs);
}
handler(e);
};
} else {
this.pc2.ontrack = handler;
}
stream.getTracks().forEach((track) => this.pc1.addTrack(track, stream));
}

VideoPipe.prototype.negotiate = async function() {
this.pc1.onicecandidate = e => this.pc2.addIceCandidate(e.candidate);
this.pc2.onicecandidate = e => this.pc1.addIceCandidate(e.candidate);

const offer = await this.pc1.createOffer();
// Disable video/red to allow for easier inspection in Wireshark.
await this.pc2.setRemoteDescription({type: 'offer', sdp: offer.sdp.replace('red/90000', 'green/90000')});
await this.pc1.setLocalDescription(offer);

Expand Down
35 changes: 17 additions & 18 deletions src/content/peerconnection/audio/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const supportsSetCodecPreferences = window.RTCRtpTransceiver &&
if (supportsSetCodecPreferences) {
codecSelector.style.display = 'none';

const {codecs} = RTCRtpSender.getCapabilities('audio');
const {codecs} = RTCRtpReceiver.getCapabilities('audio');
codecs.forEach(codec => {
if (['audio/CN', 'audio/telephone-event'].includes(codec.mimeType)) {
return;
Expand Down Expand Up @@ -98,23 +98,6 @@ function gotStream(stream) {
localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));
console.log('Adding Local Stream to peer connection');

if (supportsSetCodecPreferences) {
const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
if (preferredCodec.value !== '') {
const [mimeType, clockRate, sdpFmtpLine] = preferredCodec.value.split(' ');
const {codecs} = RTCRtpSender.getCapabilities('audio');
console.log(mimeType, clockRate, sdpFmtpLine);
console.log(JSON.stringify(codecs, null, ' '));
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === mimeType && c.clockRate === parseInt(clockRate, 10) && c.sdpFmtpLine === sdpFmtpLine);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
const transceiver = pc1.getTransceivers().find(t => t.sender && t.sender.track === localStream.getAudioTracks()[0]);
transceiver.setCodecPreferences(codecs);
console.log('Preferred video codec', selectedCodec);
}
}

pc1.createOffer(offerOptions)
.then(gotDescription1, onCreateSessionDescriptionError);

Expand Down Expand Up @@ -207,6 +190,22 @@ function hangup() {
}

function gotRemoteStream(e) {
if (supportsSetCodecPreferences) {
const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
if (preferredCodec.value !== '') {
const [mimeType, clockRate, sdpFmtpLine] = preferredCodec.value.split(' ');
const {codecs} = RTCRtpReceiver.getCapabilities('audio');
console.log(mimeType, clockRate, sdpFmtpLine);
console.log(JSON.stringify(codecs, null, ' '));
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === mimeType && c.clockRate === parseInt(clockRate, 10) && c.sdpFmtpLine === sdpFmtpLine);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
e.transceiver.setCodecPreferences(codecs);
console.log('Preferred video codec', selectedCodec);
}
}

if (audio2.srcObject !== e.streams[0]) {
audio2.srcObject = e.streams[0];
console.log('Received remote stream');
Expand Down
24 changes: 14 additions & 10 deletions src/content/peerconnection/negotiate-timing/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ async function call() {
pc1.oniceconnectionstatechange = e => onIceStateChange(pc1, e);
pc2.oniceconnectionstatechange = e => onIceStateChange(pc2, e);
pc2.addEventListener('track', gotRemoteStream, {once: true});
if (preferredVideoCodecMimeType) {
pc2.ontrack = (e) => {
if (e.track.kind === 'video') {
const {codecs} = RTCRtpReceiver.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredVideoCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
e.transceiver.setCodecPreferences(codecs);
}
};
}

localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));
console.log('Added local stream to pc1');
Expand All @@ -156,7 +168,7 @@ async function onIceCandidate(pc, event) {
if (event.candidate) {
console.log(`${getName(pc)} emitted ICE candidate for index ${event.candidate.sdpMLineIndex}:\n${event.candidate.candidate}`);
} else {
console.log(`$getName(pc)} ICE NULL candidate`);
console.log(`${getName(pc)} ICE NULL candidate`);
}
await getOtherPc(pc).addIceCandidate(event.candidate);
console.log(`${getName(pc)} addIceCandidate success`);
Expand All @@ -175,15 +187,7 @@ function adjustTransceiverCounts(pc, videoCount) {
if (currentVideoCount < videoCount) {
console.log('Adding ' + (videoCount - currentVideoCount) + ' transceivers');
for (let i = currentVideoCount; i < videoCount; ++i) {
const transceiver = pc.addTransceiver('video');
if (preferredVideoCodecMimeType) {
const {codecs} = RTCRtpSender.getCapabilities('video');
const selectedCodecIndex = codecs.findIndex(c => c.mimeType === preferredVideoCodecMimeType);
const selectedCodec = codecs[selectedCodecIndex];
codecs.splice(selectedCodecIndex, 1);
codecs.unshift(selectedCodec);
transceiver.setCodecPreferences(codecs);
}
pc.addTransceiver('video');
}
} else if (currentVideoCount > videoCount) {
console.log('Stopping ' + (currentVideoCount - videoCount) + ' transceivers');
Expand Down

0 comments on commit 00bdcc3

Please sign in to comment.