Skip to content

Commit

Permalink
Fixed Canary screen issue. Recording Scalable-Broadcast. Added Codecs…
Browse files Browse the repository at this point in the history
…Handler.js
  • Loading branch information
muaz-khan committed Feb 5, 2016
1 parent 4ab29c4 commit d79b5ff
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 40 deletions.
44 changes: 44 additions & 0 deletions README.md
Expand Up @@ -1186,6 +1186,50 @@ var connection = new RTCMultiConnection(roomId, {
});
```

## Wanna use H264 for video?

```html
<script src="/dev/CodecsHandler.js"></script>
<script>
// in your HTML file
connection.processSdp = function(sdp) {
// modify sdp to remove vp8/vp9
sdp = CodecsHandler.removeVPX(sdp);
return sdp;
};
</script>
```

## Disable Video NACK

```html
<script src="/dev/CodecsHandler.js"></script>
<script>
// in your HTML file
connection.processSdp = function(sdp) {
// Disable NACK to test IDR recovery
sdp = CodecsHandler.disableNACK(sdp);
return sdp;
};
</script>
```

## Prioritize Codecs

```html
<script src="/dev/CodecsHandler.js"></script>
<script>
// in your HTML file
if(connection.DetectRTC.browser.name === 'Firefox') {
connection.getAllParticipants().forEach(function(p) {
var peer = connection.peers[p].peer;
CodecsHandler.prioritize('audio/opus', peer);
});
}
</script>
```

## RTCMultiConnection v2.2.2 Demos

| Experiment Name | Demo | Source Code |
Expand Down
8 changes: 3 additions & 5 deletions RTCMultiConnection.js
@@ -1,4 +1,4 @@
// Last time updated: 2016-02-04 11:01:06 AM UTC
// Last time updated: 2016-02-05 9:33:13 AM UTC

// ______________________________
// RTCMultiConnection-v3.0 (Beta)
Expand Down Expand Up @@ -5035,8 +5035,7 @@
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down Expand Up @@ -5148,8 +5147,7 @@
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down
4 changes: 2 additions & 2 deletions RTCMultiConnection.min.js

Large diffs are not rendered by default.

97 changes: 78 additions & 19 deletions demos/Scalable-Broadcast.html
Expand Up @@ -15,7 +15,8 @@
<style>
video {
object-fit: fill;
width: 30%;
width: 100%;
max-width: 100%;
}
button,
input,
Expand Down Expand Up @@ -75,10 +76,6 @@
input, input:focus, input:active {
background: white;
}

video {
width: 30%;
}
</style>
</head>

Expand All @@ -103,17 +100,10 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
<section class="experiment">
<div class="make-center">
<input type="text" id="broadcast-id" placeholder="broadcast-id" value="room-xyz">
<select id="broadcast-options">
<option>Audio+Video</option>
<option>Audio+Screen</option>
<option>Audio</option>
<option>Video</option>
<option>Screen</option>
</select>
<button id="open-or-join">Open or Join Broadcast</button>
</div>

<div id="videos-container"></div>
<video id="video-preview" controls loop></video>
</section>

<blockquote>
Expand All @@ -128,6 +118,9 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
<!-- <script src="/RTCMultiConnection.min.js"></script> -->
<script src="https://cdn.webrtc-experiment.com/rmc3.min.js"></script>

<script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
<script src="https://cdn.webrtc-experiment.com/ConcatenateBlobs.js"></script>

<script>
var connection = new RTCMultiConnection(null, {
useDefaultDevices: true // if we don't need to force selection of specific devices
Expand Down Expand Up @@ -190,11 +183,26 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
document.getElementById('open-or-join').disabled = false;
};

connection.videosContainer = document.getElementById('videos-container');
var videoPreview = document.getElementById('video-preview');

connection.onstream = function(event) {
connection.videosContainer.appendChild(event.mediaElement);
if(event.mediaElement) {
event.mediaElement.pause();
event.mediaElement.src = null;
delete event.mediaElement;
}

connection.isUpperNodeLeft = false;
videoPreview.src = URL.createObjectURL(event.stream);
videoPreview.play();

if(event.type === 'local') {
videoPreview.muted = true;
}

if (connection.isInitiator == false && event.type === 'remote') {
repeatedlyRecordStream(event.stream);

if (connection.isInitiator == false) {
// he is merely relaying the media
connection.dontCaptureUserMedia = true;
connection.attachStreams = [event.stream];
Expand All @@ -219,9 +227,8 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
this.disabled = true;

connection.session = {
video: document.getElementById('broadcast-options').value.indexOf('Video') !== -1,
screen: document.getElementById('broadcast-options').value.indexOf('Screen') !== -1,
audio: document.getElementById('broadcast-options').value.indexOf('Audio') !== -1,
audio: true,
video: true,
oneway: true
};

Expand All @@ -241,6 +248,58 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
});
};

connection.onstreamended = /*videoPreview.onended = */function(event) {
connection.isUpperNodeLeft = true;

if(allRecordedBlobs.length) {
ConcatenateBlobs(allRecordedBlobs, 'video/webm', function(resultingBlob) {
videoPreview.src = URL.createObjectURL(resultingBlob);
videoPreview.play();

allRecordedBlobs = [];
});
}
else if(connection.currentRecorder) {
var recorder = connection.currentRecorder;
connection.currentRecorder = null;
recorder.stopRecording(function() {
videoPreview.src = URL.createObjectURL(recorder.blob);
videoPreview.play();
});
}

if(connection.currentRecorder) {
connection.currentRecorder.stopRecording();
connection.currentRecorder = null;
}
};

var allRecordedBlobs = [];

function repeatedlyRecordStream(stream) {
connection.currentRecorder = RecordRTC(stream, {
type: 'video'
});

connection.currentRecorder.startRecording();

setTimeout(function() {
if(connection.isUpperNodeLeft) {
return;
}

connection.currentRecorder.stopRecording(function() {
allRecordedBlobs.push(connection.currentRecorder.blob);

if(connection.isUpperNodeLeft) {
return;
}

connection.currentRecorder = null;
repeatedlyRecordStream(stream);
});
}, 30 * 1000);
};

</script>

Expand Down
62 changes: 62 additions & 0 deletions dev/CodecsHandler.js
@@ -0,0 +1,62 @@
// CodecsHandler.js

var CodecsHandler = (function() {
// "removeVPX" method is taken from github/mozilla/webrtc-landing
function removeVPX(sdp) {
if (!sdp || typeof sdp !== 'string') {
throw 'Invalid arguments.';
}

sdp = sdp.replace('a=rtpmap:120 VP8/90000\r\n', '');
sdp = sdp.replace('a=rtpmap:120 VP9/90000\r\n', '');

sdp = sdp.replace(/m=video ([0-9]+) RTP\/SAVPF ([0-9 ]*) 120/g, 'm=video $1 RTP\/SAVPF $2');
sdp = sdp.replace(/m=video ([0-9]+) RTP\/SAVPF 120([0-9 ]*)/g, 'm=video $1 RTP\/SAVPF$2');

sdp = sdp.replace('a=rtcp-fb:120 nack\r\n', '');
sdp = sdp.replace('a=rtcp-fb:120 nack pli\r\n', '');
sdp = sdp.replace('a=rtcp-fb:120 ccm fir\r\n', '');

return sdp;
}

function disableNACK(sdp) {
if (!sdp || typeof sdp !== 'string') {
throw 'Invalid arguments.';
}

sdp = sdp.replace('a=rtcp-fb:126 nack\r\n', '');
sdp = sdp.replace('a=rtcp-fb:126 nack pli\r\n', 'a=rtcp-fb:126 pli\r\n');
sdp = sdp.replace('a=rtcp-fb:97 nack\r\n', '');
sdp = sdp.replace('a=rtcp-fb:97 nack pli\r\n', 'a=rtcp-fb:97 pli\r\n');

return sdp;
}

function prioritize(codecMimeType, peer) {
if (!peer || !peer.getSenders || !peer.getSenders().length) {
return;
}

if (!codecMimeType || typeof codecMimeType !== 'string') {
throw 'Invalid arguments.';
}

peer.getSenders().forEach(function(sender) {
var params = sender.getParameters();
for (var i = 0; i < params.codecs.length; i++) {
if (params.codecs[i].mimeType == codecMimeType) {
params.codecs.unshift(params.codecs.splice(i, 1));
break;
}
}
sender.setParameters(params);
});
}

return {
removeVPX: removeVPX,
disableNACK: disableNACK,
prioritize: prioritize
};
})();
3 changes: 1 addition & 2 deletions dev/Screen-Capturing.js
Expand Up @@ -180,8 +180,7 @@ function getScreenConstraints(callback) {
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
};
Expand Down
6 changes: 2 additions & 4 deletions dev/getScreenId.js
Expand Up @@ -71,8 +71,7 @@ getScreenId(function (error, sourceId, screen_constraints) {
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down Expand Up @@ -184,8 +183,7 @@ getScreenId(function (error, sourceId, screen_constraints) {
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down
2 changes: 1 addition & 1 deletion dist/rmc3.fbr.min.js

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions dist/rmc3.js
@@ -1,4 +1,4 @@
// Last time updated: 2016-02-04 11:01:06 AM UTC
// Last time updated: 2016-02-05 9:33:13 AM UTC

// ______________________________
// RTCMultiConnection-v3.0 (Beta)
Expand Down Expand Up @@ -5035,8 +5035,7 @@
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down Expand Up @@ -5148,8 +5147,7 @@
minFrameRate: 30,
maxFrameRate: 128,
minAspectRatio: 1.77, // 2.39
googLeakyBucket: true,
googTemporalLayeredScreencast: true
googLeakyBucket: true
},
optional: []
}
Expand Down
4 changes: 2 additions & 2 deletions dist/rmc3.min.js

Large diffs are not rendered by default.

0 comments on commit d79b5ff

Please sign in to comment.