VideoJS doesn´t play after pause RTMP live stream - html5-video

I´m using VideoJS for a live stream from Wowza server but when I pause the player and them I play again the player does not recover the stream. I need to reload the webpage to start the stream again.
<video id="videoID" class="video-js vjs-default-skin vjs-big-play-centered" poster="/images/image.png" controls="controls" width="320" height="240" data-setup='{"techOrder": ["flash"]}'>
<source src="rtmp://www.myhost.com:1935/live/live.stream" type="rtmp/mp4" />
</video>
There are any method to do stop or VideoJS reload when the paused event appear?
EDIT: I've encountered the solution using this script:
<script type="text/javascript">
var myPlayer = videojs('videoID');
videojs("videoID").ready(function(){
var myPlayer = this;
myPlayer.on("pause", function () {
myPlayer.on("play", function () { myPlayer.load (); myPlayer.off("play"); });
});
});
</script>

Ok so i found a solution. Instead of stripping all of the play events form the player you actually just need to edit the flash play event inside of video.dev.js on line 7337 (in version 4.11.4 i think). this is the line that says:
vjs.Flash.prototype.play = function(){
this.el_.vjs_play();
};
it should be changed to say:
vjs.Flash.prototype.play = function(){
this.el_.vjs_load();
this.el_.vjs_play();
};
so that the load event is called before the play event.

I found the solution here
$(document).ready(function(){
var player = videojs('really-cool-video', { /* Options */}, function () {
// ...
var player = this;
player.on("pause", function () {
player.one("play", function () {
player.load();
player.play();
});
});
});
});

Related

Browser keeps on accessing the camera with red dot even after stopping the stream aafter establishing the peer connection using webRTC

let localStream;
let peerConnection;
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(function(stream) {
createPeerConnection();
localStream = stream;
peerConnection.addStream(localStream);
});
so when stopping the stream it stops the video
localStream.getTracks().forEach(track => track.stop());
But the browser tab says that it is accessing the camera or microphone with a red dot besides it. I just do not want to reload the page in order to stop that.
Note: this happens when after establishing a peer connection using webRTC and after disconnecting the peers the camera light stays on.
Is there any way to do that. Thanks for your help in advance.
you can use boolean value or condition in which tab access camera after track.stop() you can set the value to false then the camera will not be acessed anymore. (p.s you can try that if its works)
<!DOCTYPE html>
<html>
<head>
<title>Web Client</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="callerIDContainer">
<button onclick="call_user();">Call User</button>
</div>
<div class="video-container">
<video autoplay muted class="local-video" id="local-video"></video>
</div>
<div>
<button onclick="hangup();">Hangup</button>
</div>
</body>
<script >
var localStream;
var accessRequired=true
function call_user() //your function
{
if(accessRequired)
{
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(function(stream) {
localStream = stream;
const localVideo = document.getElementById("local-video");
if (localVideo) {
localVideo.srcObject = localStream;
}
});
}
}
function hangup(){
localStream.getTracks().forEach(track => track.stop()).then(()=>{accessRequired=false});
}
</script>
</html>
try this call user then hangup it is working
The sample code in your question looks like it uses gUM() to create an audio-only stream ({video: false, audio:true}).
It would be strange if using .stop() on all the tracks on your audio-only stream also stopped the video track on some other stream. If you want to turn off your camera's on-the-air light you'll need to stop the video track you used in peerConnection.addTrack(videoTrack). You probably also need to tear down the call using peerConnection.close().
I had same issue with webRTC and React. I have stopped tracks of remote stream but I forgot to stop local stream :
window.localStream.getTracks().forEach((track) => {
track.stop();
});

URL.createObjectURL(mediaSource) - play back video from URL - MOOV atom - Elastic Transcoder

