Table of Contents |
---|
Overview
Supported platforms and browsers
...
Chrome
...
Firefox
...
Windows
...
+
...
+
...
Mac OS
...
+
...
+
Operation flowchart
1. The browser establishes a connection to the server via the Websocket protocol and sends the publish command.
2. The browser captures the screen and sends a WebRTC stream to the server.
3. The second browser establishes a connection also via Websokcet and sends the play command.
4. The second browser receives the WebRTC stream and plays the stream on the page.
Quick manual on testing
Capturing a video stream from the computer screen and preparing for publishing
1. For the test we use the demo server at demo.flashphoner.com and the Screen Sharing web application in the Chrome browser
https://demo.flashphoner.com/client2/examples/demo/streaming/screen-sharing/screen-sharing.html
2. Install the required extension by clicking the "Install Now" button
3. Click the "Start" button. The extension asks for permission to access the screen, and screen capturing starts, then the stream is prepared for publishing:
4. Make sure the stream is sent to the server and the system operates normally in chrome://webrtc-internals
5. Open Two Way Streaming in a new window, click Connect and specify the stream id, then click Play.
6. Playback diagrams in chrome://webrtc-internals
Call flow
Below is the call flow when using the Screen Sharing example
1. Checking if the extension install is required
Browser.isFirefox(), Browser.isChrome(); code
Code Block | ||||
---|---|---|---|---|
| ||||
if (Browser.isFirefox()) {
$("#installExtensionButton").show();
...
} else if (Browser.isChrome()) {
$('#mediaSourceForm').hide();
interval = setInterval(function() {
chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {
. if (response) {
$("#extension").hide();
clearInterval(interval);
onExtensionAvailable();
} else {
(inIframe()) ? $("#installFromMarket").show() : $("#installExtensionButton").show();
}
});
}, 500);
} else {
$("#notify").modal('show');
return false;
} |
2. Establishing a connection to the server.
Flashphoner.createSession(); code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
//session connected, start streaming
startStreaming(session);
}).on(SESSION_STATUS.DISCONNECTED, function(){
setStatus(SESSION_STATUS.DISCONNECTED);
onStopped();
}).on(SESSION_STATUS.FAILED, function(){
setStatus(SESSION_STATUS.FAILED);
onStopped();
}); |
...
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
//session connected, start streaming
startStreaming(session);
...
}); |
4. Publishing the stream.
stream.publish(); code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: localVideo,
constraints: constraints
}).on(STREAM_STATUS.PUBLISHING, function(publishStream){
...
}).on(STREAM_STATUS.UNPUBLISHED, function(){
...
}).on(STREAM_STATUS.FAILED, function(stream){
...
}).publish();
|
...
StreamStatusEvent, статус PUBLISHING code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: localVideo,
constraints: constraints
}).on(STREAM_STATUS.PUBLISHING, function(publishStream){
...
setStatus(STREAM_STATUS.PUBLISHING);
//play preview
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PLAYING, function(previewStream){
document.getElementById(previewStream.id()).addEventListener('resize', function(event){
resizeVideo(event.target);
});
//enable stop button
onStarted(publishStream, previewStream);
}).on(STREAM_STATUS.STOPPED, function(){
publishStream.stop();
}).on(STREAM_STATUS.FAILED, function(stream){
//preview failed, stop publishStream
if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
setStatus(STREAM_STATUS.FAILED, stream);
publishStream.stop();
}
}).play();
}).on(STREAM_STATUS.UNPUBLISHED, function(){
...
}).on(STREAM_STATUS.FAILED, function(stream){
...
}).publish();
|
6. Sending the audio-video stream via WebRTC
7. Stopping publishing the stream.
stream.stop(); code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: localVideo,
constraints: constraints
}).on(STREAM_STATUS.PUBLISHING, function(publishStream){
/*
* User can stop sharing screen capture using Chrome "stop" button.
* Catch onended video track event and stop publishing.
*/
document.getElementById(publishStream.id()).srcObject.getVideoTracks()[0].onended = function (e) {
publishStream.stop();
};
...
setStatus(STREAM_STATUS.PUBLISHING);
//play preview
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PLAYING, function(previewStream){
...
}).on(STREAM_STATUS.STOPPED, function(){
publishStream.stop();
}).on(STREAM_STATUS.FAILED, function(stream){
//preview failed, stop publishStream
if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
setStatus(STREAM_STATUS.FAILED, stream);
publishStream.stop();
}
}).play();
...
}).publish();
|
...
StreamStatusEvent, статус UNPUBLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: localVideo,
constraints: constraints
}).on(STREAM_STATUS.PUBLISHING, function(publishStream){
...
}).on(STREAM_STATUS.UNPUBLISHED, function(){
setStatus(STREAM_STATUS.UNPUBLISHED);
//enable start button
onStopped();
}).on(STREAM_STATUS.FAILED, function(stream){
...
}).publish();
|
To developer
...
Known issues
1. If the web applicaiton is inside an iframe element, publishing of the video stream may fail.
Symptoms: IceServer errors in the browser console.
Solution: put the app out of iframe to an individual page.
...
3. All streams captured from the screen stop if any one of them stops
Symptoms: while multiple streams are captured from the screen on one tab in the Chrome browser, if one stream is stopped, all streams stop.
Solution: cache tracks by the source of the video and stop them along with the last stream that uses that source, for example:
...
language | js |
---|---|
theme | RDark |
...
Include Page | ||||
---|---|---|---|---|
|