Browse Source

webrtc: fix reading Opus stereo tracks with Chrome (#2043) (#2470)

pull/2471/head
Alessandro Ros 3 years ago committed by GitHub
parent
commit
412a48ac74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      internal/core/webrtc_manager.go
  2. 25
      internal/core/webrtc_publish_index.html
  3. 46
      internal/core/webrtc_read_index.html

2
internal/core/webrtc_manager.go

@ -88,7 +88,7 @@ var audioCodecs = []webrtc.RTPCodecParameters{
MimeType: webrtc.MimeTypeOpus, MimeType: webrtc.MimeTypeOpus,
ClockRate: 48000, ClockRate: 48000,
Channels: 2, Channels: 2,
SDPFmtpLine: "minptime=10;useinbandfec=1", SDPFmtpLine: "minptime=10;useinbandfec=1;stereo=1;sprop-stereo=1",
}, },
PayloadType: 111, PayloadType: 111,
}, },

25
internal/core/webrtc_publish_index.html

@ -276,7 +276,7 @@ const setAudioBitrate = (section, bitrate, voice) => {
}; };
const editAnswer = (answer, videoCodec, audioCodec, videoBitrate, audioBitrate, audioVoice) => { const editAnswer = (answer, videoCodec, audioCodec, videoBitrate, audioBitrate, audioVoice) => {
const sections = answer.split('m='); const sections = answer.sdp.split('m=');
for (let i = 0; i < sections.length; i++) { for (let i = 0; i < sections.length; i++) {
const section = sections[i]; const section = sections[i];
@ -287,7 +287,7 @@ const editAnswer = (answer, videoCodec, audioCodec, videoBitrate, audioBitrate,
} }
} }
return sections.join('m='); answer.sdp = sections.join('m=');
}; };
class Transmitter { class Transmitter {
@ -377,19 +377,16 @@ class Transmitter {
return; return;
} }
answer = new RTCSessionDescription({ editAnswer(
type: 'answer', answer,
sdp: editAnswer( document.getElementById('video_codec').value,
answer.sdp, document.getElementById('audio_codec').value,
document.getElementById('video_codec').value, document.getElementById('video_bitrate').value,
document.getElementById('audio_codec').value, document.getElementById('audio_bitrate').value,
document.getElementById('video_bitrate').value, document.getElementById('audio_voice').value,
document.getElementById('audio_bitrate').value, );
document.getElementById('audio_voice').value,
),
});
this.pc.setRemoteDescription(new RTCSessionDescription(answer)); this.pc.setRemoteDescription(answer);
if (this.queuedCandidates.length !== 0) { if (this.queuedCandidates.length !== 0) {
this.sendLocalCandidates(this.queuedCandidates); this.sendLocalCandidates(this.queuedCandidates);

46
internal/core/webrtc_read_index.html

@ -64,6 +64,48 @@ const parseOffer = (offer) => {
return ret; return ret;
}; };
const enableStereoOpus = (section) => {
let opusPayloadFormat = '';
let lines = section.split('\r\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('a=rtpmap:') && lines[i].toLowerCase().includes('opus/')) {
opusPayloadFormat = lines[i].slice('a=rtpmap:'.length).split(' ')[0];
break;
}
}
if (opusPayloadFormat === '') {
return section;
}
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('a=fmtp:' + opusPayloadFormat + ' ')) {
if (!lines[i].includes('stereo')) {
lines[i] += ';stereo=1';
}
if (!lines[i].includes('sprop-stereo')) {
lines[i] += ';sprop-stereo=1';
}
}
}
return lines.join('\r\n');
};
const editOffer = (offer) => {
const sections = offer.sdp.split('m=');
for (let i = 0; i < sections.length; i++) {
const section = sections[i];
if (section.startsWith('audio')) {
sections[i] = enableStereoOpus(section);
}
}
offer.sdp = sections.join('m=');
};
const generateSdpFragment = (offerData, candidates) => { const generateSdpFragment = (offerData, candidates) => {
const candidatesByMedia = {}; const candidatesByMedia = {};
for (const candidate of candidates) { for (const candidate of candidates) {
@ -139,6 +181,8 @@ class WHEPClient {
} }
onLocalOffer(offer) { onLocalOffer(offer) {
editOffer(offer);
this.offerData = parseOffer(offer.sdp); this.offerData = parseOffer(offer.sdp);
this.pc.setLocalDescription(offer); this.pc.setLocalDescription(offer);
@ -186,7 +230,7 @@ class WHEPClient {
return; return;
} }
this.pc.setRemoteDescription(new RTCSessionDescription(answer)); this.pc.setRemoteDescription(answer);
if (this.queuedCandidates.length !== 0) { if (this.queuedCandidates.length !== 0) {
this.sendLocalCandidates(this.queuedCandidates); this.sendLocalCandidates(this.queuedCandidates);

Loading…
Cancel
Save