Make youtube video fullscreen using iframe and javascript API - javascript

I have an embedded youtube video with hidden controls:
<iframe id="ytplayer" type="text/html" width="400" height="225"
src="http://www.youtube.com/embed/dMH0bHeiRNg?rel=0&controls=0&showinfo=0
&loop=1&hd=1&modestbranding=1&enablejsapi=1&playerapiid=ytplayer"
frameborder="0" allowfullscreen></iframe>
I can control it with the youtube Javascript API.
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
Things like player.playVideo() and so on work perfectly. Now I am looking for a way to make the video play in fullscreen mode with a Javascript call but I couldn't find any method in the API.
Is it even possible (without the controls) and if so - how?

This worked perfect in my case. You can find more details on this link: demo on CodePen
var player, iframe;
var $ = document.querySelector.bind(document);
// init player
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '200',
width: '300',
videoId: 'dQw4w9WgXcQ',
events: {
'onReady': onPlayerReady
}
});
}
// when ready, wait for clicks
function onPlayerReady(event) {
var player = event.target;
iframe = $('#player');
setupListener();
}
function setupListener (){
$('button').addEventListener('click', playFullscreen);
}
function playFullscreen (){
player.playVideo();//won't work on mobile
var requestFullScreen = iframe.requestFullScreen || iframe.mozRequestFullScreen || iframe.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(iframe)();
}
}

You can use html5 fullscreen api:
node.requestFullScreen();
document.cancelFullScreen();
document.fullScreen; // bool
But note that:
this usually requires vendor specific prefix like mozRequestFullScreen() or webkitRequestFullScreen
requestFullScreen has to be called on user events (like onclick)
in firefox the fullscreen will be black until "Allow" is clicked by user

I've added code to do fullscreen (real full screen, not full window) to my answer on Auto-Full Screen for a Youtube embed.
YouTube don't expose fullscreen in their API, but you can call the native browser requestFullScreen() function from the playerStateChange() event from the YouTube API or make your own custom play button like I have.

Looking at the API reference for the iframe player, I don't think it's possible to set it to fullscreen (with the iframe API alone)- ctrl f didn't find fullscreen, so either it's a secret method hidden inside the API or it doesn't exist. However, as you probably know, you can set the size of the player player.setSize(width:Number, height:Number):Object, then make the window fullscreen.

Maybe have a look at this similar question. It looks as though this might work for you (using the javascript fullscreen api rather than the Youtube API):
Full Screen Option in Chromeless player using Javascript?

You can try setting the iframe dimension to the window dimension through javascript.
Something like this (using jQuery):
$('ytplayer').attr('width', $(window).width());
$('ytplayer').attr('height', $(window).height());
I hope this can help you.

Related

Handle key events when using Youtube iframe API

