How to get videojs to unload automatically - javascript

I'm currently using VideoJS in a Rails application (where there is a video player on every page) to display videos and I'm encountering a very strange problem:
The player works perfectly fine on the first page I visit but if I play the video and visit another page, the video from the first page keeps playing in the background even though the page isn't open anymore (you can hear the audio) and the video on the page you visited doesn't initialize properly (options aren't applied which means the video can't be played because controls are an option) and the console reads VIDEOJS: WARN: Player "player" is already initialised. Options will not be applied.
How to I get VideoJS to unload itself when the user leaves the page and why does it keep playing in the first place, the HTML5 video player didn't do that before.
Is the best way around this to get VideoJS to reload itself manually on page load? If so, how can that be done?
Note: If I navigate to any other page within the website the videos continue to not initialize, but if I reload the page, any page, the video on said page works again.
Note 2: Turns out that the onbeforeunload javascript event doesn't even fire if I click a link to another page, it only fires if you're going to a whole different website, so I can't even use that to .dispose() VideoJS on page unload.
Note 3: .reset() doesn't seem to be working either.

You can check to see if the player already exists and unload it, then reload it.
I was actually able to figure out a fairly simple and elegant solution:
if (player) {player.dispose()} else {var player}
player = videojs('player', {
//options
});
First it checks to see if the player exists. If it does, it destroys the VideoJS instance. If it doesn't, it creates the variable. Then it initializes the player.

By Referring this issue : https://github.com/videojs/video.js/issues/2904
We can re-write the above solution to something like this:
const playerId = 'video-player';
const videoOptions = {
controls: true,
sources: [{
src: 'test-file.mp4',
type: 'video/mp4',
}]
};
let player;
let players = videojs.players;
const imaOptions = { adTagUrl };
if (players && Object.keys(players).length) {
player = players[playerId];
player.dispose();
}
player = videojs(playerId,videoOptions);
player.ima(imaOptions);

I found this one to be the solution:
var oldPlayer = document.getElementById('my-player');
videojs(oldPlayer).dispose();
it's in the docs actually

Related

Detect if i'm allowed to play video on hover

We have a dynamic element on the page that in certain situations will have a video (Vimeo). The jQuery code checks if the element excists and adds video itself and the play on hover.
This works (tested on Chrome & Firefox) after you have interacted with the website. Before you interact, you run into the autoplay policies, a good thing in my opinion, and the console will tell you the action is not allowed.
You might get around this with muting the video. But the contents are about a person explaining something. So without the sound it loses a lot of its value. So would like to keep that in.
As said, these policies are a good thing in my opinion, so I do not want a way around it or a way to trick it into playing anyway. I would like to add some other functionality when the site is in this 'state'(?). Add a button or some other incentive to interact with the site and play the video. But if not in this 'state' I would like to keep the play on hover.
Is there a way I can detect this state?
I see another question, almost the same issue: Is there an event to detect when user interacted with a page?
But the solutions there are not answers to the problem, like trying it with an interval until it works... creative, but not something I'm looking for.
Here is in short what I have now. And what is missing.
...video settings...
if ($('#vidcontainer').length) {
var videoPlayer = new Vimeo.Player('vidcontainer', options);
...
if state is 'allow hover' {
...
$("#vidcontainer").mouseover(function () {
videoPlayer.play();
}).mouseout(function () {
videoPlayer.pause();
});
...
} else if state is 'not allowd hover' {
... do something else ...
}
...
}

How to play live video on page load?

I have a javascript code that checks whether there are some people connected to a room in Twilio Programmable Video. If there are any participants, the javascript adds their remote video to the webpage.
// A function that adds a remote participant audio & video to the current web page.
function AddParticipantAudioAndVideo(participant) {
participant.tracks.forEach(publication => {
if (publication.track) {
document.getElementById("some html item").appendChild(track.attach());
console.log("track subscribed");
}
});
participant.on('trackSubscribed', track => {
document.getElementById("some html item").appendChild(track.attach());
console.log('track subscribed');
});
}
function InitializeRoom() {
// room is defined somewhere else
room.on('participantConnected', participant => {
console.log('A remote Participant connected : ' + participant.identity);
AddParticipantAudioAndVideo(participant);
});
// Loop over all the participants already connected to the room
room.participants.forEach(participant => {AddParticipantAudioAndVideo(participant)});
}
If I call this code from a button click for example, it works and live video plays properly :
<div onclick="InitializeRoom()">My Button</div>
However if I call the exact same code from the page load event handler (before any manual interaction with the page), it doesn't work and the video tag is not added to the html document.
window.addEventListener("load",function(event){
InitializeRoom();
});
I know that Chrome doesn't like videos with audio and autoplay = true. So I was wondering if this problem is due to the same reason and if there is any solution to that.
Thanks
Cheers,
I know that Chrome doesn't like videos with audio and autoplay = true. So I was wondering if this problem is due to the same reason and if there is any solution to that.
Yes, exactly.
Based on your other questions, I assume you're wanting to do this in some automated context where you have control over the browser. If so, you can add a flag to the Chrome/Chromium command line:
chrome.exe --autoplay-policy=no-user-gesture-required
See also: https://developer.chrome.com/blog/autoplay/#developer-switches

