I'm using YouTube's API for embedded videos. I use the exact same API code for every video on every page. But on one particular video, it loads with subtitles, but only for the first run. Hit refresh and the subtitles disappear. Clear cache and cookies and they're back.
Why is this behavior manifesting for one video, but not any of the others that share the same code?
Ok so here is the HTML tag:
<div id="youTube" data-video-id="[YouTube video ID here]"></div>
And here is the API code:
window.onYouTubeIframeAPIReady = function () {
player = new YT.Player('youTube', {
videoId: $("#youTube").data("videoId"),
playerVars: {
'rel': 0,
},
events: {
'onReady': function () {
player.unMute();
player.setVolume(35);
player.playVideo();
},
'onStateChange': function () {
if (player.getPlayerState() == 2 && !counted) {
viewCount++;
counted = true;
}
}
}
});
}
Oh, and here's a couple more bits of relevant information:
The bug is repeatable on any client, and it shows up whether deployed to server or from localhost.
I cannot get rid of subtitles using 'cc_load_policy': 0,
The subtitles do not show up on when viewing the video on YouTube.com
I don't get subtitles when I use the iframe embed code instead of the full API:
Again, I have other videos that share the same API code with no subtitle bug.
* UPDATE *
Ok, now I'm seeing this same behavior with other videos. This did not used to happen, so I'm thinking it is something on the YouTube side.
...I still would like some help looking into this, though. Here's a jsfiddle:
https://jsfiddle.net/4ruz2xcx/3/
Related
I integrated Vimeo Video in my site and I used 'background= 1' parameter in query string to remove all the default functionalities but it cause a problem that my Video get muted when it loads and I want to unmute the video on page load.
I am beginner so please Give me some good and simple solution keeping in mind that background = 1 should stay there.
Here is what I tried so far:
<script>
var dynamicContent = getParameterByName('background');
$(document).ready(function() {
if (dynamicContent=='1') {
$('#vi-video-1-container').attr('data-audio-volume', 1);
$("#vi-banner-video").vimeo("setVolume", 1);
}
});
</script>
On the page a have a flowplayer which play videos by provided tag (just a name of video category) using playlist plugin. And I have section “Suggested videos”. When I click on suggested video, I want to reload playlist using newly selected video tag. I tried use setPlaylist(array) as described in documentation https://flowplayer.org/docs/playlist.html#methods:
var player = flowplayer();
player.setPlaylist(this.playlist);
but it's not working.
Full player method code:
updatePlayer() {
if(document.getElementById('flow').innerHTML === "") {
var player = flowplayer(document.getElementById("flow"), {
autoplay: true,
playlist: this.playlist,
loop: true
});
// here I add all player events what I need
} else {
console.log('player updated');
var player = flowplayer();
player.unload();
//update flowplayer playlist
player.setPlaylist(this.playlist);
}
}
When the player is initialized and I click to suggested videos console.log() shows me message and player.unload() works, but setPlaylist() doesn't.
The only solution what can help its to use shutdown() method, which destroys all player instances, events and so on. But it is an ugly solution I think, previous I used JW player where you can easily update playlist dynamically.
Can anyone help me? Thanks!
Solution is player.setPlaylist(this.playlist).play(0);
I have copied the Youtube embedded player demo code Youtube embedded player demo code almost verbatim - the changes are inserting console.log so that I can see what is going on.
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
console.log('onPlayerReady');
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
console.log('onPlayerStateChange');
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
This works as intended in Safari and Firefox, that is once the API loads the choosen video plays for six seconds and the console.log contains evidence that the events are firing. However in Internet Explorer the events onReady and onStateChange do not fire. The video will play if I manually click the play control in the player but I do not get the expected onStateChange events.
I checked the version of Flash on my machine and it is: 11.2.202.228 and the current available is 12.0.0.70. If I disable Flash in IE (manage add ons) the player works as expected: plays for 6 seconds and events fire.
I did not update Flash because while that might fix the issue on my machine my audience will be limited to those only that can do the same and if I updated I would not be able to find out if the issue was resolved by other means.
I have also tried to manually create the iframe myself as mentioned in the above Youtube documentation, this worked as expected in Firefox and Safari but not in IE.
There is a Youtube demo player this works perfectly in Firefox, the play, pause and stop controls via the API work and the events are clearly firing as the Events and Function Calls are written to the screen in the "Statistics" section. In contrast when I look at this in IE the play, pause and stop controls via the API do nothing. There is no output in the statistics section. The only way to play and pause is to use the buttons on the player. If I disable Flash then the player & API works perfectly.
If I try an iframe non API embed then the player works correctly, this leads me to believe that it is an issue arising from using the API.
I know some would say that all users should have the latest Flash, easier said than done. Many schools, companies and libraries lock down the options section in IE so the user would be able to turn off Flash for my site.
I wonder is there some way of turning off Flash when using the API?
I have searched around Stackoverflow and elsewhere and while I have found similar issues I have not found any fixes. I did find a somewhat similar promising lead but alas I had no joy. Also here and here and here and here and here.
I must point out that the issue is present when used on a local machine and on a website and even if I set the origin parameter.
I would appreciate suggestions and help. Thanks in advance.
I wonder is there some way of turning off Flash when using the API?
You could force the YouTube player to use its html5 player using the following option:
playerVars: {html5: 1}
Changing your code to:
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
playerVars: {
html5: 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
I have a youtube video that I've embedded with youtube's iFrame API. I would like to:
show a translucent overlay when a user pauses the video (WORKS)
hide that overlay when the user plays the video (WORKS)
NOT show an overlay when the user is "seeking" via the youtube controls (POSSIBLE?)
Having trouble controlling the seek behavior. Is it possible?
To reproduce, hold the seek at the same position for a few seconds and watch the overlay appear. Example jsfiddle is here:
http://jsfiddle.net/dNU84/3/
var ytvideo;
window.onYouTubePlayerAPIReady = function () {
ytvideo = new YT.Player('ytvideo', {
width: '400',
height: '300',
videoId: 'BOksW_NabEk',
playerVars: {
'autoplay': 1,
'controls': 1
},
events: {
"onStateChange": onPlayerStateChange
}
});
}
function showOverlay() {
if ($('.video .video-overlay').length) $('.video .video-overlay').fadeIn(1200);
}
function hideOverlay() {
if ($('.video .video-overlay').length) $('.video .video-overlay').hide();
}
var overlay;
function onPlayerStateChange(event) {
console.log(event.data);
clearTimeout(overlay);
// youtube fires 2xPAUSED, 1xPLAYING on seek
if (event.data == YT.PlayerState.PAUSED) {
overlay = setTimeout(showOverlay, 1000);
}
if (event.data == YT.PlayerState.PLAYING) {
overlay = hideOverlay();
}
}
Unfortunately, the YouTube player APIs don't have a reliable way to report on a "seek" state. If you're interested, here's a link to an (older) explanation as to why this is the case:
https://groups.google.com/forum/#!topic/youtube-api-gdata/1xGLZ54YOPI
If you have any desire to use a chromeless player instead of the default one with YouTube controls, you can get around this limitation by listening for events on your custom scrubber ... as a simple example, jQuery UI's slider can be set up as a scrubber for a chromeless player and report the "seek" state by using the 'start,' 'stop,' and 'slide' events.
I know this question is old, but I was just searching for a solution to this because I show an overlay on pause, but the overlay was showing each time the user would seek as well due to both event values being 2.
The easiest solution I've come across is to set a one second timeout:
setTimeout(function() {
if ( event.target.getPlayerState() == 2 ) {
// execute your code here for paused state
}
}, 1000)
This will only execute code on the paused state, and not on seek because after the 1 second timeout the PlayerState would be 1 again if it were the user seeking.
I've got this plugin which applies different style to html5 <audio> element and provides flash fallback to browsers that don't support .mp3 file format. Problem I encountered is that once you start playing one song, and then click play on any other song, all of them will play at the same time, which is bad user experience.
I was trying to figure out how to edit plugin to make it only play one song at a time, so say if user listens to one song and then click play on other, first one should pause, and so on.
I'm not entirely sure, but I think something need's to be edited along these lines:
playPause: function() {
if (this.playing) this.pause();
else this.play();
},
However, there are various places in the plugin which seem to deal with playing and pausing song, so I'm not sure that this is exact correct line for this. I'm still very new to jQuery, and can't entirely figure out how this big audio library works, I've been reading through code comment's , but still am unable to figure this out.
Full code of the plugin is available here: http://freshbeer.lv/mg/js/audio.min.js Official plugin website: http://kolber.github.io/audiojs/
You can visit my demo page to see the issue, just click play on several players and you will see that they all play at the same time: http://freshbeer.lv/mg/index.html
Use the addEventListener and the play event. This pauses all players except the one that the play button has been pressed on.
audiojs.events.ready(function () {
var as = audiojs.createAll();
$('audio').each(function () {
var myAudio = this;
this.addEventListener('play', function () {
$('audio').each(function () {
if (!(this === myAudio)) {
this.pause();
}
});
});
});
});