I was looking for a solution on how to handle key events when running Youtube videos on my application using Youtube iframe API. unfortunately couldn't find any. Did went through this documentation https://developers.google.com/youtube/iframe_api_reference#Events but it seems player doesn't fire any event related to key ( ex: onkeydown, keypress, keyup ).
I tried adding events directly to the provided code but it didnt worked.
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('trailer_video', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
// 'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onkeydown': myfunction // custom event
}
});
}
Is there any way I can handle key events specially when Arrow keys are pressed ?.
P.S: I dont know I might be wrong here but usually when i press Arrow keys while video is buffering, i see chain of dots moving which gives me a hint, that the player does detects these events and responds.
UPDATE QUESTION
As answer below suggests which is ofcourse a solution in a way but since Youtube also handles left and right arrow key events its possible to use when cursor is over the video as well, My concern is, how can i handle the events for up and down arrow key which are not getting handled by Youtube and which only works when cursor is not over the video if I implement a custom event handler.
It depends on what you are trying to accomplish. But the answer to your question, "Is there any way I can handle key events specially when Arrow keys are pressed?" is yes. Here is an example of a custom rewind/fast-forward functionality that uses the left and right arrow keys:
https://jsfiddle.net/xoewzhcy/3/
<div id="video"></div>
function embedYouTubeVideo() {
player = new YT.Player('video', {
videoId: 'M7lc1UVf-VE'
});
}
function rewind() {
var currentTime = player.getCurrentTime();
player.seekTo(currentTime - 30, true);
player.playVideo();
}
function fastforward() {
var currentTime = player.getCurrentTime();
player.seekTo(currentTime + 30, true);
player.playVideo();
}
$(function(){
// embed the video
embedYouTubeVideo();
// bind events to the arrow keys
$(document).keydown(function(e) {
switch(e.which) {
case 37: // left (rewind)
rewind();
break;
case 39: // right (fast-forward)
fastforward();
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
});
NOTE: Watch out for when you're focused on the embedded video (i.e., you click the YouTube play button or click into the YouTube iframe in any way). Because, your key events won't be listened to since the YouTube iframe is a completely separate window. To get around this, you could overlay a transparent div on the YouTube iframe and build your own play/pause buttons. That way no one can ever click into the iframe and lose focus of the parent window.
I hope this helps!

Allow only one YouTube video in the same page with jQuery

I have some videos which are embedded from YouTube in my "index.php". I am able to watch several videos at the same time by clicking them repeatedly. So, as usual it can be done. But I want to block this somehow.
For example, I'm watching X video and I clicked play to watch Y video. The X video should stop when I do it. Then I should be able to continue watching the Y video. I saw this feature in a website which I don't remember the name of it. And I don't know how to do and have an idea.
What I can guess is that it can be done by using some JavaScript or jQuery.
Here is an example for YouTube video code:
<iframe width="426" height="240" src="//www.youtube.com/embed/lWA2pjMjpBs?rel=0" frameborder="0" allowfullscreen></iframe>
Here is my JavaScript (without jQuery) solution to allow only one YouTube video to play at the time.
DEMO.
First you need to add a Youtube API by simply adding the script to your HTML page:
<script src="https://www.youtube.com/iframe_api"></script>
Then paste as many embed videos as you need. Keep in mind that
?enablejsapi=1&version=3&wmode=transparent
needs to be added to each link in order to access API. I wrapped the videos in div with yt_videos class.
<div class="yt_videos">
<iframe class="video_groups" src="https://www.youtube.com/embed/r4CH0al0ucs?enablejsapi=1&version=3&wmode=transparent" frameborder="0" allowfullscreen></iframe>
<iframe class="video_groups" src="https://www.youtube.com/embed/lL9Zoc46ZG0?enablejsapi=1&version=3&wmode=transparent" frameborder="0" allowfullscreen></iframe>
<iframe class="video_groups" src="https://www.youtube.com/embed/s1NZ2mkW0hM?enablejsapi=1&version=3&wmode=transparent" frameborder="0" allowfullscreen></iframe>
</div>
Then in javascript I access onYouTubeIframeAPIReady() so I can control players behaviour. I loop through the iframes and assign unique id's:
var players = [];
function onYouTubeIframeAPIReady() {
var predefined_players = document.getElementsByClassName("yt_videos")[0].getElementsByTagName('iframe');
for(var i = 0; i < predefined_players.length; i++){
predefined_players[i].id = "player" + i;
players[i] = new YT.Player("player" + i, {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
}
function onPlayerStateChange(event) {
var link = event.target.a.id;
var newstate = event.data;
if (newstate == YT.PlayerState.PLAYING) {
players.forEach(function(item, i) {
if (item.a.id != link) item.pauseVideo();
});
}
}
See the DEMO.
You can use the Youtube JS API
https://developers.google.com/youtube/js_api_reference
With it you can handle youtube player events...
If you're using only 1 iframe and just have several links on the sides that would contain the src destination of the iframe you could change the src attribute of the iframe like this:
$('.YoutubeLink').click(function(event){
$('#myIframe').attr('src',$(this).attr('href'));
});

Embeded Youtubu doesn't load on mobile safari, when hidden

Google changed something last days, so I have strange problem with Youtube embeded as iFrame in mobile safari. When iFrame is hidden (some parent div has set display:none) during page load and later is changed to be visible, Youtube player do not play.
Any solution? I've tried to reload iframe, when it turns to visible state, it works. But it is not comfortable solution…
I am assuming you are using the third party youtube Iframe API to load the youtube player into a div. The code from youtube actually has a race condition in it where if the div is not loaded/ parsed by the browser prior to onYouTubeIframeAPIReady being called, the video load will fail. In firefox it will just hang and for a second and Chrome is smart enough to deal with the problem.
The solution is to make sure that this code. Is run after the container holding the video is parsed.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
And this code...
function onYouTubeIframeAPIReady() {
Has global scope and is called after the script is created.
The way I typically solve this to to create a function 'class' with the tag creator and event listener and create the object in my document.ready function. Then right below the document.ready function I put.
function onYouTubeIframeAPIReady() {
myVideo.apiReady();
}
Where 'myVideo' is the class I have create and apiReady(); contains.
this.apiReady = function () {
player = new YT.Player('player', {
height: '548',
width: '900',
videoId: 'VIDEO234324',
events: {
'onReady': onPlayerReady
}
});
}
I hope this helps.

How to capture onclick within an iFrame for embedded YouTube video?

I have an iFrame that displays an embedded youtube video.
<iframe width="560" height="315" src="http://www.youtube.com/embed/xxx" frameborder="0" allowfullscreen></iframe>
What I would like to do is somehow capture the click event when the user clicks the you tube video so that I can call an http://myserver.com/dostuff rest api to update an external server counter tracking the number of clicks and of course allow the video to play as expected.
Any information would be greatly appreciated.
You can't, I believe. That would be a security risk. If you mainly want to do tracking and whatnot, you would probably be best off doing something like adding an image/button in the place of the video that the user clicks, causing the video to appear.
Edit: This solution may work too; I'm not sure if it'll work for iframes that aren't on the same domain.
window.postMessage could help. But you should have an access to source code of the page you're rendering in iframe.
So in case of embedding of youtube video, you probably can't deal with this.
Everybody had great feedback. Thanks for all who posted. After trying some hacks the bottom line is that trapping the click event is not natively supported via html or javascript.
The best artifact and cleanest solution that I have found is here.
//Its possible by recording the stateChange in the video.
//HTML code----
<!DOCTYPE html>
<html>
<body>
<div id='vidWrapper'>
//your iframe tag goes here.
<iframe id="video-id-first" src="https://www.youtube.com/embed/nNlEiuqiKAk?enablejsapi=1&origin=http%3A%2F%2F3.7.232.244" gesture="media" allow="encrypted-media" allowfullscreen="" data-gtm-yt-inspected-53610233_3="true" width="560" height="400" frameborder="0"></iframe>
</div>
</body>
</html>
//JS code ----
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
var width = document.getElementById("video-id-first").getAttribute("width");
var height = document.getElementById("video-id-first").getAttribute("height");
var src = document.getElementById("video-id-first").getAttribute("src");
//splitting to get the videoId from src.
var partsArr = src.split("/");
var videoSource = partsArr[partsArr.length -1 ].split("?");
var videoId = videoSource[videoSource.length -2 ];
function onYouTubeIframeAPIReady() {
player = new YT.Player('vidWrapper', {
height:height,
width: width,
videoId: videoId,
events: {
'onStateChange': function(event) {
if (event.data == YT.PlayerState.PLAYING) {
startVideo();
}
if (event.data == YT.PlayerState.PAUSED) {
stopVideo();
}
}
}
});
}
function startVideo() {
//write your functionality here.
alert('Video Started');
}
function stopVideo() {
//write your functionality here.
alert('Video Paused');
}

Advice on making a youtube video stop when a click event is fired

I have set up some test code that loads in a youtube video and then a jquery click event on a link that I plan to stop the video, at the moment however when I click the link I get the error: Uncaught TypeError: Object [object Object] has no method 'stopVideo'
Can anyone suggest where I might be going wrong with this?
<div id="container">
This is the link
<br /><br />
<br /><br />
<div id="player"></div>
</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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw'
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
$(document).ready(function() {
$('a').click(function(e) {
player.stopVideo();
e.preventDefault();
});
});
</script>
Your code snippet works as intended in a fiddle. Also, the YouTube Frame API won't function at a file:/// protocol, because of limitations at the postMessage implementation.
I have previously created a custom implementation of the YouTube API, available at YouTube iframe API: how do I control a iframe player that's already in the HTML?. I have successfully executed the stopVideo method at a file:/// protocol.
If you're running your code online, I can only think of one other cause: You're trying to click at the link before the player is ready. To fix it, merge your functions:
function onPlayerReady(event) {
event.target.playVideo();
$('a').click(function(e) { //<--- Binds event to ALL anchors! Are you sure?
player.stopVideo();
e.preventDefault();
});
});

Categories