How to get the progress event working with jplayer - javascript

I am using jQuery 1.5 and jPlayer 2.0.0, please ignore the fact that this is going to auto play music, I am going to supply enough warning before it starts, the user has to press a big button to initiate the page and I will provide a big STOP button.
I would like the audio file to begin playing and a function be called after the page is ready and the audio is loaded.
I have the following javascript (I have modified the code so it can be understood better).
function FemeMusic() {
FemeMusic.prototype.addMusic = function(actionAfterMusic) {
$("#jp").jPlayer({
ready: function() {
var jPlayerElement = $(this);
jPlayerElement.jPlayer('setMedia', {
mp3: 'aSongByJamesBlunt.mp3'
});
jPlayerElement.bind($.jPlayer.event.progress,
function(event) {
if (event.jPlayer.status.seekPercent === 100) {
jPlayerElement.jPlayer("play");
}
if (actionAfterMusic) {
actionAfterMusic.call();
}
});
},
swfPath: "/flash",
preload: "auto"
});
}
}
I have this function to trigger the above code.
$(document).ready(function() {
var femeMusic = new FemeMusic();
femeMusic.addMusic(killMyself);
});
I was using the same code but with the $.jPlayer.event.loadeddata event without the if statement instead of $.jPlayer.event.progress and it worked fine in some browsers but isn't compatible when it comes to using flash because it doesn't fire the event (Also I had a problem with it in firefox 3.5 but I don't know why). The above seems to work in Firefox
I read this
"I suggest you use the progress event instead and check that the:
event.jPlayer.status.seekPercent === 100. "
On this post http://groups.google.com/group/jplayer/browse_thread/thread/9dc9736f9d6947bd?pli=1 by the creator
Any one got any suggestions?
Edit
Having not got this working in chrome and safari I tested this on a new version 3.6 of Firefox (which I should have done in the first place) and it worked as expected, despite the fact that in the documentation event.progress id described as:
A robust jPlayer event supported by Flash and HTML5 browsers
and in the link above the creator suggests to use event.progress to get round browser problems I can only assume it's a browser specific issue.
Would be nice to get some clarification on this though.

From the creator of jPlayer:
So your goal here is to auto-play AFTER the media is buffered?
If you want the short answer. Forget it. x-browser buffering is a mine
field. Some simply ignore it as you have found. Just setMedia and play it.
If you really want to try and do it. Then a play then pause would help,
since a media.play() is better x-browser than a media.load() i.e. its
operation varies less. The iOS Safari would ignore the play completely
though. The user would need to click on something that starts the
operation i.e. a play button.
That last point applies to trying any form of autoplay, so ensure that there
is a play button available. The jPlayer interface will cope with iOS not
playing through feedback from the browser events i.e. stalled.

I had problems with the progress event with flash and html5 backend in most browsers. as far as I can see the timeupdate event is working much better.

Related

Facebook embedded video not playing on click

I'm facing problem with facebook video embedded on my post. My client wanted me to follow this method: https://medium.com/#BenBillups/facebook-video-embeds-that-actually-work-57037f8cdcf3
I've done all of the part except PHP code because that wasn't required by my client. Now what is happening. When page loads a play button appear to start video. On click it work just fine. It plays the video but only on desktops. The click event triggers on mobiles and tablets. But it doesn't start the video.
Please take a look at https://candylish.com/mix-and-match-swirl-cookies/ and also check in mobile. You'll see the difference.
In short, you've to click twice in mobile to start video.
Please help me sort this out.
Thanks :)
I think you are simply dealing with mobile browser's general reluctance to start playing video, when they can't determine it was directly connected to a user interaction (and therefor likely willingly triggered by the user.)
//Autoplay
FB.Event.subscribe('xfbml.ready', function(msg) {
if (msg.type === 'video') {
msg.instance.play();
}
});
This code waits for one of the SDK's events to fire and then tries to call the play method, introducing exactly the kind of asynchronism/detachment that gets this blocked, because techniques like that are often used in a malicious way.
In short, you've to click twice in mobile to start video.
That second click is "a whole different animal" altogether ... it happens on the native play button of the (now) embedded social plugin. The other script is not involved at all any more at this point, and this click is a direct user interaction that triggers the video to play, so it is allowed to work. This isn't nested into anything asynchronous or callbacks, it is straight up click => trigger play.
I don't think you will find any example using this technique where this will work differently.
Mobile browsers are more gracious when it comes to autoplay-on-page-load(!) videos, if those videos do not contain an audio track or are embedded to be muted by default. I don't think Facebook offers the latter as an option for mobile to begin with (the data-autoplay attribute does that for desktop, but is documented to not work on mobile) - so at most you could try with a Facebook video that is silent to begin with; but apart from that I'm not sure this restriction resp. when it actually gets lifted even applies here, it's probably not going to fulfill your client's requirement either.
I started typing this as a comment, but besides that it has gotten a little longer now, in this case I think it can't be done actually simply is the answer, even if it might not be a satisfying one.

