I'm working on a website, and i'm trying to get an youtube video in an <iframe> tag to play and pause with one button. I can get it to play or pause with separate buttons, but I can't seem to get the if statement to work in order to control the video with just one button.
I'm still relatively new to JavaScript, so it may just bee something simple I missed, but I'v searched online for a while now, and could not find anything that solved my problem.
Below is the code I use right now. The first time I click the button the YouTube video play's, but the second time nothing happens.
I also tried turning autoplay on for the embedded video, but then when I press the button, nothing happens at all.
This is the code I'm currently using:
HTML
<div class="iframe">
<iframe id="iframe1" width="360" height="203" src="https://www.youtube-nocookie.com/embed/videoseries?list=PLb-Mg8r29XuOV9CbkXVDQ5NdQG__WbJqI&controls=0&showinfo=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<a href="#" onclick="iframe1play();return false;">
<div id="iframe1play">
</div>
</a>
</div>
JavaScript
function onYouTubePlayerAPIReady() {
iframe1 = new YT.Player('iframe1');
}
function iframe1play() {
if (event.data == YT.PlayerState.PLAYING && !done) {
iframe1.pauseVideo();
document.getElementById("iframe1").style.opacity = "0";
} else {
iframe1.playVideo();
document.getElementById("iframe1").style.opacity = "1";
}
}
var tag = document.createElement('script');
tag.src = "//www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
Any suggestions are appreciated!
Ok so the main problem was that you didn't have event object in your function.
this should do the trick
if (player.getPlayerState() == YT.PlayerState.PLAYING) {
player.pauseVideo();
document.getElementById("iframe").style.opacity = "0";
} else {
player.playVideo();
document.getElementById("iframe").style.opacity = "1";
}
Use jQuery or other framework, if you can,for injecting functions to elements.
Maybe I don't understand your question. Because I tried your code and it works.
I can see a page with a youtube video. On clicking play button the video starts and when I click again on the video in pauses. So what is your problem. I'm sorry if I don't use comments but I can't yet.
Related
I am trying to embed a vimeo video using iframe in my Qualtrics survey. When this video ends, I want to automatically advance to the next page (i.e., automatically press the "next button"). Before using vimeo, my videos were stored on dropbox and I used the following code for this (the url is not the real one):
<video autoplay="" id="video1" height="580" width="740"><source src="https://dl.dropboxusercontent.com/u/6339921/att/fam.mp4" type="video/mp4"></video>
Qualtrics.SurveyEngine.addOnload(function() {
that = this;
document.getElementById('video1').addEventListener('ended',myHandler,false);
function myHandler(e) {
if(!e) {
e = window.event;
}
that.clickNextButton();
}
});
However, it seems that I have to use iframe with vimeo, but I am unable to make the auto-advance work (the video will play but the page will not advance). Maybe it is because I am assigning the "ID" the wrong way. Here is the code:
<iframe id="player1" src="https://player.vimeo.com/video/20708824?autoplay=1api=1&player_id=player1&title=0&byline=0&portrait=0&background=1&mute=0&loop=0" width="600" height="400" frameborder="0"></iframe>
Qualtrics.SurveyEngine.addOnload(function() {
that = this;
var idPlayer = new Vimeo.Player('player1');
document.getElementByID('player1').addEventListener('ended',myHandler,false);
function myHandler(e) {
if(!e) { e = window.event; }
that.clickNextButton();
}
});
I am looking for a) an option to fix the iframe code, or b) an option to embed a vimeo video using the old code that I had used with dropbox videos.
Thanks so much and I apologize if this all sounds naive, I am not a programmer :-(
You can't add an event listener to an iframe from a different domain. It is called cross-domain scripting and for security reasons isn't allowed by the browser.
You have to use postMessage. There is a JavaScript class already written, but you would have figure out how to integrate it into Qualtrics:
https://github.com/vimeo/player.js
Well, I think this is a major Youtube bug but I don't find any report about it.
I have a web app which is displayed in full screen browser using the JavaScript Fullscreen API.
In the web app there is an embedded Youtube player. When you open the Youtube player in fullscreen, then clicks the Youtube's fullscreen button again to exit the player's fullscreen, it doesn't respond!
I am sure it is related to the fact that the browser is already in full screen mode so there is some kind of conflict.
I have created a simplified example which can be viewed here:
http://run.plnkr.co/CjrrBGBvrSspfa92/
Click the "GO FULLSCREEN" button.
Play the video and click the
fullscreen button. The video will go fullscreen.
Click the
fullscreen button again. It won't exit.
EDIT:
The code for the html file above is here:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe width="560" height="315" src="https://www.youtube.com/embed/b-6B2zyoFsI" frameborder="0" allowfullscreen></iframe>
<button id="btn">GO FULLSCREEN</button>
<script type="text/javascript">
document.getElementById("btn").addEventListener("click", function() {
var elem = document.documentElement;
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
}
});
</script>
</body>
</html>
The thing is I did some searching and it seams Youtube doesn't know if the video is in fullscreen or not when using the JavaScript Fullscreen API nor does Google provide an API call to fo in or out of fullscreen. So, When you click the button and it goes in fullscreen, you'll see the player's fullscreen button not pressed. So, in order to get back to the window view, the user has two options:
1) click on the button 2 times (the first time, the player tries to go in fullscreen and the button changes state, the second time, the player goes in window mode) - this is the solution
2) click Esc on the keyboard.
I checked with the HTML5 player.
Furthermore, I tried injecting a button inside YouTube's iframe so I can select it in order to exit fullscreen, but it didn't work... would have been silly to actually.
This should work:
<div id="videoplayer"></div>
<p><button id="btn">GO FULLSCREEN</button></p>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('videoplayer', {
height: '380',
width: '500',
videoId: 'h7ArUgxtlJs',
fs: 1
});
}
document.getElementById("btn").addEventListener("click", function() {
var elem = document.getElementById('videoplayer');
var requestFullScreen = elem.requestFullscreen || elem.msRequestFullscreen || elem.mozRequestFullScreen || elem.webkitRequestFullscreen;
if (requestFullScreen) {
requestFullScreen.bind(elem)();
}
});
</script>
You can use the classic embed, I belive.
Working demo
This may help: "Exiting Fullscreen Mode":
// Whack fullscreen
function exitFullscreen() {
if(document.exitFullscreen) {
document.exitFullscreen();
} else if(document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if(document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
// Cancel fullscreen for browsers that support it!
exitFullscreen();
Source.
Side note: Youtube's API is still pretty scarce in terms of what you can customize even in 2015 (due to how it relies on so much iFrame, and they don't want you to reskin their player). You'll likely get to a point where your using a bunch of funky JavaScript hacks to get what you want, which can get messy and unstable. It would be better practice to utilize one of many customizable video players where you can have more control with JS; like JW player, Video.js, Flow player, popcorn.js etc.
Site plays a full screen video with sound. The site was designed to play the video without sound. When a link is clicked the other portions of the site appear on top of the video.
Unfortunately the client has insisted on having sound, so when something is clicked you still hear the music until the video ends. I know it is possible to have the video stop or even have it muted when a link is clicked but I cannot seem to understand where exactly to implement this. Your help is appreciated. I'm not a jquery person so I'm rather dim on this. Site uses the YTPlayer ( http://pupunzi.open-lab.com/mb-jquery-components/jquery-mb-ytplayer/ )
The site: http://www.bradfordweb.com/clients/concannon2/
The code in the page that is playing the video is:
<a id="P2" class="player" data-property="{videoURL:'http://youtu.be/OgAr2jQr3rg',containment:'#home',autoPlay:true, mute:false, loop:false, opacity:.6}"></a>
The link is:
<div class="link-home"><div class="cl-effect-8"><span>ABOUT US</span> </div></div>
I tried:
onclick="stop()"
and
stopYTP
I found the function in the jquery.mb.YTPlayer.js file:
stopYTP: function () {
var YTPlayer = this.get(0);
var controls = jQuery("#controlBar_" + YTPlayer.id);
var playBtn = controls.find(".mb_YTVPPlaypause");
playBtn.html(jQuery.mbYTPlayer.controls.play);
YTPlayer.player.stopVideo();
},
Help?
I've had this issue as well and found it in the onYouTubePlayerReady function.
Look for it in that file and do the following changes:
function onYouTubePlayerReady(playerId) {
var player=$("#"+playerId);
player.mb_setMovie();
// Remove or comment out the lines below.
// $(document).on("mousedown",function(e){
// if(e.target.tagName.toLowerCase() == "a")
// player.pauseYTP();
// });
}
That line just simply binds the mousedown event on an a tag and consequently pauses the player.
Hope that helps.
Strange one: embedded YouTube videos, once played (either by clicking 'play' or autoplaying on page load) will not play again.
I'm using the standard iFrame embed copied straight from YouTube. This happens with several different short videos and across all browser/OS combinations I've tested (Chrome/Safari/Firefox/IE on Windows/Mac).
Here's the code:
<iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen></iframe>
and you can see it in action at this fiddle.
So it appears that the issue is NOT related to video length; it's a problem with the flash player. If the flash player is loaded, and there is no user interaction with the controls at all, then when the player finishes it will not reload the iframe (despite the fact that it raises the 'video ended' event ... when you try to reload it won't issue the right call to reload the video and hence can never restart playback). You can test longer videos as well; if you start watching them and don't use the scrub bar, they'll exhibit the same behavior. Likewise, on your very short video, if you start playback and then scrub a bit (even backwards in time), that will trigger an iframe reload (akin to what #SuperMan noted), and so when the video finishes, then the reload will work just fine.
This is most likely a recently introduced bug in the Flash player, and it is not present in the HTML5 player; so if your use case allows it, the simplest solution would be to force the HTML5 player by appending ?html5=1 to the source of your iframe.
However, if having the flash player as a possibility is an iron clad requirement, then you can hack your code to force it to reload itself when finished (rather than waiting for a user to hit the reload or replay button).
<html>
<body>
<script>
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;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
events: {
onStateChange: 'onPlayerStateChange'
}
});
}
function onPlayerStateChange(event) {
if (event.data===YT.PlayerState.ENDED) {
event.target.cueVideoById(event.target.getVideoData().video_id);
}
}
</script>
<iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen id="player"></iframe>
</body>
</html>
Note that this requires giving your iframe an id attribute, so that you can bind to it with the iframe API.
This also avoids having to overlay any DOM elements over the video (which is not in any way a bad solution as long as you don't have any odd wmode requirements; a very strict reading of the YouTube TOS might also lead to the conclusion that you can't overlay anything over any portion of the player even if it's transparent...).
One drawback of my solution is that it won't display the 'related videos' at the end of the video, so if that's a deal breaker then this is a no-go (in other words, my solution is more akin to adding the rel=0 attribute to your iframe source).
Okay, I don't know how to fix the problem but here's a work around.
The general idea is to place a div over the reload button when the video finishes, and when the div is clicked the video reloads, since the normal method doesn't work.
Here's the code I used, in the code the div is blue for visualization purposes
<!DOCTYPE html>
<html>
<body>
<div id="player_prop" style="position:relative;"><iframe id="player" type="text/html" width="640" height="390"
src="http://www.youtube.com/embed/OuSdU8tbcHY?enablejsapi=1"
frameborder="0"></iframe></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', {
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.
//from mantish http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url
function youtube_parser(url){
var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
var match = url.match(regExp);
if (match&&match[2].length==11){
return match[2];
}else{
//error
}
}
//end of Lasnvs code
function restart_vid()
{
el = document.getElementById("fake_replay_button");
vid_id = youtube_parser(document.getElementById('player').src);
player.loadVideoById(vid_id);
el.parentNode.removeChild(el);
}
function fakeplay()
{
el = document.getElementById("player_prop");
var xPos = el.offsetLeft
var yPos = el.offsetHeight - 30;
var pseudoPlay = document.createElement('div');
pseudoPlay.setAttribute('style', 'background-color:blue; cursor:pointer; display:block; width:55px; height:25px; position:absolute; top:'+yPos+'px;');
pseudoPlay.setAttribute('onclick','restart_vid()');
pseudoPlay.setAttribute('id','fake_replay_button');
el.appendChild(pseudoPlay);
}
function onPlayerStateChange(event)
{
if(event.data==YT.PlayerState.ENDED)
{
fakeplay();
}
}
</script>
</body>
</html>
To use this code all you have to do is copy and paste the script portion, and instead of only using this
<iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen></iframe>
give it an id=player, enable jsapi by adding ?enablejsapi=1 at the end of the src and enclose the iframe in a div with id = player_prop, make sure the div has property position:relative, or else the alignment of the button would be off, it should look like this
<div id="player_prop" style="position:relative;">
<iframe id="player" type="text/html" width="640" height="390" src="http://www.youtube.com/embed/OuSdU8tbcHY?enablejsapi=1" frameborder="0"></iframe>
</div>
And of course here's a link to the Fiddle
In simple and fine way is that you have to add two addition parameter in youtube url first one is loop=1 and second is playlist=videoid
However, you can extract videoid from the url. It will be after embed slash
<iframe src="https://www.youtube.com/embed/J3jB4CS0x34?autoplay=1&mute=1&loop=1;playlist=J3jB4CS0x34" width="100%" height="100%" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="">
</iframe>
Maybe something like this:
JsFiddle
It's not a perfect solution, cause you interect with video outside of iframe, but maybe it will get you going(changing src will always reload the video).
$('iframe').attr("src", "//www.youtube.com/embed/OuSdU8tbcHY?autoplay=1"); // restarts the 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');
}