Hello I'm displaying a youtube video in a div full screen.
It change size on resize window and the most important thing it load on demand and play/pause if it's on the viewport or not.
To control the viewport and lazy loading I'm using viewportchecker
So, ViewportChecker check if the DIV is in the viewport, if YES it start the funcion playPause1, the function will start the video or pause it in case the video is already being played.
$('#Wraptv1').viewportChecker({
callbackFunction: playPause1,
offset: 300,
repeat: true,
});
Everything works very good but sometimes the video is not respecting the startSeconds parameter mostly if the page is loaded when the video DIV is outside the viewport.
In this case the first video should start in the second 30 (as tou can see below in the video parameters) but it starts from the second 0.
video parameters:
var ystv1 = [{
'videoId': 'Gc2en3nHxA4',
'startSeconds': 30,
'endSeconds': 45,
'suggestedQuality': 'hd720'
},{
'videoId': 'Gc2en3nHxA4',
'startSeconds': 65,
'endSeconds': 90,
'suggestedQuality': 'hd720'
}, ],
Here the code example: https://codepen.io/ysanmiguel/pen/WEGwqO
any help or suggestion to fix this problem or improve the code?
thank you very much.
Same scenario is required in this SO post.
Here is the main problem of the user:
For my project I need to be able to control the current time that the
video is playing. I have searched the You-Tube API notes and data but
could not find a parameter nor a function that enables me to set the
current time of the video (There is a GET for the current time but not
a set).
You may also try the answer in this SO post and visit the following documents.
https://developers.google.com/youtube/js_api_reference
https://developers.google.com/youtube/youtube_player_demo
First you need a JS reference to the Player object. For a quick start,
please take a look at the following Question:
How do I get the reference to an existing YouTube player?
With this reference you can do:
player.seekTo(42); //Go to 42 seconds
Thank you for looking at my question. Fiddle is HERE.
I am trying to implement an audio player for many songs on a page. This is using JQueryUI Slider and HTML5 Audio, with one Audio element and multiple sliders.
The problems right now are:
The slider does not animate with the audio.
The slider does not seek to the audio.
previously, when both of the above WERE working, once you chose a spot in the song, the slider would no longer animate.
I have created function to rebindSlider() when a new song is clicked. Inside this function, two things happen: a) the new slider is created, with slide and stop listeners defined, and b) the new slider is bound to the timeupdate event on the audio element for the new song. I feel like this should be all that I need, but the slider does not bind, and an undefined error can be seen when you try to drag the slider.
Using a single slider, and a single audio element, I have gotten this 90% the way there; as soon as I introduced multiple divs for the sliders though, problems started occurring.
Here is the code for rebindSlider:
function rebindSlider(sliderDiv) {
var createSeek = function() {
sliderDiv.slider({
value: 0,
step: 1,
orientation: "horizontal",
range: "min",
max: audioPlayer.duration,
animate: true,
slide: function() {
manualSeek = true;
},
stop: function(e, ui) {
manualSeek = false;
audioPlayer.currentTime = ui.value;
}
});
};
createSeek();
$(audioPlayer).bind('timeupdate', function() {
if (!manualSeek) {
sliderDiv.slider('value', audioPlayer.currentTime);
}
});
}
Further description is below.
There is a list of songs included on the page. Each song has a containing div, within which is an <a> that contains meta data (absent in the fiddle), as well as a div designated for the audio seek slider. There is a single audio element on the page, which has its source re-loaded as you click through the songs.
When a song is clicked, I would like to destroy the sliders bound to the playing audio (if necessary), and bind the new slider for the clicked song to the audio player.
The closest I have gotten was to have the slider 1) begin animating when the song plays 2) dragging of the slider moved to a different position in the song. Once the slider had moved though, it no longer animated. After a refactor, the slider no longer works, and though I could go to a previous commit to get the working code, the refactor was so drastic that I would prefer to present the current, non-working code, as it better represents what I would like to end up with.
Reasoning, and additional information.
I am making a web app, for which I have a concept for an audio player that I would rather build myself than modify anything that I have come across. That being said, if you know of something that I can implement, I would love suggestions.
The idea sounds simple enough, and most of it is done, but there is a very crucial part of it that I am having trouble with, which is setting up the slider to animate with, and seek to the desired spot in the audio track, and to be able to rebind a new slider to the audio when a song is clicked.
There are a few changes needed to get the slider working correctly. I'll cover them each, in order that they apply.
Invalid Slider Max Value
The first issue is that the slider's max value is set to the audioPlayer.duration, which would normally be all well and good, except that the HTML5 audio player loads the audio assets asynchronously. What this means is that even though you might have loaded the audio prior to setting the slider, the audio asset may not be loaded yet, and the audioPlayer.duration may be invalid (likely NaN).
Simply remove the max key (and value) from the slider initialization, and this will work. Et viola! The slider moves!
One caveat: the slider defaults to a max value of 100 units, and the duration of the audio is a little over 25 seconds, so the song finishes playing when the slider is 1/4th of the way along. We can set the max key to 25 (seconds), but that's a little inelegant, and wont work if we change the audio to use a different source.
Set the Slider Max Value
Capturing the audioPlayer.duration must be done be handling an event, once the asynchronous load has completed. Javascript provides such an event: onloadedmetadata. Let's install an event handler, and make this work:
audioPlayer.onloadedmetadata = function() {
$(".slider").slider("option", { max: Math.floor(audioPlayer.duration) });
};
Now, what this does is set the slider's max to the audioPlayer.duration once the audio asset has loaded. Actually, this is currently setting the max value for ALL of the sliders, but that shouldn't be a problem, since they're all hidden. If you have a very large number of songs, there might be a bit of a delay, and you may want to find the specific slider to update.
Smooth Sliding
Now, you may notice after these changes that the slider is somewhat jumpy. It pauses for a second, then jumps, then pauses, etc. This can be fixed very easily, by changing the step key to 0.1 in the slider initialization, like so:
sliderDiv.slider({
value: 0,
step: 0.1,
orientation: "horizontal",
The time updates occur every 50 to 250 milliseconds, but the slider could only move in 1-second increments. Now, with 1/10th of a second increments, the slider will move more smoothly. You can decrease that slightly if you like, but don't make the number too small; 0.01 is the practical lower bound.
Update the End-of-Play State
When the song has finished, the "Play" button is left in play state, even though there's no longer anything playing. There's an event for that, as well: onended. We'll use that event to update the UI, so that the user doesn't get confused:
audioPlayer.onended = function() {
playButton.removeClass('fa-pause-circle-o');
playButton.addClass('fa-play-circle-o');
};
Now, when the song finishes, the Play button will go back to the "play" state, and the user will know that clicking on it will play the song.
Refactor Play Button State
Since there are now 3 places that update the state of the Play button, and this involves duplication, we can refactor the state handling. This function will definitively set the state of the Play button:
function setUIState() {
if (audioPlayer.paused || audioPlayer.ended) {
playButton.removeClass('fa-pause-circle-o');
playButton.addClass('fa-play-circle-o');
} else {
playButton.removeClass('fa-play-circle-o');
playButton.addClass('fa-pause-circle-o');
}
}
Now, calling it from the other functions, you end up with the onended event handler:
audioPlayer.onended = function() {
setUIState();
};
The changeUI function:
function changeUI(selectedSong) {
setUIState();
var sliderDiv = selectedSong.parent().find('.slider');
rebindSlider(sliderDiv);//Bind the desired slider
$('.slider').hide(); //Hide all sliders
sliderDiv.show();//Show only the desired slider
}
And, the Play button click handler:
$(".playButton").click(function() {
if (audioLoaded === true) {
if (!audioPlayer.paused) {
audioPlayer.pause();
} else {
audioPlayer.play();
}
setUIState();
} else {
alert("Please click a song");
}
return false;
});
This makes the UI state management for the button simple to deal with, and keeps the state from creeping out through the app. You can already see how the refactored code is noticeable clearer and will be easier to maintain. Plus, as a bonus, we got to use the cool audioPlayer.ended attribute, which you don't see used much.
But Wait, There's More!
With the changes above, you're well on your way to having a very functional audio player. But that's certainly not the end of the line for feature functionality. There's always room to grow!
I've create a jsFiddle that includes all of these changes, as well as a few other mods to the original code. You can find the most recent version at: https://jsfiddle.net/mgaskill/mp087adp/. Additional features are likely to keep popping up, but the jsFiddle already includes these additional features:
Volume control (slider)
Time display
Dynamically generated HTML for audio controls (keeps the HTML simpler)
I've made a site that randomizes HTML videos or images just to practice my javascript.
I am trying to make it so that each time a video is randomized the URL location will change to represent the new video, this way users would be able to link directly to a video that was randomized.
Currently it only displays a static url that does not change whenever content is loaded.
Here is the obligatory codepen
Codepen
function chooseRandomVideoFromList() {
var i = Math.floor(Math.random() * currentList.length);
var video = currentList[i];
var $video = $('video');
// clear
$video.html('');
// <source src="" type="">
video.sources.forEach(function (source) {
var $source = $('<source>').attr('type', source.type).attr('src', source.src);
$video.append($source);
});
Any help or advice would be greatly appreciated, i've read the documentation and I am still stumped :S
Thanks guys!
You cannot directly write on the window.location.href property, but you may change your sites url with the html5 history api and pushstate.
Example:
history.pushState({}, "Stackoverflow", "http://stackoverflow.com");
This should work in all modern browsers, see: http://caniuse.com/#search=pushstate
More information on this topic could be found here: https://developer.mozilla.org/de/docs/Web/Guide/DOM/Manipulating_the_browser_history
Though keep in mind you need also to listen on popstate events if you want the users to be able to use their browsers back and forward buttons. Also your server side code needs to handle the urls.
If you need to support older browsers or don't want the server side to be involved you could set the window.location.hash property instead which does not change the url itself but let you change the hash part of the current url, for example:
window.location.hash = "uri=stackoverflow.com";
This way you might store the Index of the video currently shown. When loading the page you might want to check if there's a value in "window.location.hash" and if it is a valid index for your videoFiles. If so you should play that video.
Example (insert in your starting code):
if (window.location.hash !== "") {
showSpecificVideoFromList(window.location.hash);
}
And this one in your chooseRandomVideoFromList:
window.location.hash=i;
Then implement your showSpecificVideoFromList in order to show the given index (and check for validity)
Actually this the first time I'm gonna use jplayer plugin, so all I need is to play a sound clip (2 sec) when I click on a div, and I don't know how to use jplayer!
I also need to load the sound clip file in cache as well as the page is loading, so when I click that div the sound clip plays immediately without loading it when clicking
btw, is it possible to do that without using jplayer, jquery maybe?!
If you want to stick with jPlayer, try setting warningAlerts and errorAlerts to true.
$(id).jPlayer( { warningAlerts: true, errorAlerts: true } );
This may solve your problem.
But as long as you only need sound (no video), SoundManager 2 might be a better fit for you. Its really robust and provides extensive debugging output.
soundManager.url = './swf/'; // directory where SM2 .SWFs live
var mySound;
soundManager.onready(function() {
// SM2 has loaded - now you can create and play sounds!
mySound = soundManager.createSound({
id: 'someSound',
url: '/path/to/some.mp3'
});
});
//....
//if(xhr-stuff)
if(mySound)
mySound.play();
Use soundmanager2.js for testing and soundmanager2-nodebug-jsmin.js for production. If you have further questions, don't hesistate to ask.
-snip-
scratch that... there's an api
http://www.jplayer.org/latest/developer-guide/#jPlayer-play
Use
$("#jpId").jPlayer("play");
[EDIT: Sorry to those who already answered -- in my sleep-deprived state, I forgot that this particular situation is a YouTube movie, not the JW FLV player. I can see that there is more extensive documentation on interacting with YouTube movies, so I will pursue that, but any more information is also welcome]
I am using embedded YouTube videos in a collection of divs that are being rotated by using the jQuery cycle plugin (http://malsup.com/jquery/cycle/).
I would like the cycle to stop when I click on one of the movies to start it playing, but I can't figure out how to attach a jQuery event handler to the player object.
Here's what my current code looks like (you can't directly select an object tag with jQuery, so I select the parent div and then get the object element as the first child):
$("div.feature-player").children(":first").click(function(event) {
$('#features').cycle('stop');
});
But that doesn't do the trick. I'm not a Flash author, so I'm not really familiar with ActionScript, and I've never set up an interaction between JavaScript and a Flash movie before.
The YouTube player API is pretty straight-forward. You just have to listen to the onStateChange event and control the cycle plugin depending on the state:
Here's a working demo: http://jsbin.com/izolo (Editable via http://jsbin.com/izolo/edit)
And the pertinent code:
function handlePlayerStateChange (state) {
switch (state) {
case 1:
case 3:
// Video has begun playing/buffering
videoContainer.cycle('pause');
break;
case 2:
case 0:
// Video has been paused/ended
videoContainer.cycle('resume');
break;
}
}
function onYouTubePlayerReady(id){
var player = $('#' + id)[0];
if (player.addEventListener) {
player.addEventListener('onStateChange', 'handlePlayerStateChange');
}
else {
player.attachEvent('onStateChange', 'handlePlayerStateChange');
}
}
Flash movies are pretty much black boxes as far as javascript is concerned. If the SWF you're using wasn't written to interact with javascript then you're probably out of luck.
You'll either need to figure out what javascript methods the movie you're using exposes (hopefully it has documentation), find another one that does provide javascript interaction, or write your own SWF to handle it.
What you're looking for is the flash ExternalInterface class, which is used for communication from flash to javascript and from javascript to flash.
If you're embedding the player using swfobject you're going to want to use swfobject.getObjectById to get a reference to the movie. Read the docs to see why you need to do this.
Also you'll need to set {wmode:"transparent"} for the player in order for it to bubble up click events to JavaScript.