My HTML
<div id="player">
<!-- hardcoded for the moment -->
<div id="video">
<iframe class="youtube-player" id="video-frame" width="640" height="390" src="http://www.youtube.com/v/gSy4HeDjPvs?version=2&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</div>
</div>
JavaScript
var youtube_player; // global player variable
// adding YouTube controls
$(function () {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
function onYouTubeIframeAPIReady() {
//noinspection JSUnresolvedFunction,JSUnresolvedVariable
youtube_player = new YT.Player('video', {
height:'390',
width:'640',
videoId:'JW5meKfy3fY',
events:{
'onReady':onPlayerReady,
'onStateChange':onPlayerStateChange
}
});
}
// playing video in left pane
function play_video(id) {
console.log('play video', id);
//noinspection JSUnresolvedFunction
if (youtube_player) {
youtube_player.loadVideoById(id, 0);
}
}
function onPlayerReady(evt) {
evt.target.playVideo();
}
// when video is finished playing, what next video to play?
function onPlayerStateChange(event) {
if (event.data == 0) {
var id = get_next_video_id();
if (id == -1) {
// repeat = 0, reset video_index
reset_video_index();
} else {
play_video(id);
}
}
}
This runs fine in Safari but fails in Chrome. On console.log, it says
Uncaught TypeError: Object #<U> has no method 'loadVideoById' vlists.js:447
30
Unable to post message to http://www.youtube.com. Recipient has origin https://www.youtube.com.
Even though in YouTube API, loadVideoById exists.
After working through the YouTube API for a while, I am able to make it run for both Chrome and Safari
The demo is http://plnkr.co/edit/07Cq5KqIa5Pase8JYHbA?p=preview
Related
I'm trying to defer the loading of YouTube CSS and JavaScript on my site for performance purposes. However, running a scan of my page with Google's Page Speed Insights indicates that the YouTube CSS file https://www.youtube.com/yts/cssbin/www-player-sprite-mode-vflixBY8E.css is not being deferred. I also tested removing the JavaScript to make sure the CSS file was not being requested by some other resource but that was not the case.
Here is the code I am using:
In my main.js file (which is deferred)
function init() {
var vidDefer = document.getElementsByClassName('youtube');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
}
}
}
window.onload = init;
Then, the iframe looks like this:
<iframe class="youtube" id="home-youtube" src="" data-src="https://www.youtube.com/embed/QHfgMrpMOm4" frameborder="0" allowfullscreen></iframe>
Thanks in advance
You could always try using Youtube's javascript API and
https://developers.google.com/youtube/iframe_api_reference
<!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) {
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) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
I'm loading YouTube videos using JS API. I can play, pause and go fullscreen with external controls but I can't exit fullscreen with double click on the video.
Using the code below try this:
load the video with button
go fullscreen using internal iframe button
double click on video (you will exit fullscreen)
Now my problem:
load the video with button
go fullscreen using external button
double click on video (nothing happens unless you press ESC key)
How can I do this? I need to exit fullscreen by double click (besides using ESC key)
fiddle: https://jsfiddle.net/cs8tnvkh/
HTML
<button id="btn_load">load video</button>
<button id="btn_play">play</button>
<button id="btn_pause">pause</button>
<button id="btn_fullscreen">fullscreen</button>
<div id="video_player">
<div id="video"></div>
</div>
JS
const YOUTUBE_LINK = "https://www.youtube.com/embed/#VIDEO?wmode=transparent&autoplay=1&rel=0&controls=1&enablejsapi=1&html5=1";
const YOUTUBE_VIDEO_ID = "mPyLF7NxZyY";
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('video', {
height: '480',
width: '720',
events: {
// call this function when player is ready to use
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
$("#btn_play").click(function() {
player.playVideo();
});
$("#btn_pause").click(function() {
player.pauseVideo();
});
$("#btn_fullscreen").click(function() {
var iframe = $('#video')[0];
var requestFullScreen = iframe.requestFullScreen || iframe.mozRequestFullScreen || iframe.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(video)();
}
});
}
var tag = document.createElement('script');
tag.src = "//www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
$(document).ready(function() {
$("#btn_load").click(function() {
var video_src = YOUTUBE_LINK.replace("#VIDEO", YOUTUBE_VIDEO_ID);
$("#video_player iframe").attr("src", video_src);
});
});
I have a iframe generated on my site. The src of the iframe is video id from database. I would like to know, how can I detect that the video finishes playing.
My embeded youtube video:
echo "<iframe width='50%' height='60%' id='cc' src='https://www.youtube.com/embed/" . $data_song[0] . "' frameborder='1' allowfullscreen></iframe><br>";
Thanks for any advice.
Okay, Since you are using the iframe to stream youtube videos, what you want can be achieved by this,
When Player.Status = 0 that means the video has stopped. I have commented those for you to understand easily.
<script type="text/javascript">
var player;
$(document).ready(function () {
onYouTubePlayerAPIReady();
});
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
events: {
'onStateChange': getStatus
}
});
}
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function getStatus() {
var sStatus;
sStatus = player.getPlayerState();
if (sStatus == -1) {} //Video has not started yet
else if (sStatus == 0) {
// video has stopped. This is the event that you want
}
else if (sStatus == 1) { } //Video is playing
else if (sStatus == 2) {} //Video is paused
else if (sStatus == 3) { } //video is buffering
else if (sStatus == 5) { } //Video is cued.
}
</script>
If you use a tag <video> is better.
For example:
Your HTML
<video id="videoplayer">.
Your JS
var myvideo = document.getElementById('videoplayer');
myvideo.addEventListener('ended',function() {
// The video's callback
} ,false);
I'm currently loading a YouTube video inside a -UIwebView, this is working perfectly and the video starts playing automatically. but the problem is that once the video finishes inside the -UIwebViewit just stops and shows the play button. I would however want the video player to close so the users wouldn't have to manually hit the "Done" button every time.
Image of the screen when the video doesn't close.
Here's the link I launch the video inside the -UIwebview
NSString *youTubeVideoHTML = [NSString stringWithFormat:#"<!DOCTYPE html><html><head>
<style>body{margin:0px 0px 0px 0px;}</style></head> <body> <div id=\"player\"></div> <script>
var tag = document.createElement('script'); tag.src = \"http://www.youtube.com/player_api\";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
width:'320',
height:'200',
videoId:'%#',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
</script> </body> </html>", [[NSUserDefaults standardUserDefaults]
objectForKey:#"detailVideoURL"]];
EDIT:
I tried implementing the first answer into my code and this is how it ended up like. I'm still unsure what I should add into the callback ?
NSString *youTubeVideoHTML = [NSString stringWithFormat:#"<!DOCTYPE html><html><head><style>body{margin:0px 0px 0px 0px;}</style></head> <body> <div id=\"player\"></div> <script>
var tag = document.createElement('script'); tag.src = \"http://www.youtube.com/player_api\";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
width:'320',
height:'200',
videoId:'%#',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000); done = true;
}
if (event.data == YT.PlayerState.ENDED) {
window.location = "callback:nil"; }; }
function stopVideo() {
player.stopVideo();
}
</script> </body> </html>", [[NSUserDefaults standardUserDefaults] objectForKey:#"detailVideoURL"];
Image of the error : http://gyazo.com/31da955d8af98f40b82789a7f60c1edb
You can do it by calling your objective function from javascript using youtube api.
On the HTML/Javascript Side
<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 = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '300',
width: '250',
videoId: 'GUdYebAN-Fs',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
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) {
event.target.destroy();
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 60000);
done = true;
}
if (event.data == YT.PlayerState.ENDED) {
event.target.destroy();//to close the video
window.location = "callback:anything"; //here's the key
};
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
onStateChange- From the google's API reference page
This event fires whenever the player's state changes. The data property of the event object that the API passes to your event listener function will specify an integer that corresponds to the new player state.
So in the javascript function you would be able to trace the End of the video time.Then just
add event.target.destroy() on entering the state end condition.
On the native/iOS side:
And even you can do the native stuff here by catching up the call back method using the webview delegate method.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ( [[[request URL] scheme] isEqualToString:#"callback"] ) {
//Video has ended up playing,you can perform native stuff here...
return NO;
}
return YES;
}
Note: Please make sure to test this code in your device,because sometimes the simulators won't be supporting.
Good Luck...Hope it helps...
This is how you can apply Puneeth's solution to Google's YTPlayerView so the player hides after the video finishes:
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state
{
if(state == kYTPlayerStateEnded) {
[self.youTubePlayer.webView stringByEvaluatingJavaScriptFromString:#"player.destroy();"];
// you'll have to recreate the player again since it's now destroyed
[self.youTubePlayer removeFromSuperview];
self.youTubePlayer = nil;
}
}
So I have My code it detects when the player has stopped the problem is I can't get it to play from 0 seconds when the end has come I'm using the Iframe embed that holds a html5 video, Here is the code!
<div id="youtube-fs"><iframe id="youtube-iframe" type="text/html" src="http://www.youtube.com/embed/LYL0lzmrvk8?enablejsapi=1&html5=1&autoplay=1&showinfo=0&controls=0&rel=0&wmode=transparent&vq=hd1080&hd=1&loop=1" frameborder="0" wmode="Opaque" ></iframe> <script type="text/javascript">
<!--
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() { player = new YT.Player('youtube-iframe', { events: { 'onStateChange': onPlayerStateChange } }); }
function onPlayerReady(event) { event.target.playVideo(); }
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) { player.playVideoAt(0); } // Play from 0 seconds
}
-->
</script>
</div>
Any idea's? maybe seekTo? or something
Thank you in advance!
Used player.seekTo(1, true); that worked
Try this
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
player.seekTo(0);
player.playVideo();
} // Play from 0 seconds
}
http://plnkr.co/aoSupfT7vXGGoM99sNwl