Stopping a dynamically created Soundcloud oEmbed player when closing a modal

I am working on a webapp that allows people to share links from Soundcloud by copying and pasting the URL. Then the webapp generates a running list of people, allowing users to open a modal that loads the a Soundcloud player (via SC.oEmbed). The URL is derived from the element that opens up the modal. So SC.oEmbed opens up the URL found within the href attribute.
I have everything working great, except that when the modal is closed the music keeps playing.
There doesn't seem to be a stop() or pause() function associated with this player like there is with the Widget player. The only solution I have found is upon close to have SC.oEmbed open up another random soundcloud link but with auto_play off. This works but seems really inelegant and a waste of resources. There must be a better way no? Oh, and I'm using Twitter Bootstrap too.
Here's my jQuery code:
$(document).ready( function() {
SC.initialize({
client_id: "xxxxxxxxxxxxxxxxxx",
});
$("a[data-target='#myModal']").click(function(event) {
event.preventDefault(); /* makes sure <a> link doesn't actually open new window */
var url = this.href; // gets Soundcloud URL from href in <a> element
SC.oEmbed(url, { auto_play: false }, document.getElementById("audio_1_body"));
});
/* this part below is what I want to improve -- loading up a random track, just to stop playing of track that was loaded in the modal */
$("#myModal").on("hidden.bs.modal", function(){
url = "https://soundcloud.com/the-deep-dark-woods/sugar-mama-1";
SC.oEmbed(url, { auto_play: false }, document.getElementById("audio_1_body")); //this last part is what I want to improve
});
Does not seem that there is a way to do so from SC JS SDK.
Best you can do is to delete SC iframe:
$('#audio_1_body').html('')

Unable to reset HTML video on iPhone to start from the beginning

Using a shared video object I'm loading and playing different source movies dynamically. Resetting the current time like this works fine on the desktop;
$('video').bind('loadeddata', function () {
var video = document.getElementById('video');
video.currentTime = 0;
});
...but while QT is playing on the iPhone the newly loaded movie continues from the previous position of the play head. I tried using "loadedmetadata" also without success. Is there another way to restart the QT player?

Preloading HTML5 Audio in Mobile Safari

I'm having a problem preloading HTML5 audio content and then using what I have in cache rather than attempting to redownload the audio every time I try to replay it.
http://cs.sandbox.millennialmedia.com/~tkirchner/rich/K/kungFuPanda2_tj/
The experience is suppose to be that when someone clicks on the banner, it pops up an ad with a loading bar. THe loading bar is loading all the images necessary for the animation. In the meantime, the audio is also getting loaded via audio tags already on in the DOM (which is fine). After all the images are loaded, the loading bar disappears and the user can continue on. There are 4 buttons on the bottom of the screen that they can click. Clicking one of them plays the audio file and images do a flipbook-style animation thats synced to the audio.
Audio Tags:
<audio id="mmviperTrack" src='tigress.mp3'></audio>
<audio id="mmmantisTrack" src='viper.mp3'></audio>
<audio id="mmtigressTrack" src='kungfu3.mp3'></audio>
<audio id="mmcraneTrack" src='crane.wav'></audio>
Play Button Event Listeners:
button.addEventListener('click',function(){
if ( f.playing ) return false;
f.playing = true;
button.audio.play();
},false);
button.audio.addEventListener('playing', function(){
animate();
}, false);
The problem is, in javascript, everytime I click play(), it reloads the audio file and then plays it. I can't seem to get it to load the audio once in the beginning and go off of whats stored in memory rather than try to reload the audio every single time I click the button.
I've tried experimenting with the preload and autobuffer properties, but it seems that mobile safari ignores those properties, because no matter what I set them too, the behavior is always the same. I've tried experimenting with source tags and different file formats... nothing.
Any ideas?
Alright, so the solution was a bit of a hack, cheat, workaround, whatever you want to call it.
What I noticed is that if I hit the play button on an audio file that I just played, it doesn't reload itself. It could be because I paused the audio after it finished playing through, but I'm not 100% sure on that. In any case, what I did is I combined all 4 audio files into one large audio file (yay Audacity~!). Then, every time I hit one of the play buttons I would set the currentTime property of the audio object to whatever the starting point of that track and then play the track until it hit its ending point, and then pause it again. Mission accomplished! Loaded once in the beginning and never again for each play.
Not crazy about the idea that I had to combine all the different audio tracks, but hey it works.
Oh, also. To get the audio track to load and fire a "canplaythrough" event, I attached this function to a user click event:
var track;
function addHTMLAudio() {
track = document.createElement('audio');
track.id = 'mm_audio'
track.autoplay = false;
track.preload = false;
track.addEventListener('canplaythrough',function(){
track.removeEventListener('canplaythrough');
audioLoaded = true;
},false);
document.getElementById('body').appendChild(track);
track.src = f.trackURL;
track.play();
setTimeout(function(){ track.pause(); },1);
}
playButton.addEventListener('click',function(e){
if ( playStatus > 0 ) return;
playStatus = 1;
var myId = e.target.parentNode.id;
var myClip = findClip( myId );
myClip.state = 'active';
track.currentTime = myClip.tIndex.start;
track.play();
runAnimation(myClip);
},false);

Categories