-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathrid-as-mid.html
126 lines (123 loc) · 4.52 KB
/
rid-as-mid.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<html>
<head>
<meta charset="utf-8">
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="https://webrtc.github.io/samples/src/js/third_party/graph.js"></script>
<script src="split-merge.js"></script>
<script src="test-assert.js"></script>
<script src="draw-graphs.js"></script>
<style>
video {
width: 320px;
}
.container {
display: inline-flex;
}
</style>
</head>
<body>
<div id="local">
<h2>Local Video</h2>
</div>
<div id="remotes">
<h2>Remote Videos</h2>
</div>
<p>
Use ?codec=<i>h264|vp8</i>&profile=<i>h264profile</i> in the URL to optionally filter the codec.<br>
The ?resolution=<i>1080p|720p|360p</i> parameter restricts the getUserMedia resolution.<br>
The ?scalabilityMode parameter allows controlling the (codec-specific) scalability modes from <a href="https://w3c.github.io/webrtc-svc/#dependencydiagrams*">WebRTC-SVC</a>.<br>
The ?remb parameter allows disabling transport-cc and falling back to REMB.
</p>
<script>
const SDPUtils = adapter.sdp;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
pc1.onicecandidate = (e) => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = (e) => pc1.addIceCandidate(e.candidate);
pc2.ontrack = (e) => {
if (searchParameters.has('codec') && ['vp8', 'h264', 'vp9', 'av1'].includes(searchParameters.get('codec'))) {
const codecs = RTCRtpReceiver.getCapabilities('video').codecs
.filter(c => {
return c.mimeType.toLowerCase() === 'video/' + searchParameters.get('codec') || c.mimeType.toLowerCase() === 'video/rtx';
})
.filter(c => {
return !searchParameters.has('profile') || (c.sdpFmtpLine || '').includes(searchParameters.get('profile')) || c.mimeType.toLowerCase() === 'video/rtx';
});
console.log('restricted codecs', codecs)
e.transceiver.setCodecPreferences(codecs);
}
show(e.streams[0], true);
}
const searchParameters = new URLSearchParams(window.location.search);
const scaleDown = (searchParameters.get('scaleDown') || '4/2/1').split('/');
const rids = [0, 1, 2];
const streamIds = {0: 'low', 1: 'mid', 2: 'hi'};
const video = {
'1080p': {width: 1920, height: 1080},
'720p': {width: 1280, height: 720},
'360p': {width: 640, height: 360},
}[searchParameters.get('resolution') || '720p'];
const scalabilityMode = searchParameters.get('scalabilityMode') || {
vp9: 'L1T2', // VP9 requires scalabilityMode to enable simulcast for backward compat reasons.
av1: 'L1T2', // AV1 requires scalabilityMode too?
}[searchParameters.get('codec')];
const remb = searchParameters.has('remb');
navigator.mediaDevices.getUserMedia({video})
.then((stream) => {
const transceiver = pc1.addTransceiver(stream.getVideoTracks()[0], {
streams: [stream],
sendEncodings: rids.map(rid => ({rid, scalabilityMode, scaleResolutionDownBy: scaleDown[rid]})),
});
if (searchParameters.has('gfd00') && ('getHeaderExtensionsToNegotiate' in RTCRtpTransceiver.prototype)) {
const ext = transceiver.getHeaderExtensionsToNegotiate();
ext.forEach(e => {
if (e.uri === 'http://www.webrtc.org/experiments/rtp-hdrext/generic-frame-descriptor-00') {
e.direction = 'sendrecv';
} else if (e.uri === 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension') {
e.direction = 'stopped';
}
});
transceiver.setHeaderExtensionsToNegotiate(ext);
}
show(stream, false);
return pc1.setLocalDescription();
})
.then(() => {
return pc2.setRemoteDescription({
type: 'offer',
sdp: splitLayers(pc1.localDescription.sdp, {
disableTransportCC: remb,
rids,
streamIds,
}),
});
})
.then(() => pc2.setLocalDescription())
.then(() => {
if (adapter.browserDetails.browser === 'firefox') {
ssrc2track = [];
SDPUtils.matchPrefix(pc1.localDescription.sdp, 'a=ssrc-group:')
.map(line => SDPUtils.parseSsrcGroup(line))
.forEach(group => {
if (group.semantics != 'FID') return;
ssrc2track.push(group.ssrcs[0]);
});
}
return pc1.setRemoteDescription({
type: 'answer',
sdp: mergeLayers(pc2.localDescription.sdp, pc1.localDescription.sdp, {
disableTransportCC: remb,
rids,
streamIds,
}),
});
})
.then(() => {
window.setInterval(() => {
draw(pc1, pc2);
}, 2000);
})
.catch(e => console.error(e));
</script>
</body>
</html>