...
Code Block |
---|
language | xml |
---|
theme | RDark |
---|
title | Code |
---|
collapse | true |
---|
|
<!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 |
---|
|
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 |
---|
|
function removeVideoTrackEndedListener(localVideo) {
var videoTrack = extractVideoTrack(localVideo);
if(videoTrack) {
videoTrack.onended = null;
}
} |
3. Add function to extract videotrack
Code Block |
---|
|
function extractVideoTrack(localVideo) {
return localVideo.firstChild.srcObject.getVideoTracks()[0];
} |
4. Register event handler when publishing a stream
Code Block |
---|
|
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 |
---|
|
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 |
---|
|
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.
...