I am trying to play back a video (currently hosted on S3 with public access) by creating a blob URL.
I have used Elastic Transcoder to encode the video since it is supposed to set the MOOV atom to the top (beginning).
I am unable to get the code to work but also found a working example: link here
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
mediaSource.endOfStream();
video.play();
//console.log(mediaSource.readyState); // ended
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
What am I doing wrong? I looked at tools ie.e MP4Box or QT-FastStart but they seem to be kind of old school. I would also be willing to change from MP4 to M3U8 playlist but then I don't know what MIME types to use.
At the ned of the day I am trying to play back a video/stream and hide the URL (origin) potentially using blob.
Thank you guys!
So, first, even though this code seems to be taken from mozilla documentation site, there are a few issues - you are not checking the readyState before calling endOfStream thus the error you get is valid, secondly, the play() call is blocked by the autoplay policy changes. If you add an error handler, you will actually see that the appendBuffer fails. Here is the updated snippet:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
// console.log(mediaSource.readyState); // ended
if (mediaSource.readyState === "open") {
mediaSource.endOfStream();
video.play();
}
});
sourceBuffer.addEventListener('error', function (event) {
console.log('an error encountered while trying to append buffer');
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
So lets advance to next issue - the actual error. So, using chrome://media-internals/ we can see that the video actually fails to load do to incompatibility with the ISOBMFF format:
I am not familiar with Elastic Transcoder, but it seems that is it not producing an mp4 file suitable for live streaming. Also, if using mse, putting moov at the beginning is not enough, the video actually has to meet all of the ISOBMFF requirements - see chapters 3. and 4.
The working sample you mentioned is not a valid comparison since it uses the blob for the src, where the ISOBMFF rules do not apply. If it is fine for you to go that way, don't use MSE and put the blob directly in the src. If you need MSE, you have to mux it correctly.
Ok, so I got the original code example to work by encoding my MP4 videos with ffmpeg:
ffmpeg -i input.mp4 -vf scale=1920:1080,setsar=1:1 -c:v libx264 -preset medium -c:a aac -movflags empty_moov+default_base_moof+frag_keyframe output.mp4 -hide_banner
Important is: -movflags empty_moov+default_base_moof+frag_keyframe
This setup also scales the video to 1920x1080 (disregarding any aspect ratio of the input video)
However, based on the comments of the original post, I do believe there might be a more efficient way to generate the blob url and ingest into a video tag. This example was copied straight from https://developer.mozilla.org.
If anyone comes up with a better script (not over-engineered), please post it here.
Thank you #Rudolfs Bundulis for all your help!

video.js loadedalldata firing only once?

The following code sets up video.js and listens on loadedalldata event to start playing and listens on ended event to load another file. If an flv plays first, I get loadedalldata event for loading the flv, then it plays, I get the ended event, the mp4 loads, but I never get the loadedalldata event.
If the mp4 plays first, I get two loadedalldata events, the mp4 plays, I get the ended event, the flv loads, I get the loadedalldata event, the flv plays, I get the ended event, the flv loads again - but I never get the loadedalldata event.
If both vids are mp4, it plays in a loop (with two loadedalldata events each time).
So it seems, something about the flv playing disrupts the next loadedalldata event.
i event tried adding a .on('loadedalldata') event in the ended handler. No change.
Any suggestions??
<html>
<head>
<link type="text/css" href="/js/video.js/video-js.css" rel="stylesheet" />
<script type="text/javascript" src="/js/jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="/js/video.js/video.js"></script>
<script>
videojs.options.flash.swf = "/js/video.js/video-js.swf"
$(document).ready(function () {
var playIt = function playVid() {
alert("Event");
this.play();
}
videojs("video1", {}, function(){
this.on('loadedalldata', playIt);
this.on('ended', function() {
this.src({ type: "video/mp4", src: "/files/test.mp4" });
this.load();
});
this.src({ type: "video/flv", src: "/files/barsandtone.flv" });
this.load();
});
});
</script>
</head>
<body>
<div id="div1">
<video id="video1" class="video-js vjs-default-skin"></video>
</div>
</body>
</html>
It looks like that's a bug in Video.js when playing additional sources through Flash. With Flash, progress events are created manually in javascript as opposed to being able to use the native events like with html5. This line of code turns the events off as soon as the buffer reaches 100%, but then never resets itself on a later source load.
https://github.com/videojs/video.js/blob/ce18a9af740eb2a01f2b0efe2d10299de32818ce/src/js/media/media.js#L192
It should restart these events when the loadstart event is fired again by the flash player, signaling a new source has been loaded. You should submit an issue on the video.js repo for this. https://github.com/videojs/video.js/issues/new

Auto-Redirecting after BigVideo.js video ends

I'm having trouble auto-redirecting after my video has ended using BigVideo.js. Not sure what's wrong here. Not only does this not redirect it completely breaks the player and the video does not play.
<script type="text/javascript">
var BV;
$(function() {
// initialize BigVideo
BV = new $.BigVideo();
BV.init();
BV.show('vids/video.mp4');
BV.getPlayer().on("ended", function() {
window.location = "http://www.google.com";
})
});
</script>
I tested your code locally and the redirection worked without any problems.
I guess it depends on the browser type/version or other environment factor.
Try to properly unload the video element by:
BV.getPlayer().on("ended", function () {
this.pause();
delete(this);
window.location = "http://www.google.com";
});
reference:
How to properly unload/destroy a VIDEO element
hope that will do the trick :)

Hyperlinks in Bing Maps infobox breaks Windows 8 App Navigation State

I have Bing Maps on a page in my WinJS Windows 8 Application.
The Map has a few pins each with its own Infobox. When clicking on the pin it displays the infobox correctly with its content. The content contains a hyperlink that links to a different page in the Windows 8 Application. The app navigates to this page correctly, however the back button stops working and the App Bar can't be accessed either. (Navigating to the page normally works fine)
I think something goes wrong with how the page navigates and how the navigator records the state. I am new to this so it might also just be a stupid question.
Here is the code in the page's .js file:
// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/testBing/testBing.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
Microsoft.Maps.loadModule('Microsoft.Maps.Map', { callback: initMap });
}
});
})();
var pinInfobox = null;
function initMap() {
try {
var mapOptions =
{
credentials: "credentials",
center: new Microsoft.Maps.Location(-33.961176, 22.420985),
mapTypeId: Microsoft.Maps.MapTypeId.road,
zoom: 5
};
var mapDiv = document.querySelector("#mapdiv");
map = new Microsoft.Maps.Map(mapDiv, mapOptions);
centerPosition();
}
catch (e) {
var md = new Windows.UI.Popups.MessageDialog(e.message);
md.showAsync();
}
}
function addPushPin(location) {
map.entities.clear();
var pushpin = new Microsoft.Maps.Pushpin(location, null);
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { title: 'My Pushpin', visible: true, description: "<a href='/pages/player/player.html'>Profile</a>" });
Microsoft.Maps.Events.addHandler(pushpin, 'click', displayInfobox);
Microsoft.Maps.Events.addHandler(map, 'viewchange', hideInfobox);
map.entities.push(pushpin);
map.entities.push(pinInfobox);
}
function hideInfobox(e) {
pinInfobox.setOptions({ visible: false });
}
function centerPosition() {
var geolocator = new Windows.Devices.Geolocation.Geolocator();
geolocator.getGeopositionAsync().then(function (loc) {
var mapCenter = map.getCenter();
mapCenter.latitude = loc.coordinate.latitude;
mapCenter.longitude = loc.coordinate.longitude;
map.setView({ center: mapCenter, zoom: 15 });
addPushPin(mapCenter);
});
}
function displayInfobox(e) {
pinInfobox.setOptions({ title: e.target.Title, innerHTML: e.target.Description, visible: true, offset: new Microsoft.Maps.Point(0, 25) });
pinInfobox.setLocation(e.target.getLocation());
}
The HTML just has the following
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!--Bing Mapps Reference -->
<script type="text/javascript" src="ms-appx:///Bing.Maps.JavaScript//js/veapicore.js"></script>
<link href="testBing.css" rel="stylesheet" />
<script src="testBing.js"></script>
</head>
<body>
<div class="testBing fragment">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back" disabled type="button"></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Welcome to testBing</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<div id="mapdiv"></div>
</section>
</div>
</body>
</html>
The comment by Dominic Hopton is correct: foo.html gets loaded as the whole page instead of as part of your app's navigation process. If the links are supposed to do an app navigation (as opposed to open in an external web browser), you can add this code to your page's ready function to convert the link click into a navigation event.
WinJS.Utilities.query("a").listen("click", function (e) {
e.preventDefault();
nav.navigate(e.target.href);
});
If you have some links that should navigate and some that should open in a browser, you can modify the query. For example, if can can add a CSS class to links that should open in a web browser, you could change the query to:
WinJS.Utilities.query("a:not(.defaultClick)")
You might also be able to modify the query to examine the href attribute of the link to check for "http" like so:
WinJS.Utilities.query("a:not([href^=http])")
I have not tested this last example yet, but if it works as I suspect it would, it would have a links that start with "http" (so including "https") behave normally, while all links that have a relative URL or a package URL will be converted to navigation events.
I don't recommend that you do this blindly, but depending on your app, this simple shortcut might change the behavior to match your expectations.