Play event is going to infinite loop in videojs - javascript

I just did a small example of videojs, which has a log on event play, and i am using APIs like play(),pause().
var myplayer;
var playCount = 0;
videojs("example_video_1").ready(function(){
myplayer = this;
myplayer.on("play", function(){
playCount++;
$("#count").text(playCount)
});
});
$("#test").click(function (){
myplayer.pause();
myplayer.play();
});
The issue is that while executing the APIs the play event will go to an infinite loop.
I can found this issue in touch devices if I enable the controls even while seeking the bar, do play pause etc. So if I didnt use the combination also I can found this issues.
Internally the library is using these APIs in seek, or other controls ?
Link in jsfiddle LIVE BUG:

This is a bug in video js event handling:
https://github.com/videojs/video.js/issues/573 <-- original bug
https://github.com/videojs/video.js/issues/620 <-- best info on 'why' here
In the meantime, one workaround is to put any play/pause toggles in timeouts.
$("#test").click(function (){
myplayer.pause();
window.setTimeout(function() {myplayer.play();}, 10);
});

This is the fix forthis issue...
https://github.com/cameront/video.js/commit/ff0b443c285691074f7f01e8d0326ade0f0a6609 for issues/620

Related

How do I make sure all resources are loaded before running a function?

I'm working on a music webapp that plays a random sequence of notes, but I ran into this issue: whenever it was the case that I was going to press play for the first time after the page loaded, the sequence would "choke" before getting on track. I thought maybe that was because the resources are not yet loaded when I press play for the very first time. I guess I was right, did some research, found this preload = auto thing, which seemed to solve this problem. At least, if you refresh or visit the page for the first time and press play immediately, it works just fine. However, if you don't do anything for a while, like 2/3 minutes, the same thing happens. There's a delayed start, as if it's loading the file, and then it awkwardly speeds up like it's trying to catch up with the setInterval timer. I wrote this very simplified version of the code just to illustrate:
<button>Play</button>
<audio src="source1.mp3"></audio>
<audio src="source2.mp3"></audio>
<audio src="source3.mp3"></audio>
<script>
let notes = []
document.querySelectorAll("audio").forEach(function(note){
notes.push(note)
})
function play(){
let random_index = Math.floor(Math.random() * 3),
note = notes[random_index]
note.play()
setInterval(function(){
note.pause()
note.currentTime = 0
play()
}, 500)
}
let button = document.querySelector("button")
button.addEventListener("click", function(){
play()
})
</script>
So my question is how do I solve this? Is there anyway to tell the function to hold until it can actually play the first file? Maybe a DOM event that fires when the resource is buffered and ready? I feel like I can't relly let the timer begin until I have a way to check that, otherwise it will go crazy as usual. Any ideas will be greatly appreciated!
The load event is called after the page is fully loaded:
window.addEventListener("load", function(){
// Your code
});
The DOMContentLoaded event is called after the DOM is loaded but before css and img.
document.addEventListener("DOMContentLoaded", function(){
// Your code
});

Play() Causes distortion/echo when playing sound

