A streamer example with publishing/playback automatic restore
This example shows how to restore stream publishing/playback automatically by :
- changing publishing codec to VP8
...
- when H264
...
- publishing fails
...
Code of the example
The example code is available on WCS server by the following path:
/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/stream-auto-restore
stream-auto-restore.css - styles file
stream-auto-restore.html - client page
stream-auto-restore.js - main script to work
The example can be tested by the following URL:
https://host:8888/client2/examples/demo/streaming/stream_filter/stream-auto-restore.html
Where host - WCS server address.
Analyzing the code
To analyze the code take the file stream_filter.js version with hash f2862b9 which is available here and can be downloaded with SDK build 2.0.207.
...
- republish a stream if browser stops sending media packets (this is detected by video bitrate drop to 0)
- when network is changing (form Wi-Fi to LTE and vice versa)
- when streaming fails due to server connection breaking (including server restart) or due to stream publishing stopping by other side
Bitrate checking parameters
- Check bitrate - check if bitrate drops to 0
- Change codec - change H264 codec to VP8 if bitrate drop is detected
- Bitrate check interval - publishing bitrate checking interval
- Max tries - maximium number of subsequent bitrate drops to 0
Connection restoring parameters
- Restore connection - restore connection if session breaks or publishing/playback is failed
- Timeout - connection restore tries interval
- Max tries - maximum number of connection restore tries
- Missing pings - maximum number of subsequent missing pings from server (0 disables ping checking)
- Pings check period - pings checking interval (0 disables ping checking)
Code of the example
The example code is available on WCS server by the following path:
/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/stream-auto-restore
stream-auto-restore.css - styles file
stream-auto-restore.html - client page
stream-auto-restore.js - main script to work
The example can be tested by the following URL:
https://host:8888/client2/examples/demo/streaming/stream_filter/stream-auto-restore.html
Where host - WCS server address.
Analyzing the code
To analyze the code take the file stream_filter.js version with hash 2035db9 which is available here and can be downloaded with SDK build 2.0.209.
1. Page loading action
1.1. API initialization
Flashphoner.init() code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.init(); |
1.2. Connecting to the server.Flashphoner.createSession() Session and publishing/playing streams state objects initialization
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){ currentSession = sessionState(); setStatus("#connectStatus", session.statusstreamPublishing = streamState()); onConnected(session); }).on(SESSION_STATUS.DISCONNECTED, function(){ setStatus("#connectStatus", SESSION_STATUS.DISCONNECTED); onDisconnected(); }).on(SESSION_STATUS.FAILED, function(){ setStatus("#connectStatus", SESSION_STATUS.FAILED); onDisconnected(); }); |
3. Receiving the event confirming successful connection.
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
setStatus("#connectStatus", session.status());
onConnected(session);
}).on(SESSION_STATUS.DISCONNECTED, function(){
...
}).on(SESSION_STATUS.FAILED, function(){
...
}); |
4. Video streaming.
...
streamPlaying = streamState(); |
1.3. Bitrate checking object initialization
Code Block | ||||
---|---|---|---|---|
| ||||
h264PublishFailureDetector = codecPublishingFailureDetector(); |
1.4. Connection restore object initialization
The function should be passed to the object to execute it when restore connection timer is fired
Code Block | ||||
---|---|---|---|---|
| ||||
streamingRestarter = streamRestarter(function() {
if (streamPublishing.wasActive) {
onPublishRestart();
}
if (streamPlaying.wasActive && streamPlaying.name != streamPublishing.name) {
onPlayRestart();
}
}); |
1.5. Network change detector start
Code Block | ||||
---|---|---|---|---|
| ||||
networkChangeDetector(); |
2. Server connection/disconnection actions
2.1. Connecting to the server
Flashphoner.createSession() code
The following parameters are passed when session is created:
- streamName - stream name
- localVideo - div tag to display video from camera
- stripCodecs - codec to exclude from publishingurl - server Websocket URL
- receiveProbes - maximum number of subsequent missing pings from server (0 disables ping checking)
- probesInterval - pings checking interval (0 disables ping checking)
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream Flashphoner.createSession({ nameurlServer: streamNameurl, display receiveProbes: localVideoreceiveProbes, cacheLocalResources: true receiveVideoprobesInterval: false,probesInterval }).on(SESSION_STATUS.ESTABLISHED, function receiveAudio: false,(session) { stripCodecs: stripCodecs ... } }).publish(); |
5. Receiving the event confirming successful streaming.
StreamStatusEvent PUBLISHING code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({ on(SESSION_STATUS.DISCONNECTED, function () { ... }).on(STREAMSESSION_STATUS.PUBLISHINGFAILED, function (stream) { setStatus("#publishStatus", STREAM_STATUS.PUBLISHING); ... onPublishing(stream}); }).on(STREAM_STATUS.UNPUBLISHED, function() |
2.2. Receiving the event comfirming successful connection
ConnectionStatusEvent ESTABLISHED code
When xconnection is established:
- session parameters are stored in session state object
- stream publishing/playback is restarted if stream was published/played in previous session
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({ ... urlServer: url, receiveProbes: receiveProbes, probesInterval: probesInterval }).on(STREAMSESSION_STATUS.FAILEDESTABLISHED, function (session) { setStatus("#connectStatus", ... }).publish(); |
6. Stream playback.
session.createStream(), play() code.
When stream is created, the following parameters are passed
- streamName - name of the stream (including the stream published on step above)
- remoteVideo - <div> element, in which video playback will be displayed
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
...
}).play(); |
7. Receiving the event confirming successful stream playback.
StreamStatusEvent PLAYING code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
...
}).on(STREAM_STATUS.PLAYING, function(stream) {
setStatus("#playStatus", stream.status());
onPlaying(stream);
}).on(STREAM_STATUS.STOPPED, function() {
...
}).on(STREAM_STATUS.FAILED, function() {
...
}).play(); |
8. Stream playback stop.
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onPlaying(stream) {
$("#playBtn").text("Stop").off('click').click(function(){
$(this).prop('disabled', true);
stream.stop();
}).prop('disabled', false);
$("#playInfo").text("");
} |
9. Receiving the event confirming successful playback stop.а.
StreamStatusEvent STOPPED code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
...
}).on(STREAM_STATUS.PLAYING, function(stream) {
...
}).on(STREAM_STATUS.STOPPED, function() {
setStatus("#playStatus", STREAM_STATUS.STOPPED);
onStopped();
}).on(STREAM_STATUS.FAILED, function() {
...
}).play(); |
10. Streaming stop.
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onPublishing(stream) {
$("#publishBtn").text("Stop").off('click').click(function(){
$(this).prop('disabled', true);
stream.stop();
}).prop('disabled', false);
$("#publishInfo").text("");
...
} |
11. Receiving the event confirming successful streaming stop.
StreamStatusEvent UNPUBLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
...
}).on(STREAM_STATUS.PUBLISHING, function(stream){
...
}).on(STREAM_STATUS.UNPUBLISHED, function(){
setStatus("#publishStatus", STREAM_STATUS.UNPUBLISHED);
onUnpublished();
}).on(STREAM_STATUS.FAILED, function(){
...
}).publish(); |
...
session.status());
currentSession.set(url, session);
onConnected(session);
if(restoreConnection) {
if(streamPublishing.wasActive) {
console.log("A stream was published before disconnection, restart publishing");
onPublishRestart();
return;
}
if(streamPlaying.wasActive) {
console.log("A stream was played before disconnection, restart playback");
onPlayRestart();
}
}
}).on(SESSION_STATUS.DISCONNECTED, function () {
...
}).on(SESSION_STATUS.FAILED, function () {
...
}); |
2.3. Connection closing by clicking Disconnect button
session.disconnect() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onConnected(session) {
$("#connectBtn").text("Disconnect").off('click').click(function () {
$(this).prop('disabled', true);
currentSession.isManuallyDisconnected = true;
session.disconnect();
}).prop('disabled', false);
...
} |
2.4. Receiving the connection closing event
ConnectionStatusEvent DISCONNECTED code
If connection is closed manually by clicking Disconnect:
- state objects are cleared
- connection restore timer is stopped
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({
urlServer: url,
receiveProbes: receiveProbes,
probesInterval: probesInterval
}).on(SESSION_STATUS.ESTABLISHED, function (session) {
...
}).on(SESSION_STATUS.DISCONNECTED, function () {
setStatus("#connectStatus", SESSION_STATUS.DISCONNECTED);
onDisconnected();
// Prevent streaming restart if session is manually disconnected
if (currentSession.isManuallyDisconnected) {
streamPublishing.clear();
streamPlaying.clear();
streamingRestarter.reset();
currentSession.clear();
}
}).on(SESSION_STATUS.FAILED, function () {
...
}); |
2.5. Receiving the connection failure event
ConnectionStatusEvent FAILED code
Connection restore timer is starting if a stream was published or played befor connection is failed
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({
urlServer: url,
receiveProbes: receiveProbes,
probesInterval: probesInterval
}).on(SESSION_STATUS.ESTABLISHED, function (session) {
...
}).on(SESSION_STATUS.DISCONNECTED, function () {
...
}).on(SESSION_STATUS.FAILED, function () {
setStatus("#connectStatus", SESSION_STATUS.FAILED);
onDisconnected();
if(restoreConnection
&& (streamPublishing.wasActive || streamPlaying.wasActive)) {
streamingRestarter.restart($("#restoreTimeout").val(), $("#restoreMaxTries").val());
}
}); |
3. Stream publishing actions
3.1 Stream publishing
session.createStream(), publish() code
The following parameters are passed while stream creation:
- streamName - stream name to publish
- localVideo - div element to display local video
- stripCodecs - codec to exclude if codec changing option is active
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: localVideo,
cacheLocalResources: true,
receiveVideo: false,
receiveAudio: false,
stripCodecs: stripCodecs
...
}).publish(); |
3.2. Receiving the stream publishing event
StreamStatusEvent PUBLISHING code
When stream is publishing successfully:
- bitrate checking timer starts
- the stream parameters are stored in publishing stream state object
- connection restore timer stops
- stream playback starts if stream was played previously
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
...
}).on(STREAM_STATUS.PUBLISHING, function (stream) {
setStatus("#publishStatus", STREAM_STATUS.PUBLISHING);
onPublishing(stream);
streamPublishing.set(streamName, stream);
streamingRestarter.reset();
if ($("#restoreConnection").is(':checked')
&& streamPlaying.wasActive) {
console.log("A stream was played before, restart playback");
onPlayRestart();
}
}).on(STREAM_STATUS.UNPUBLISHED, function () {
...
}).on(STREAM_STATUS.FAILED, function (stream) {
...
}).publish(); |
3.3. Bitrate checking timer startup
Code Block | ||||
---|---|---|---|---|
| ||||
function onPublishing(stream) {
...
// Start publish failure detector by bitrate #WCS-3382
if($("#checkBitrate").is(':checked')) {
h264PublishFailureDetector.startDetection(stream, $("#bitrateInteval").val(), $("#bitrateMaxTries").val());
}
} |
3.4. Publishing stopping by clicking Stop button
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onPublishing(stream) {
$("#publishBtn").text("Stop").off('click').click(function () {
$(this).prop('disabled', true);
streamPublishing.isManuallyStopped = true;
stream.stop();
}).prop('disabled', false);
...
} |
3.5. Receiving stream publishing stoppin event
StreamStatusEvent UNPUBLISHED code
When stream is successfully stopped:
- bitrate checking timer stops
- connection restore timer stops
- publishing stream state object is cleared
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
...
}).on(STREAM_STATUS.PUBLISHING, function (stream) {
...
}).on(STREAM_STATUS.UNPUBLISHED, function () {
setStatus("#publishStatus", STREAM_STATUS.UNPUBLISHED);
onUnpublished();
if (!streamPlaying.wasActive) {
// No stream playback< we don't need restart any more
streamingRestarter.reset();
} else if (streamPlaying.wasActive && streamPlaying.name == streamPublishing.name) {
// Prevent playback restart for the same stream
streamingRestarter.reset();
}
streamPublishing.clear();
}).on(STREAM_STATUS.FAILED, function (stream) {
...
}).publish(); |
3.6. Receiving stream publishing failure event
StreamStatusEvent FAILED code
When stream publishing fails:
- bitrate checking timer stops
- connection restore timer starts unless local browser error is detected (media devices unavailable for example)
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
...
}).on(STREAM_STATUS.PUBLISHING, function (stream) {
...
}).on(STREAM_STATUS.UNPUBLISHED, function () {
...
}).on(STREAM_STATUS.FAILED, function (stream) {
setStatus("#publishStatus", STREAM_STATUS.FAILED, stream);
onUnpublished();
if ($("#restoreConnection").is(':checked') && stream.getInfo() != ERROR_INFO.LOCAL_ERROR) {
streamingRestarter.restart($("#restoreTimeout").val(), $("#restoreMaxTries").val());
}
}).publish(); |
3.7. Bitrate checking timer stopping
Code Block | ||||
---|---|---|---|---|
| ||||
function onUnpublished() {
...
h264PublishFailureDetector.stopDetection(streamPublishing.isManuallyStopped || currentSession.isManuallyDisconnected);
...
}
|
4. Stream playback actions
4.1. Stream playback
session.createStream(), play() code.
The following parameters are passed while stream creation:
- streamName - stream name to play
- remoteVideo - div element to display remote video
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
...
}).play(); |
4.2. Receiving the stream playback event
StreamStatusEvent PLAYING code
When stream is successfully playing:
- the stream parameters are stored in playing stream state object
- connection restore timer stops
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PENDING, function (stream) {
...
}).on(STREAM_STATUS.PLAYING, function (stream) {
setStatus("#playStatus", stream.status());
onPlaying(stream);
streamingRestarter.reset();
streamPlaying.set(streamName, stream);
}).on(STREAM_STATUS.STOPPED, function () {
...
}).on(STREAM_STATUS.FAILED, function (stream) {
...
}).play(); |
4.3 Stream playback stopping by clicking Stop button
stream.stop() code
Code Block | ||||
---|---|---|---|---|
| ||||
function onPlaying(stream) {
$("#playBtn").text("Stop").off('click').click(function(){
$(this).prop('disabled', true);
stream.stop();
}).prop('disabled', false);
$("#playInfo").text("");
} |
4.4. Receiving the stream playback stopping event
StreamStatusEvent STOPPED code
When stream playback is successfully stopped:
- connection restore timer stops
- playing stream state object is cleared
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PENDING, function (stream) {
...
}).on(STREAM_STATUS.PLAYING, function (stream) {
...
}).on(STREAM_STATUS.STOPPED, function () {
setStatus("#playStatus", STREAM_STATUS.STOPPED);
onStopped();
streamingRestarter.reset();
streamPlaying.clear();
}).on(STREAM_STATUS.FAILED, function (stream) {
...
}).play(); |
4.5. Receiving the stream playback failure event
StreamStatusEvent FAILED code
Connection restore timer starts is stream playback fails
Code Block | ||||
---|---|---|---|---|
| ||||
session.createStream({
name: streamName,
display: remoteVideo
}).on(STREAM_STATUS.PENDING, function (stream) {
...
}).on(STREAM_STATUS.PLAYING, function (stream) {
...
}).on(STREAM_STATUS.STOPPED, function () {
...
}).on(STREAM_STATUS.FAILED, function (stream) {
setStatus("#playStatus", STREAM_STATUS.FAILED, stream);
onStopped();
if ($("#restoreConnection").is(':checked')) {
streamingRestarter.restart($("#restoreTimeout").val(), $("#restoreMaxTries").val());
}
}).play(); |
5. Bitrate checking and stream republishing if bitrate drops to 0
5.1. Receiving browser WebRTC statistics, codec and bitrate detection, publishing stopping if bitrate drops to 0
Code Block | ||||
---|---|---|---|---|
| ||||
stream.getStats(function(stat) {
let videoStats = stat.outboundStream.video;
if(!videoStats) {
return;
}
let stats_codec = videoStats.codec;
let bytesSent = videoStats.bytesSent;
let bitrate = (bytesSent - detector.lastBytesSent) * 8;
if (bitrate == 0) {
detector.counter.inc();
console.log("Bitrate is 0 (" + detector.counter.getCurrent() + ")");
if (detector.counter.exceeded()) {
detector.failed = true;
console.log("Publishing seems to be failed, stop the stream");
stream.stop();
}
} else {
detector.counter.reset();
}
detector.lastBytesSent = bytesSent;
detector.codec = stats_codec;
$("#publishInfo").text(detector.codec);
}); |
5.2. Bitrate checking timer stopping
Code Block | ||||
---|---|---|---|---|
| ||||
if (detector.publishFailureIntervalID) {
clearInterval(detector.publishFailureIntervalID);
detector.publishFailureIntervalID = null;
} |
5.3. Stream republishing
Code Block | ||||
---|---|---|---|---|
| ||||
if (detector.failed) {
$("#publishInfo").text("Failed to publish " + detector.codec);
if($("#changeCodec").is(':checked')) {
// Try to change codec from H264 to VP8 #WCS-3382
if (detector.codec == "H264") {
console.log("H264 publishing seems to be failed, trying VP8 by stripping H264");
let stripCodecs = "H264";
publishBtnClick(stripCodecs);
} else if (detector.codec == "VP8") {
console.log("VP8 publishing seems to be failed, giving up");
}
} else {
// Try to republish with the same codec #WCS-3410
publishBtnClick();
}
} |
6. Connection restoration
6.1. Connection restore timer launching
The timer invokes a function to perform an ctions needed
Code Block | ||||
---|---|---|---|---|
| ||||
restarter.restartTimerId = setInterval(function(){
if (restarter.counter.exceeded()) {
logger.info("Tried to restart for " + restartMaxTimes + " times with " +restartTimeout + " ms interval, cancelled");
restarter.reset();
return;
}
onRestart();
restarter.counter.inc();
}, restartTimeout); |
6.2. Connectin restore timer stopping
Code Block | ||||
---|---|---|---|---|
| ||||
if (restarter.restartTimerId) {
clearInterval(restarter.restartTimerId);
logger.info("Timer " + restarter.restartTimerId + " stopped");
restarter.restartTimerId = null;
}
restarter.counter.reset(); |
6.3. New session creation if previous session is failed or disconnected
Code Block | ||||
---|---|---|---|---|
| ||||
let sessions = Flashphoner.getSessions();
if (!sessions.length || sessions[0].status() == SESSION_STATUS.FAILED) {
logger.info("Restart session to publish");
click("connectBtn");
} else {
...
} |
6.4. Republishing
Code Block | ||||
---|---|---|---|---|
| ||||
let streams = sessions[0].getStreams();
let stream = null;
let clickButton = false;
if (streams.length == 0) {
// No streams in session, try to restart publishing
logger.info("No streams in session, restart publishing");
clickButton = true;
} else {
// If there is already a stream, check its state and restart publishing if needed
for (let i = 0; i < streams.length; i++) {
if (streams[i].name() === $('#publishStream').val()) {
stream = streams[i];
if (!isStreamPublishing(stream)) {
logger.info("Restart stream " + stream.name() + " publishing");
clickButton = true;
}
break;
}
}
if (!stream) {
logger.info("Restart stream publishing");
clickButton = true;
}
}
if (clickButton) {
click("publishBtn");
} |
6.5. Replaying
Code Block | ||||
---|---|---|---|---|
| ||||
var statPublishFailureDetector let streams = {sessions[0].getStreams(); failed: false, let codec: "",stream = null; lastBytesSent: 0, let clickButton counter:= {false; value: 0,if (streams.length == 0) { threshold: PUBLISH_FAILURE_DETECTOR_MAX_TRIES // } }; |
13. Publishing bitrate chacking start by STREAM_STATUS.PUBLISHING event.
Code Block | ||||
---|---|---|---|---|
| ||||
function onPublishing(stream) { ... if(Browser.isChrome()) { No streams in session, try to restart playing detectPublishFailure(stream, PUBLISH_FAILURE_DETECTOR_INTERVAL, PUBLISH_FAILURE_DETECTOR_MAX_TRIES); logger.info("No streams in session, restart playback"); } } |
14. WebRTC statistics gathering from browser, current publishing codec and bitrate detection, publishing stopping if bitrate is constantly drops to 0.
Code Block | ||||
---|---|---|---|---|
| ||||
clickButton = true; stream.getStats(function(stat)} else { let// videoStatsIf = stat.outboundStream.video; if(!videoStats) { there is already a stream, check its state and restart playing if needed for (let i = 0; i < return;streams.length; i++) { } if (streams[i].name() === $('#playStream').val()) { let codec = videoStats.codec; let bytesSentstream = videoStats.bytesSentstreams[i]; let bitrate = (bytesSent - statPublishFailureDetector.lastBytesSent) * 8; if (!isStreamPlaying(stream)) { if (bitrate == 0) { logger.info("Restart stream " + statPublishFailureDetector.counter.value++stream.name() + " playback"); console.log("Bitrate is 0 (" + statPublishFailureDetector.counter.value + ")"); clickButton = true; } if (statPublishFailureDetector.counter.value >= statPublishFailureDetector.counter.threshold) { break; statPublishFailureDetector.failed = true; } console.log("Publishing seems to be failed, stop the stream"); } if (!stream) { streamlogger.stop(info("Restart stream playback"); clickButton = }true; } else { } statPublishFailureDetector.counter.value = 0;if (clickButton) { }click("playBtn"); } |
7. Network change actions
7.1. Network change event handling
connection.onchange code
Code Block | ||||
---|---|---|---|---|
| ||||
statPublishFailureDetector.lastBytesSent = bytesSent;if (Browser.isChrome() || (Browser.isFirefox() && Browser.isAndroid())) { connection = navigator.connection || statPublishFailureDetectornavigator.codecmozConnection = codec|| navigator.webkitConnection; if (connection) { $("#publishInfo").text(statPublishFailureDetector.codec); }); |
15. Bitrate checking timer stopping and streaming restart function invokation by STREAM_STATUS.UNPUBLISHED event
Code Block | ||||
---|---|---|---|---|
| ||||
function onUnpublished() { connectionType = connection.type; ... if (publishFailureIntervalIDBrowser.isFirefox()) { clearInterval(publishFailureIntervalID); publishFailureIntervalIDconnection.ontypechange = nullonNetworkChange; } else { checkPublishFailureConditions(); } |
16. Restart publishing with VP8 codec
Code Block | ||||
---|---|---|---|---|
| ||||
function checkPublishFailureConditions() { if (statPublishFailureDetector.failed) { connection.onchange = onNetworkChange; $("#publishInfo").text("Failed to publish " + statPublishFailureDetector.codec);} } } |
7.2. Closing the connection if network is changed
Code Block | ||||
---|---|---|---|---|
| ||||
if (isNetworkConnected() if (statPublishFailureDetector.codec == "H264"&& connection.type != connectionType) { console.log("H264 publishing seems to be failed, trying VP8 by stripping H264"); if (currentSession.getStatus() == SESSION_STATUS.ESTABLISHED) { let stripCodecslogger = "H264"; Flashphoner.getLogger(); publishBtnClick(stripCodecs); logger.info("Close session due to network change }from else" if (statPublishFailureDetector.codec == "VP8") { + connectionType + " to " + connection.type); console.log("VP8 publishing seems to be failed, giving up" currentSession.sdkSession.disconnect(); } } } |