...
This example may be used to embed player to the web page for live streams from web and IP cameras playback. These technologies are supported^
- WebRTC
- MSE
- WSPlayer (Websocket + HTML5 Canvas)
Embedding page interface:
Code of the example
Source code of the example is on server by this path:
/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/embed_player
player.css - CSS style fileplayer.html - player pageplayer.js - script for player to worksample.css - CSS style file for embedding interface pagesample.html - embedding embedding interface pagesample.js - script to form embedding code
The example can be tested on this URL:
https://host:8888/client2/examples/demo/streaming/embed_player/sample.html
where host is your WCS server address
Analyzing the code
To analyze code get player.js file version with hash ecbadc3 24a69e1 that can be found here and is avalable to download in build 2.0.212225.
1. API initializing.
Flashphoner.init() code
| Code Block | ||||
|---|---|---|---|---|
| ||||
Flashphoner.init({ preferredMediaProviders: mediaProviders && mediaProviders !== "" ? receiverLocation: '../../dependencies/websocket-player/WSReceiver2.js', decoderLocation: '../../dependencies/websocket-player/video-worker2.js', preferredMediaProviders: mediaProviders && mediaProviders !== "" ? mediaProviders.split(','): [] }); |
2. Connection to the server
Flashphoner.createSession() code
These parameters are passed to createSession() method:
...
mediaProviders.split(','): [] }); |
2. Connection to the server
Flashphoner.createSession() code
The following parameters are passed to createSession() method:
urlServer- WCS server URLmediaOptions- parameters to connect through the TURN server
| Code Block | ||||
|---|---|---|---|---|
| ||||
let mediaOptions = {"iceServers": [{'url': 'turn:turn.flashphoner.com:443?transport=tcp', 'username': 'flashphoner', 'credential': 'coM77EMrV7Cwhyan'}]};
Flashphoner.createSession({urlServer: urlServer, mediaOptions: mediaOptions}).on(SESSION_STATUS.ESTABLISHED, function (session) {
...
}); |
3. Receiving the event confirming successful connection
SESSION_STATUS.ESTABLISHED code
| Code Block | ||||
|---|---|---|---|---|
| ||||
var mediaOptions = {"iceServers": [{'url': 'turn:turn.flashphoner.com:443?transport=tcp', 'username': 'flashphoner', 'credential': 'coM77EMrV7Cwhyan'}]};Flashphoner.createSession({urlServer: urlServer, mediaOptions: mediaOptions}).on(SESSION_STATUS.ESTABLISHED, function (session) { FlashphonersetStatus(session.createSession({urlServer: urlServer, mediaOptions: mediaOptionsstatus()); //session connected, start playback playStream(session); }).on(SESSION_STATUS.ESTABLISHEDDISCONNECTED, function (session) { ... }).on(SESSION_STATUS.FAILED, function () { ... }); |
3. Receiving the event confirming successful connection
ConnectionStatusEvent ESTABLISHED code
...
| language | js |
|---|---|
| theme | RDark |
...
4. Video stream playback.
Session.createStream() , Stream.play() code
The following parameters are passed to createStream() method:
streamName- name of the streamremoteVideo-divelement to display stream on page- resolution to play the stream (transcoding will be enabled on server)
useControls- enables a standard HTML5 video controlsunmutePlayOnStart: false- disables automatic audio unmuting for autoplay to conform browsers requirements
| Code Block | ||||
|---|---|---|---|---|
| ||||
let useVideoControls = true; ... let options = { name: streamName, setStatus(session.status()); display: remoteVideo, useControls: //session connected, start playbackuseVideoControls }; if (resolution) { playWidth playStream(session); = resolution.split("x")[0]; playHeight }).on(SESSION_STATUS.DISCONNECTED, function () {= resolution.split("x")[1]; options.constraints = { ... }).on(SESSION_STATUS.FAILED, function ()video: { ... }); |
...
session.createStream(), play() code
These parameters are passed to createStream() method:
- streamName - name of the stream
- remoteVideo - <div>-element to display stream on page
- switch to show/|hide full screen button
- player window resolution
- unmutePlayOnStart: false - disables automatic audio unmuting for autoplay to conform browsers requirements
| Code Block | ||||
|---|---|---|---|---|
| ||||
var options = { name: streamNamewidth: playWidth, height: playHeight }, display: remoteVideo, flashShowFullScreenButtonaudio: true }; } if (resolution_for_wsplayerautoplay) { options.playWidthunmutePlayOnStart = resolution_for_wsplayer.playWidth; options.playHeight = resolution_for_wsplayer.playHeight; } else if (resolutionfalse; } playingStream = session.createStream(options).on(STREAM_STATUS.PENDING, function (stream) { options.playWidth = resolution.split("x")[0]; options.playHeight = resolution.split("x")[1]; } if (autoplay) { options.unmutePlayOnStart = false; } stream = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) { ... }); stream.play(); |
5. Receiving the event confirming stream is ready to playback
StreamStatusEvent PENDING code
...
...
});
playingStream.play(); |
5. Receiving the event confirming stream is ready to playback
STREAM_STATUS.PENDING code
On this event:
- hide the custom preloader in Chrome browser because there is a standard one when standard controls are enabled
- set up
resizevideo event handler - set up video event handlers separately for Safari and other browsers
| Code Block | ||||
|---|---|---|---|---|
| ||||
playingStream stream = session.createStream(options).on(STREAM_STATUS.PENDING, function (stream) { var video = document.getElementById(stream.idif (Browser.isChrome()); { if (!video.hasListeners) { video.hasListeners = true;// Hide a custom preloader in Chrome because there is a standard one with standard controls video.addEventListener('playing', function () {hideItem('preloader'); } let video = document.getElementById(stream.id()); if $("#preloader").hide();(!video.hasListeners) { video.hasListeners = })true; video.addEventListener('resize', function (event) { setResizeHandler(video, stream, playWidth); if (Browser.isSafariWebRTC()) { var streamResolution = stream.videoResolutionsetWebkitEventHandlers(video); } else { if setEventHandlers(Object.keys(streamResolution).length === 0) { video); } } }).on(STREAM_STATUS.PLAYING, function (stream) { ... }).on(STREAM_STATUS.STOPPED, function () resizeVideo(event.target); { ... }).on(STREAM_STATUS.FAILED, function(stream) { } else ... }).on(STREAM_EVENT, function(streamEvent){ // Change aspect ratio to prevent video stretching var ratio = streamResolution.width / streamResolution.height; var newHeight = Math.floor(options.playWidth / ratio); ... }); playingStream.play(); |
6. Receiving the event confirming successful stream playback
STREAM_STATUS.PLAYING code
On this event, MSE stream playback is unpaused in Android Firefox browser
| Code Block | ||||
|---|---|---|---|---|
| ||||
playingStream = session.createStream(options).on(STREAM_STATUS.PENDING, function (stream) { ... }).on(STREAM_STATUS.PLAYING, function (stream) { // Android Firefox may pause stream playback via MSE even if video element is muted if (Flashphoner.getMediaProviders()[0] == "MSE" && autoplay && Browser.isAndroidFirefox()) { resizeVideo(event.target, options.playWidth, newHeightlet video = document.getElementById(stream.id()); if (video && }video.paused) { }video.play(); } }).on setStatus(STREAM_STATUS.PLAYING, function (stream) {); ... onStarted(); }).on(STREAM_STATUS.STOPPED, function () { ... }).on(STREAM_STATUS.FAILED, function (stream) { ... }).on(STREAM_STATUS.NOT_ENOUGH_BANDWIDTHEVENT, function (streamstreamEvent) { ... }); stream.playingStream.play(); |
6. Receiving the event confirming successful stream playback
StreamStatusEvent PLAYING 7. Stream playback stop
Stream.stop() code
| Code Block | ||||
|---|---|---|---|---|
| ||||
stream = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) {
...
}).on(STREAM_STATUS.PLAYING, function (stream) {
setStatus(stream.status());
onStarted(stream);
}).on(STREAM_STATUS.STOPPED, function () {
...
}).on(STREAM_STATUS.FAILED, function () {
...
}).on(STREAM_STATUS.NOT_ENOUGH_BANDWIDTH, function (stream) {
...
});
stream.play(); |
7. Stream playback stop
stream.stop() code
| Code Block | ||||
|---|---|---|---|---|
| ||||
$that.find('.play-pause').bind('click', function () { // If playing, etc, change classes to show pause or play button if (!$(this).prop('disabled')) { if (stopped) { ... } elseplayingStream.stop(); |
8. Receiving the event confirming successful playback stop
STREAM_STATUS.STOPPED code
| Code Block | ||||
|---|---|---|---|---|
| ||||
playingStream = session.createStream(options).on(STREAM_STATUS.PENDING, function (stream) {
...
}).on(STREAM_STATUS.PLAYING, function (stream) {
...
}).on(STREAM_STATUS.STOPPED, function () {
setStatus(STREAM_STATUS.STOPPED);
onStopped();
}).on(STREAM_STATUS.FAILED, function(stream) {
...
}).on(STREAM_EVENT, function(streamEvent){
...
});
playingStream.play(); |
9. Automatic playback starting if required
| Code Block | ||||
|---|---|---|---|---|
| ||||
if (autoplay) {
centralButton.click();
} |
10. Setting up resize event handler
On this event, the container size for video element is changed
| Code Block | ||||
|---|---|---|---|---|
| ||||
function setResizeHandler(video, stream, playWidth) { video.addEventListener('resize', function (event) { let streamResolution if (stream) {= stream.videoResolution(); if (Object.keys(streamResolution).length === 0) { stream.stop(resizeVideo(event.target); } else { // Change } aspect ratio to prevent video stretching let ratio = streamResolution.width / ...streamResolution.height; let newHeight = Math.floor(playWidth }/ ratio); resizeVideo(event.target, }playWidth, newHeight); } }); |
8. Receiving the event confirming successful playback stop
...
;
} |
11. Setting up event handlers for Safari browser
The following events are handled:
playing- hide the custom preloader when stream is playingwebkitbeginfullscreen,webkitendfullscreen- detect full screen mode to unpause stream playback when exiting this mode in iOS Safaripause- unpause stream playback when exiting full screen mode; stop playback by clicking the standard pause control in windowed mode
| Code Block | ||||
|---|---|---|---|---|
| ||||
function setWebkitEventHandlers(video) { let streamneedRestart = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) { false; let isFullscreen = false; // Hide custom ...preloader })video.on(STREAM_STATUS.PLAYINGaddEventListener('playing', function (stream) { ...hideItem('preloader'); }).on(STREAM_STATUS.STOPPED, function () {; // setStatus(STREAM_STATUS.STOPPED); onStopped();Use webkitbeginfullscreen event to detect full screen mode in iOS Safari })video.on(STREAM_STATUS.FAILEDaddEventListener("webkitbeginfullscreen", function () { ... isFullscreen = }).on(STREAM_STATUS.NOT_ENOUGH_BANDWIDTH, function (stream) { true; }); ... }); streamvideo.play(); |
9. Playback volume setting
stream.unmuteRemoteAudio(), stream.setVolume(currentVolumeValue) code
| Code Block | ||||
|---|---|---|---|---|
| ||||
addEventListener("pause", function () { if (streamneedRestart) { if (volume > 0) {console.log("Video paused after fullscreen, continue..."); video.play(); ifneedRestart (!firstUnmuted && slider && Browser.isAndroid()) { = false; } else if (!(isFullscreen || document.webkitFullscreenElement)) { console.error("User should click volume unmute button to// enable audio"); Stop stream by standard play/pause control returnplayingStream.stop(false); } }); else if (stream.isRemoteAudioMutedvideo.addEventListener("webkitendfullscreen", function ()) { video.play(); needRestart = stream.unmuteRemoteAudio()true; isFullscreen = false; }); firstUnmuted = true; } } } |
12. Setting up event handlers in other browsers
The following events are handled:
playing- hide the custom preloader when stream is playingpause- stop playback by clicking the standard pause control in windowed mode
| Code Block | ||||
|---|---|---|---|---|
| ||||
function setEventHandlers(video) { // Hide stream.setVolume(volume); } // Save current volume in page element to restore it when mute/unmute custom preloader video.addEventListener('playing', function () { $hideItem('#volume-range').val(volumepreloader'); ... |
10. Automatic playback start on page load
| Code Block | ||||
|---|---|---|---|---|
| ||||
if (autoplay ) {}); // Use standard pause control to stop playback video.addEventListener("pause", function () { // Autoplay will start for muted video tag only, adjust mute button and slider view if (!(document.fullscreenElement || document.mozFullscreenElement)) { firstUnmuted = false; $('.volume').addClass('volume-none'); $('.volume').html(HTML_VOLUME_MUTE); // Stop stream by standard play/pause control if we're not in fullscreen $('#slider').slider( "value", 1 playingStream.stop(); $(".play-pause").click();} }); } |