I am trying to make a chrome extension. Right now I have these codes:
<button style="text-align:center; margin-bottom: 5px;" id="myboobutton">DogMeme.avi</button>
<script type="text/javascript" src="popup.js"></script>
The html that will be the button that plays a sound
I am making a button and giving it an id so it can call a Javascript file to play a sound (I have to do this because you can't run JS on the HTML of a chrome extension.)
The button has an ID of 'myboobutton'
function myboo() {
var heyboosong = new Audio();
heyboosong.src = "myboo.mp3";
heyboosong.volume=0.5
heyboosong.play();
}
document.getElementById('myboobutton').addEventListener('click', myboo);
The button calls this popup.js so it can play the audio file.
I have a soundboard extension that plays various songs that are mp3s. When they play in the chrome extension they sound echoey. When the individual audio files play they sound fine. I suspect that it is making multiple calls to the function resulting in the echo. I am trying to figure out how to fix it. (thanks Makyen for helping to clarify) I've tested again and it still makes it.
It seems like all mp3 sounds seem to do this. Not sure if it is specific to chrome extensions or not. But it doesn't seem to happen on faster PCs as much. I am new to coding, I have just learned all of this in the past week. Thanks a bunch!
Here is the unpacked extension
https://drive.google.com/drive/folders/0B3AU3p8wyWK3YXo1YUlGWGg5RGs?usp=sharing
You can disable the button in the click event and create a setTimeout() function to enable the button again after a certain period of time.
For example:
var mybooBtn = document.getElementById('myboobutton');
mybooBtn.addEventListener('click', function() {
mybooBtn.disabled = true;
setTimeout(function() {
mybooBtn.disabled = false;
}, 1000);
// code to play sound goes here
});
Here's a fiddle: https://jsfiddle.net/g9wx30qj/
You need to apply the debounce/throttle concept. It is meant to be used when a function needs a delay between executions (i.e. ajax calls in typeahead plugins).
You can use a simple Throttle implementation:
var Throttle = function(fn, time) {
var flag = true, toId;
return function() {
if (flag) {
var args = arguments;
fn.apply(this, args);
flag = false;
clearTimeout(toId);
toId = setTimeout(function() {
flag = true;
}, time);
}
}
};
And then, in your code:
document.getElementById('myboobutton').addEventListener('click', Throttle(myboo,1000)); //1000ms is 1second
Ok,do one thing;(I am showing a solution using jQuery)
$("#myboobutton").click(function(){
$("#myboobutton").css("pointer-events","none"); //click 'll be disabled by this
//write code for playing sound;
setTimeout(function(){
$("#myboobutton").css("pointer-events",""); //button 'll be clickable again after 1 sec
},1000)
})

Mute <audio> sound with JavaScript on page focus

I have the following code that should mute audio when window is focused, but I must have done something wrong since it doesn't mute at all;
script
$(function() {
$(window).focus(function() {
console.log('Focus');
/*getElementById('notificationsound').muted = true;*/
$("#notificationsound").prop('muted', true); //mute
});
$(window).blur(function() {
console.log('Blur');
});
});
html
<audio id="notificationsound" src="sound/notify.mp3" preload="auto"></audio>
The goal is for the notification sound to be played only when the page is not viewed / out of focus (I'm using this "script structure" since it's likely I'll add more to the different states later on).
I know I'm missing something very basic since I'm a beginner, and since it logs focus/blur in the console correctly. Also – I know this most likely is a very similar question to others asked here before, but I could only find rather aged answers (which my code is based upon) so if this is not the "modern" or best practice anymore I'd love examples of alternate methods.
Examples are very much appreciated in case of major change is needed or suggested.
Try $("#notificationsound").prop('muted', true); - you missed the '#' which is the Id selector in JQuery.
$("#notificationsound").stop();
or
$("#notificationsound").pause();
$("#notificationsound").currentTime = 0;
Or even use JS:
var audio = new Audio('example.mp3');
which allows such functions:
audio.currentTime=1;
audio.play();
audio.stop();
audio.pause();
and even:
audio.volume = 0.5 //half

Checking for end of video on iPad

I can't seem to listen for onended on a video on iPad(Safari)...I want to remove a class that I was able to add when the play button was pressed, but I can't seem to track down when the video ends (works well every where else including iphone, just need it for iPad/Safari)
link here: http://www.artandseek.net/meyerson/tour/
code snippet here
$(".playBtn").click(function(){
var thisVideo = $(this).prevAll(".img-wrap").children(".togglePlay").get(0);
thisVideo.onended = function(e) {
$(this).fadeOut().parent(".img-wrap").removeClass("playing");
$(this).parent().next("h2").fadeIn();
classie.remove( thisVideo, 'tabletActive');
}; ...
I was able to find the answer here:
Bind Play/Pause/Ended functions to HTML5 video using jQuery
using this:$(thisVideo).bind('ended', function () {
console.log('working');
});

Stopping instead of rewinding at the end of a video in MediaElement.js

I'm wondering how to stop the MediaElement.js player at the end of the video. I wondered how to stop the mediaelement.js player at the end of a video. I was hoping to hold on the last frame and not rewind to show the first frame as it does now.
Is it possible to change this behaviour?
I wrote a fix for this problem and John merged in version 2.10.2.
There is now an option "autoRewind" that you can set to false to prevent the player from going back to the beginning.
The eventlistener is not added and there is no more need to remove it.
$('video').mediaelementplayer({
autoRewind: false
});
I believe that the default behavior of the <video> element is to go back to the beginning so you'd just need to override this by listening for the ended event.
var player = $('#myvideo').mediaelementplayer();
player.media.addEventListener('ended', function(e) {
player.media.setCurrentTime(player.media.duration);
}, false);
Hope that helps!
Probably the best solution is not to be afraid and remove the "rewind-to-start-on-video-end" handler from mediaelement source.
If you go into the source code for mediaelement and search for "ended", you'll eventually see, that rewinding after reaching end of the video is actually done deliberately by mediaelement.
If you want to remove that functionality feel free to just remove that handler for "ended" event from mediaelement source. That solves all the problems, including flickering between last and first frame, mentioned in some other answers to this question.
The code in John Dyer's answer didn't really work for me either for some reason. I was however able to get this version working...
var videoPlayer = new MediaElementPlayer('#homepage-player', {
loop: false,
features:[],
enablePluginDebug: false,
plugins: ['flash','silverlight'],
pluginPath: '/js/mediaelement/',
flashName: 'flashmediaelement.swf',
silverlightName: 'silverlightmediaelement.xap',
success: function (mediaElement, domObject) {
// add event listener
mediaElement.addEventListener('ended', function(e) {
mediaElement.pause();
mediaElement.setCurrentTime(mediaElement.duration);
}, false);
},
error: function () {
}
});
videoPlayer.play();
The only problem I'm having - which is very frustrating, is it is flickering between the LAST and FIRST frames in Chrome. Otherwise, it works as expected in Firefox and IE...
This problem i faced when playing audio files
The problem is in the play, when you pause your player the file will stop but before resuming you have to decrease the current time of the player by any value in your case you may decrease it by a frame maybe
after setting your source ,loading your file and pausing, then
myplayer.player.play();
var currentTime = myplayer.player.getCurrentTime();
myplayer.player.setCurrentTime(currentTime-0.1);
myplayer.player.setCurrentRail();

Categories