Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagexml
themeRDark
titleCode
collapsetrue
<!DOCTYPE html>
<html>
    <head>
        <title>WebRTC Delight</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
		   <script type="text/javascript" src="../../../../flashphoner.js"></script>
		   <script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script>
		   <script type="text/javascript" src="../../dependencies/js/utils.js"></script>
		   <script src="dl8-66b250447635476d123a44a391c80b09887e831e.js" async></script>
        <meta name="dl8-custom-format" content='{"name": "STEREO_TERPON","base":"STEREO_MESH","params":{"uri": "03198702.json"}}'>
    </head>
    <body>        
        <div style="width: 50%;">
            <dl8-live-video id="remoteVideo" format="STEREO_TERPON" muted="true">
                <source>
            </dl8-live-video>
        </div>
		<input class="form-control" type="text" id="streamName" placeholder="Stream Name"> 
		<button id="publishBtn" type="button" class="btn btn-default" disabled>Publish</button>
		<button id="unpublishBtn" type="button" class="btn btn-default" disabled>UnPublish</button>
        <script>
			Flashphoner.init({flashMediaProviderSwfLocation: '../../../../media-provider.swf'});
			var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
			var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
			var STREAM_STATUS_INFO = Flashphoner.constants.STREAM_STATUS_INFO;
			var publishBtn = $('#publishBtn').get(0);
			var dl8video = null;
			var url = setURL();
            document.addEventListener('x-dl8-evt-ready', function () {
				dl8video = $('#remoteVideo').get(0);
				$('#publishBtn').prop('disabled', false).click(function() {
					publishStream();
				});
            });
			var mockLocalDisplay = $('<div></div>');
			var mockLocalVideo = $('<video></video>',{id:'mock-LOCAL_CACHED_VIDEO'});
			mockLocalDisplay.append(mockLocalVideo);
			function publishStream() {
			$('#publishBtn').prop('disabled', true);
			$('#unpublishBtn').prop('disabled', false);
			var video = dl8video.contentElement;
			Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
			var session = Flashphoner.getSessions()[0];
			session.createStream({
				name: $('#streamName').val(),
				display: mockLocalDisplay.get(0)
			}).on(STREAM_STATUS.PUBLISHING, function (stream) {
				var srcObject = mockLocalVideo.get(0).srcObject;
				video.srcObject = srcObject;
				dl8video.start();
				mockLocalVideo.get(0).pause();
				mockLocalVideo.get(0).srcObject = null;
				$('#unpublishBtn').prop('disabled', false).click(function() {
					stream.stop();
					$('#publishBtn').prop('disabled', false);
					$('#unpublishBtn').prop('disabled', true);
					dl8video.exit();
				});
			}).publish();
			})	
			}
        </script>
    </body>
</html>

If Chrome browser sends empty video due to web camera conflict

Some Chrome versions does not return an error if web camera is busy, but publish a stream with empty video (black screen). In this case, stream publishing can be stopped by two ways: using JavaScript and HTML5 on client, or using server settings.

Stopping a stream with empty video on client side

Videotrack that Chrome browsers creates for busy web camera, stops after no more than one second publishing, then stream is send without a videotrack. In this case videotrack state (readyState variable) changes to ended, and corresponding  onended event is generated that can be catched by web application. To use this event:

1. Add to web application script the registartion function for onended event handler, in which stream pub;ishing is stopped with stream.stop()

Code Block
languagejs
themeRDark
function addVideoTrackEndedListener(localVideo, stream) {
    var videoTrack = extractVideoTrack(localVideo);
    if (videoTrack && videoTrack.readyState == 'ended') {
        console.error("Video source error. Disconnect...");
        stream.stop();
    } else if (videoTrack) {
        videoTrack.onended = function (event) {
            console.error("Video source error. Disconnect...");
            stream.stop();
        };
    }
}

2. Add function to remove event handler when stream is stopped

Code Block
languagejs
themeRDark
function removeVideoTrackEndedListener(localVideo) {
    var videoTrack = extractVideoTrack(localVideo);
    if(videoTrack) {
        videoTrack.onended = null;
    }
}

3. Add function to extract videotrack

Code Block
languagejs
themeRDark
function extractVideoTrack(localVideo) {
    return localVideo.firstChild.srcObject.getVideoTracks()[0];
}

4. Register event handler when publishing a stream

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        ...
    }).on(STREAM_STATUS.PUBLISHING, function (stream) {
        addVideoTrackEndedListener(localVideo, stream);
        setStatus("#publishStatus", STREAM_STATUS.PUBLISHING);
        onPublishing(stream);
        ...
    }).publish();

5. Remove event handler when stopping a stream

Code Block
languagejs
themeRDark
function onPublishing(stream) {
    $("#publishBtn").text("Stop").off('click').click(function () {
        $(this).prop('disabled', true);
        removeVideoTrackEndedListener(localVideo);
        stream.stop();
    }).prop('disabled', false);
    $("#publishInfo").text("");
}

Videotrack activity checking on server side

Videotrack activity checking for streams published on server is enabled with the following parameters in flashphoner.properties file

Code Block
themeRDark
rtp_activity_detecting=true,60
rtp_activity_video=true

In this case, if there is no video in stream, its publishing will be stopped after 60 seconds.

Known issues

1. If the web app is inside an iframe element, publishing of the video stream may fail.

...