VideoJS - Safari 7.1, loading spinner does not go away on initial page load

I'm implementing a video player using VideoJS. Two key functions of this video player are:
a) If the user leaves the page, resume the video at that point when they come back or on refresh
b) Include HLS (h.264/mp4) support to provide better video quality depending on the connection.
The API for saving and retrieving a user's timestamp is already in place, and using the excellent HLS plugin, the video player works almost fine in all browsers as expected. The following code is used to initialize the player and jump to the saved time:
videojs.options.flash.swf = '../video-js/video-js.swf';
var player = videojs(videoId);
supportHLS = videojs.Hls.isSupported();
player.ready(function() {
[[event listeners for media controls]]
this.on('seeked', function() { console.log('seeked');});
this.on('seeking',function() { console.log('seeking');});
var PLAYER_LOADED = 'loadedmetadata';
if(!supportHLS) { PLAYER_LOADED = 'canplay';}
this.one(PLAYER_LOADED, function() {
this.one('canplay', function() {
this.play();
});
this.currentTime(savedPosition);
lastViewed = savedPosition;
});
});
(Reason for the roundabout logic: Chrome had issues with playing the video before the new data (after the seek) had loaded, which caused a number of problems with the data in the buffer. Also, Safari 7.1 would break if you tried this during the 'loadedmetadata' event)
However, there's still one problem, specific to Safari. The loading spinner doesn't always go away when you refresh the page. Examining the logs and listeners seems to indicate that the 'seeking' and 'seeked' events fire at about the same time, but in different orders; the problem always arises whenever 'seeked' fires first, and never occurs when 'seeking' is first. Furthermore, any seeking after the video is playing removes the spinner, so it has to be caused by the initial seek.
It's interesting that Safari supports HLS streaming natively, yet consistently causes the most problems with this player implementation. This is the last Safari bug to iron out, but though it's small it still has a negative impact on user experience.
What causes Safari to fire the 'seeked' and 'seeking' events out of order like this? What can I do to work around it, or is there a cleaner solution for what I'm trying to accomplish?

play a video in reverse using HTML5 video element

I am working on a functionality explained below-
Once a video is loaded/with a button click, it has to play in reverse. The target devices are smart phones and tablet devices. I am trying to do this using HTML5 tag and read about the playBackRate attribute. Further down, I am using the HTML5 stuff to generate my mobile apps using Phonegap.
Here's a link I found interesting but partially working -
http://www.w3.org/2010/05/video/mediaevents.html
The playbackrate, when changed doesn't do anything except it pushes the video back, by whatever number is given there.
I read it here that when playBackRate is set to -1, the reverse playback should happen.
I am not clear on how to exactly implement this. Does the playbackrate actually do this reversing? or should I opt on doing something else?
NEW LINE HERE:
I am almost there.. found a working example here. But this is not working when I am trying it on my system. I am not sure where I am making it wrong.
This is an old thread so I'm not sure how useful the following will be.
The Mozilla developer notes point out that:
Negative values [for playbackRate] don't currently play the media backwards.
Same goes for Chrome, but Safari on Mac works.
This page from w3c is great at observing and understanding events:
http://www.w3.org/2010/05/video/mediaevents.html
I took the jsfiddle you mentioned and added some extra controls for fast forward/rewind speeds:
http://jsfiddle.net/uvLgbqoa/
However, though this works fine for me with Chrome/Firefox/Safari, I should point out that it doesn't really address your key questions.
Firstly, the approach assumes that negative playback rates don't work (which at the time I write this, is largely true AFAICS). Instead, it fakes it by calculating and setting the current time in the video:
function rewind(rewindSpeed) {
clearInterval(intervalRewind);
var startSystemTime = new Date().getTime();
var startVideoTime = video.currentTime;
intervalRewind = setInterval(function(){
video.playbackRate = 1.0;
if(video.currentTime == 0){
clearInterval(intervalRewind);
video.pause();
} else {
var elapsed = new Date().getTime()-startSystemTime;
log.textContent='Rewind Elapsed: '+elapsed.toFixed(3);
video.currentTime = Math.max(startVideoTime - elapsed*rewindSpeed/1000.0, 0);
}
}, 30);
}
Chrome handles this quite seamlessly, even playing snippets of audio as it goes.
Secondly, I think you want to play the video in reverse as soon as the page loads. I can't imagine a use case for this, but the first issue I see is that the whole video will need to be downloaded prior to playback, so you'll need to wait - but download probably won't happen until you start playing. So you could set the currentTime to near the end and wait for the canPlay event, and then start playing in reverse. Even then, this seems very awkward.
I think there are these broad options:
Use a native video widget rather than HTML. I'm guessing (without checking) that the native API supports reverse playback.
Generate a proper reversed video and play it as normal. For example, on a server somewhere use a program like ffmpeg to reverse the video. Then your app downloads the video and plays it normally, which looks to the user like reverse.
Assuming it really does make sense to have an application that plays a video in reverse when you load it, then I'd personally go for #2.

iOS 6 js events function not called if has setTimeout in it

I noticed this strange behaviour with the latest iOS (iOS 6). If calling a function for any touch event which has a setTimeout inside, the part inside the setTimeout is never triggered.
This happens only when there is a "system animation" such as scroll and zoom-in/out.
For example:
http://jsfiddle.net/p4SdL/2/
(I used jquery just for testing but the same happens with pure js)
Open that page with safari on any iOS 6 device and zoom in or out. The alert will never be called.
If tested on any iOS 5 device this will work just fine! It seems that during these animations the setTimeout or setInterval are reset by the OS. Is this the intended behaviour or a bug?
Thanks
Note: It looks like UIWebView does not support requestAnimationFrames. Thanks to Guillaume Gendre for pointing it out!
We ran into a similar issue with a web app we're working on.
For us, it was touchmove that caused issues. We implemented a workaround (found here: https://gist.github.com/3755461) that seemed to work pretty well until another issue forced us to abandon it. (I tried adding the workaround to your fiddle and was able to get the timer to fire once or twice, but it required a weird gesture+scroll event that was damn near impossible to consistently reproduce.)
Anyway, one of the new features in iOS 6 for developers are requestAnimationFrames. My workaround is basically a wrapper for timers, allowing the developer to pass a boolean, which will call either the native function or the workaround function.
For example:
setTimeout(function(){alert("HI")}, 1000); // using native
setTimeout(function(){alert("HI")}, 1000, true); // using workaround
Here are additional ways to use the workaround:
setInterval(function(){console.log("Interval")}, 1000, true);
var timer = setTimeout(function(){ /* ... */ }, 60000, true);
clearTimeout(timer);
var interval = setInterval(someFunc, 10000, true);
if(someCondition) clearInterval(interval);
Here are two fiddles with the workaround examples. Try pinch/zooming on the black squares:
http://jsfiddle.net/xKh5m/embedded/result (Uses native setTimeout function)
http://jsfiddle.net/ujxE3/embedded/result
We've been using this workaround for a few months in a production environment, and have not run into any major issues.
Here's a public gist of the workaround: https://gist.github.com/4180482
Here's more information about requestAnimationFrames:
MDN documentation
Paul Irish on requestAnimationFrame
Good luck!

Opera: Detecting back, forward, refresh and close events

I'm currently working on a jQuery plugin that tracks a visitors mouse behavior. Movements, clicks, scrolling and resizing are all recorded and sent, via Ajax, to a location where this data is parsed and stored.
Originally, the data is sent to a script when the user leaves the page. By 'leaves' I'm referring to refreshing, going back and forth though history, closing the window/tab and going to a different address.
The solution works in all browsers EXCEPT for Opera. I'm using jQuery's 'unload' event which isn't supported by Opera at all. Neither is onbeforeunload or onunload.
The question is, how do I implement this kind of functionality for Opera browsers?
One solution I had was to make special use of a 'polling' feature I created. This feature allows you to specify an interval which pushes the content to the server every 'x' seconds. Setting this to 1 second specifically for Opera browsers would probably solve this issue, but it's an awful amount of overhead and the requests aren't always completed in sequence, etc ...
Any suggestions or am I only stuck with the above option?
Thanks!
I suppose I could just link you guys to the plugin source. http://www.thedrunkenepic.com/junk/jquery.mousalytics.js
Regarding the code linked above, adding:
if(window.opera)
{
options.interval = 1;
}
On line 89 works great. My only concern is overhead, so I'm still looking for a more elegant solution.
According to http://bytes.com/topic/javascript/insights/799229-browser-quirk-onload-onunload-do-not-fire-back-forward-refresh-opera, Opera never really fires onload / onunload events, so functionality like this isn't possible without hacks.
http://dev.opera.com/articles/view/efficient-javascript/?page=4 seems to confirm this, and basically states that opera tries to maintain the state of the page across requests.
On further investgation, http://unitehowto.com/Onunload indicates that it might be possible with opera.io.webserver.addEventListener('_close', onunload, false); (where onunload is a previously defined function), however it also indicates that this functionality is not consistent across all versions of opera, and might not work at all.
I think that your best option is probably to use the polling option for Opera, or possibly use a server-side check for the current page and where it falls in the history queue.
Does adding this line of JavaScript work for you?
history.navigationMode = 'compatible';
Source: http://www.opera.com/support/kb/view/827/
I've had the same problem and this saved my day:
if( typeof(opera) != 'undefined' )
{
opera.setOverrideHistoryNavigationMode( 'compatible' );
history.navigationMode = 'compatible';
}
More info about this problem can be found at: http://www.opera.com/support/kb/view/827/

Categories