Stop embedded youtube iframe?
Asked Answered
P

18

77

I'm using YouTube iframe to embed videos on my site.

<iframe width="100%" height="443" class="yvideo" id="p1QgNF6J1h0"
              src="http://www.youtube.com/embed/p1QgNF6J1h0?rel=0&controls=0&hd=1&showinfo=0&enablejsapi=1"
              frameborder="0" allowfullscreen>
</iframe>

And i have multiplie videos on the same page.

I want to stop all of them or one of them in a click of a button using javascript or so.

Is it possible?

UPDATE:

I tried what Talvi Watia said and used:

$('#myStopClickButton').click(function(){
  $('.yvideo').each(function(){
    $(this).stopVideo();
  });
});

I'm getting:

Uncaught TypeError: Object [object Object] has no method 'stopVideo' 
Pibroch answered 1/3, 2013 at 19:0 Comment(0)
B
126

Unfortunately these API's evolve very fast. As of May 2015, the proposed solutions don't work anymore, as the player object has no stopVideo method.

A reliable solution is to be found in this page (1) and it works with an:

<iframe id="youtube_player" class="yt_player_iframe" width="640" height="360" src="http://www.youtube.com/embed/aHUBlv5_K8Y?enablejsapi=1&version=3&playerapiid=ytplayer"  allowfullscreen="true" allowscriptaccess="always" frameborder="0"></iframe>

and the following JS/jQuery code:

$('.yt_player_iframe').each(function(){
  this.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*')
});
Brownnose answered 20/5, 2015 at 18:47 Comment(17)
With which version of the API have you falsified this solution? Have you found an alternative?Brownnose
I would like to emphasize that your embed url MUST have enablejsapi=1, otherwise this doesn't work. Details here developers.google.com/youtube/player_parameters#enablejsapi I spent some time when I realized why this answer doesn't work.Maine
This is still working as of 5/2018. Fixed a cosmetic typo in the js code.Calyces
For some reason I had to pass it to the src link for it to work: src="youtube.com/embed/…"Heyer
Are the classes here intentionally different? yt_player_iframe vs youtube_player_iframeEdify
@Clint: good catch. Looking at it now, I guess they should be the same; but I can't recall exactly what I did myself 3yrs ago. I see the original page with the solution is lost, so we are on our own. You may want to edit the text :-)Brownnose
@NejcRodošek - I don't know. It appears the original page where I found this solution is lost forever. Possibly a reference to this API version is still reachable.Brownnose
@MarcoFaustinell i found the command, it is: unMute. Its case sensitive, so watch out for the cases.Elongation
note in this answer there is a mismatch between class="yt_player_iframe" and $('.youtube_player_iframe'), correct this and it works perfectlyLorielorien
although it does throw a warning : "Cross-Origin Request Blocked" if more than one is playing.Lorielorien
On 2018-11-20 just adding ?enablejsapi=1 to the URL and using the postMessage worked for me without importing any JS files for the Youtube API. When the warning shows up in teh console, it also says: "The Same Origin Policy disallows reading the remote resource at [URL] Reason: CORS request did not succeed".Ricks
2020-05-25, this solution still works, add ?enablejsapi=1 and iframeElement.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*') (notice i'm using pauseVideo, because stopVideo hides title even if the video was not started).Kat
@Ricks @SimionAgavriloaei - the src attribute of the iframe already contains enablejsapi=1, yet you both suggest to add the same string. But where? Feel free to edit the text, because I don't understand. Thank you for the upvote, btw! :-)Brownnose
@MarcoFaustinelli I probably meant that the other 2 parameters were not needed, i.e. version and playerapiid do not need to be in the URL.Ricks
I know this post is old, but I just wanted to say that this solution still works as of July 2020.Fadiman
Still works Sept 2022. Very very glad this is an option. The API has grown quite a bit in complexity since I last used it.Insinuation
Still works in June 2023 /m/ thanks!Diderot
E
47

If anyone is still looking for the answer, i've solved it like so:

$("#photos").on("hide",function(){
    var leg=$('.videoPlayer').attr("src");
    $('.videoPlayer').attr("src",leg);
});

Where #photos is the ID of the modal and .videoPlayer is the class of the iframe. Basically it refreshes the src attribute (and stops playing the video). So,

    $('#myStopClickButton').click(function(){
      $('.yvideo').each(function(){
        var el_src = $(this).attr("src");
        $(this).attr("src",el_src);
      });
    });

should do the trick.

Edgewise answered 30/3, 2016 at 15:20 Comment(9)
I think this is the best option when you load iframes dinamically.Singularize
Good tip, thanks. I incorporated :visible into it so instead of resetting everything on the page I just reset the current one. When flipping through tabs or a gallery it means the new tab will show with the video already loaded.Revet
Perhaps something changed on the YouTube end, but for me this just restarts the video rather than stopping it (edit: nevermind, javascript elsewhere was adding '&autoplay=1' to the url)Merilee
A fine hack. Applause.Etiquette
Ha! Take that YouTube! Smart people scores!Iseabal
Yes! Thanks. This is option is still working in 2019. Also, it does not rely on YouTube API.Wohlert
seems to fail with ms edge.Homologous
@Homologous maybe it recognizes the same source wants to be loaded. Maybe you can try to insert a line "$(this).attr("src","#");" just before "$(this).attr("src",el_src);" ? let us know if that helps :)Edgewise
Cleanest solution, no dependency on API. Works on all devices. el.src = el.src. Brilliant man!Facetiae
W
24

Here is a codepen, it worked for me.

I was searching for the simplest solution for embedding the YT video within an iframe, and I feel this is it.

What I needed was to have the video appear in a modal window and stop playing when it was closed

Here is the code : (from: https://codepen.io/anon/pen/GBjqQr)

    <div><a href="#" class="play-video">Play Video</a></div>
    <div><a href="#" class="stop-video">Stop Video</a></div>
    <div><a href="#" class="pause-video">Pause Video</a></div>

    <iframe class="youtube-video" width="560" height="315" src="https://www.youtube.com/embed/glEiPXAYE-U?enablejsapi=1&version=3&playerapiid=ytplayer" frameborder="0" allowfullscreen></iframe>

$('a.play-video').click(function(){
    $('.youtube-video')[0].contentWindow.postMessage('{"event":"command","func":"' + 'playVideo' + '","args":""}', '*');
});

$('a.stop-video').click(function(){
    $('.youtube-video')[0].contentWindow.postMessage('{"event":"command","func":"' + 'stopVideo' + '","args":""}', '*');
});

$('a.pause-video').click(function(){
    $('.youtube-video')[0].contentWindow.postMessage('{"event":"command","func":"' + 'pauseVideo' + '","args":""}', '*');
});

Additionally, if you want it to autoplay in a DOM-object that is not yet visible, such as a modal window, if I used the same button to play the video that I was using to show the modal it would not work so I used THIS:

https://www.youtube.com/embed/EzAGZCPSOfg?autoplay=1&enablejsapi=1&version=3&playerapiid=ytplayer

Note: The ?autoplay=1& where it's placed and the use of the '&' before the next property to allow the pause to continue to work.

Woehick answered 18/7, 2018 at 16:39 Comment(5)
So with autoplay=1, the 1 means it should not pause (and play automatically), are you saying if you put the & after it it will not autoplay and pause the video?Mailbag
easiest way to stop player without all these JS and API from youtube, thx!Santos
I think that it does not work anymore, at least on Chrome 96, I've also checked in Firefox 89.0.2 and it works, but not in Chrome :(Monophyletic
Just tried as well, seems does not work. What might be new change. lol.Egalitarian
NOTE enablejsapi=1 this attribute is required in URLTransnational
F
21

You may want to review through the Youtube JavaScript API Reference docs.

When you embed your video(s) on the page, you will need to pass this parameter:

http://www.youtube.com/v/VIDEO_ID?version=3&enablejsapi=1

If you want a stop all videos button, you can setup a javascript routine to loop through your videos and stop them:

player.stopVideo()

This does involve keeping track of all the page IDs for each video on the page. Even simpler might be to make a class and then use jQuery.each.

$('#myStopClickButton').click(function(){
  $('.myVideoClass').each(function(){
    $(this).stopVideo();
  });
});
Flax answered 1/3, 2013 at 19:15 Comment(11)
But i will need to create an object for each player? Will the stopVideo() just work without any prior setups ?Pibroch
If you add enablejsapi=1 to the embed you should be able to reference the API. It will need to be added for every video.Flax
I'm getting: Uncaught TypeError: Object [object Object] has no method 'stopVideo'Pibroch
#9310612 has information about the cross-site prtection error. (normally a huge issue in chrome.) as for the second, you need to change .myVideoClass with the class attached to your embed. i.e. .yvideoFlax
I think it's a problem that my onYouTubePlayerReady not being called.Pibroch
entirely possible. Again, I would recommend to follow the API guide, possibly try some examples. Also make sure you allow the cross-origin script. Access-Control-Allow-Origin: *Flax
@Pibroch It appears a full working example can be found here: #7444078Flax
stopVideo is native and not a jQuery method, so do not wrap your iframe in jQuery. I also recommend to use <object> tag instead of <iframe> for embedding YT videos.Fumble
@Eskat0N again, I would recommend to use the working example. To use the (quick and easy) method I provided, you need to include jquery in your header. stopVideo is actually not a native function to javascript, rather the embedded YouTube player object. Thus, if you reference by id or class in jQuery, it really doesn't matter if it is an object or iframe. (Although <object> is better yes.) The subfunctions bound to that object will then be available in jQuery. (such as stopVideo)Flax
Hello there,does anyone know how to implement that within Ionic 3?Continental
This didn't worked for me, instead this fiddle did the trick: jsfiddle.net/MadLittleMods/3J2wT with this code $('#popup-youtube-player')[0].contentWindow.postMessage('{"event":"command","func":"' + 'stopVideo' + '","args":""}', '*');Berkshire
G
20

APIs are messy because they keep changing. This pure javascript way worked for me:

 <div id="divScope" class="boom-lightbox" style="display: none;">
    <iframe id="ytplayer" width="720" height="405"   src="https://www.youtube.com/embed/M7lc1UVf-VE" frameborder="0" allowfullscreen>    </iframe>
  </div>  

//if I want i can set scope to a specific region
var myScope = document.getElementById('divScope');      
//otherwise set scope as the entire document
//var myScope = document;

//if there is an iframe inside maybe embedded multimedia video/audio, we should reload so it stops playing
var iframes = myScope.getElementsByTagName("iframe");
if (iframes != null) {
    for (var i = 0; i < iframes.length; i++) {
        iframes[i].src = iframes[i].src; //causes a reload so it stops playing, music, video, etc.
    }
}
Glosseme answered 21/4, 2016 at 23:42 Comment(1)
this is a close solution to was looking for. Now to detect if it is playing BEFORE I try the reset. It causes the video to blink.Sukhum
F
14

Talvi's answer may still work, but that Youtube Javascript API has been marked as deprecated. You should now be using the newer Youtube IFrame API.

The documentation provides a few ways to accomplish video embedding, but for your goal, you'd include the following:

//load 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);

//will be youtube player references once API is loaded
var players = [];

//gets called once the player API has loaded
function onYouTubeIframeAPIReady() {
    $('.myiframeclass').each(function() {
        var frame = $(this);

        //create each instance using the individual iframe id
        var player = new YT.Player(frame.attr('id'));

        players.push(player);
    });
}

//global stop button click handler
$('#mybutton').click(function(){

    //loop through each Youtube player instance and call stopVideo()
    for (var i in players) {
        var player = players[i];
        player.stopVideo();
    }
});
Foti answered 23/3, 2015 at 20:53 Comment(0)
V
8

Easiest ways is

var frame = document.getElementById("iframeid");
frame.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
Vilayet answered 18/3, 2017 at 15:52 Comment(0)
P
8

One cannot simply overestimate this post and answers thx OP and helpers. My solution with just video_id exchanging:

<div style="pointer-events: none;">
    <iframe id="myVideo" src="https://www.youtube.com/embed/video_id?rel=0&modestbranding=1&fs=0&controls=0&autoplay=1&showinfo=0&version=3&enablejsapi=1" width="560" height="315" frameborder="0"></iframe> </div>

    <button id="play">PLAY</button>

    <button id="pause">PAUSE</button>


    <script>
        $('#play').click(function() {
            $('#myVideo').each(function(){ 
                var frame = document.getElementById("myVideo");
                frame.contentWindow.postMessage(
                    '{"event":"command","func":"playVideo","args":""}', 
                    '*'); 
            });
        });

        $('#pause').click(function() {
            $('#myVideo').each(function(){ 
                var frame = document.getElementById("myVideo");
                frame.contentWindow.postMessage(
                  '{"event":"command","func":"pauseVideo","args":""}',
                  '*'); 
            });
        });
    </script>
Pisolite answered 13/9, 2017 at 10:35 Comment(2)
perfect as of nowEndometrium
Hey folks, this solution is great, except that it makes the video lose all its native interactivity, how can I still use the native youtube video buttons? Thank youAlisealisen
S
6

This is the most straightforward solution that I have found.

  1. Very important! Add ?enablejsapi=1 parameter to the iframe src attribute. E.g. scr="https://youtube.com/embed/VIDEO_ID?enablejsapi=1

  2. var iframe = document.querySelector('iframe'); or however you want to get a hold of the element.

  3. iframe.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');

Essentially, this code is getting a hold of the Youtube Player object which is contained within the <iframe> element. See HTMLIFrameElement.contentWindow on MDN and postMessage(). Finally, Google provides a Javascript API reference here for all available functions.

Spade answered 9/6, 2022 at 15:40 Comment(1)
Thanks for telling to add ?enablejsapi=1 . Without it not workingLongshoreman
R
4

For a Twitter Bootstrap modal/popup with a video inside, this worked for me:

$('.modal.stop-video-on-close').on('hidden.bs.modal', function(e) {
  $('.video-to-stop', this).each(function() {
    this.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div id="vid" class="modal stop-video-on-close"
  tabindex="-1" role="dialog" aria-labelledby="Title">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Title</h4>
      </div>
      <div class="modal-body">
       <iframe class="video-to-stop center-block"
        src="https://www.youtube.com/embed/3q4LzDPK6ps?enablejsapi=1&rel=0"
        allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
        frameborder="0" allowfullscreen>
       </iframe>
      </div>
      <div class="modal-footer">
        <button class="btn btn-danger waves-effect waves-light"
          data-dismiss="modal" type="button">Close</button>
      </div>
    </div>
  </div>
</div>

<button class="btn btn-success" data-toggle="modal"
 data-target="#vid" type="button">Open video modal</button>

Based on Marco's answer, notice that I just needed to add the enablejsapi=1 parameter to the video URL (rel=0 is just for not displaying related videos at the end). The JS postMessage function is what does all the heavy lifting, it actually stops the video.

The snippet may not display the video due to request permissions, but in a regular browser this should work as of November of 2018.

Ricks answered 20/11, 2018 at 11:59 Comment(0)
S
3

Here's a pure javascript solution,

<iframe 
width="100%" 
height="443" 
class="yvideo" 
id="p1QgNF6J1h0"
src="http://www.youtube.com/embed/p1QgNF6J1h0?rel=0&controls=0&hd=1&showinfo=0&enablejsapi=1"
frameborder="0" 
allowfullscreen>
</iframe>
<button id="myStopClickButton">Stop</button>


<script>
document.getElementById("myStopClickButton").addEventListener("click",    function(evt){
var video = document.getElementsByClassName("yvideo");
for (var i=0; i<video.length; i++) {
   video.item(i).contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*');
}

});

Salutary answered 10/10, 2018 at 11:44 Comment(0)
H
3

How we Pause/stop YouTube iframe to when we use embed videos in modalpopup

 $('#close_one').click(function (e) {
         
         
         let link = document.querySelector('.divclass');// get iframe class 
         let link = document.querySelector('#divid');// get iframe id
         let video_src = link.getAttribute('src');

         $('.youtube-video').children('iframe').attr('src', ''); // set iframe parent div value null 
         $('.youtube-video').children('iframe').attr('src', video_src);// set iframe src again it works perfect

     });
Huey answered 4/9, 2020 at 4:52 Comment(0)
A
2

here is my solution using updated youtube API. Includes start, stop, pause.

https://codesandbox.io/s/youtube-video-player-73x4b

Aquino answered 12/1, 2022 at 11:3 Comment(0)
P
1

see also How to pause or stop an iframe youtube video when you leave a tab view or minimise your Ionic App

$scope.stopVideo = function() {
 var iframe = document.getElementsByTagName("iframe")[0].contentWindow;
 iframe.postMessage('{"event":"command","func":"'+'stopVideo'+   '","args":""}', '*');
 }
Perfectionist answered 1/2, 2016 at 5:14 Comment(0)
N
1

$('#aboutVideo .close').on('click',function(){
			var reSrc = $('.aboutPlayer').attr("src");
			$('.aboutPlayer').attr("src",reSrc)
		})
#aboutVideo{
	width: 100%;
	height: 100%;
}
#aboutVideo .modal-dialog, #aboutVideo .modal-dialog .modal-content, #aboutVideo .modal-dialog .modal-content .modal-body{
	width: 100%;
	height: 100%;
	margin: 0 !important;
	padding: 0 !important;
}
#aboutVideo .modal-header{
	padding: 0px; 
	border-bottom: 0px solid #e5e5e5; 
	position: absolute;
	right: 4%;
	top: 4%;
}
#aboutVideo .modal-header .close{
	opacity: 1;
	position: absolute;
	z-index: 99;
	color: #fff;
}
#aboutVideo .modal-header button.close{
      border-radius: 50%;
    width: 7vw;
    height: 7vw;
    position: absolute;
    right: 4%;
    top: 7%;
    background: aliceblue;
}
#aboutVideo .modal-header button.close:hover{
	background-color: rgba(255, 255, 255, 0.28);
}
#aboutVideo .modal-header button.close img{
	width: 20px;
	margin-top: -0.2vw;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<li class="see-video fa" type="button" data-toggle="modal" data-target="#aboutVideo">
			<label>SEE VIDEO</label>
		</li>
<div class="modal fade" id="aboutVideo" tabindex="-1" role="dialog" aria-labelledby="aboutVideoLabel">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true"><img src="http://www.freeiconspng.com/uploads/white-close-button-png-16.png"></span></button>
				</div>
				<div class="modal-body">
				<iframe class="aboutPlayer" width="100%" height="100%" src="https://www.youtube.com/embed/fju9ii8YsGs?autoplay=0&showinfo=0&controls=2&rel=0" frameborder="0" allowfullscreen poster="https://www.google.co.in/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiOvaagmqfWAhUHMY8KHUuJCnkQjRwIBw&url=http%3A%2F%2Fnodeframework.com%2F&psig=AFQjCNEaHveDtZ81veNPSvQDx4IqaE_Tzw&ust=1505565378467268"></iframe>
				</div>
			</div>
		</div>
	</div>
Nutpick answered 15/9, 2017 at 12:41 Comment(0)
C
1

Solution for React with TypeScript


interface Props {
  videoId: string;
}

function YoutubeEmbedded (props:Props) {
  const { videoId } = props;

  const pauseVideo = () => {
    // At the place of pauseVideo you can use "stopVideo", "playVideo"
    var iframe = document.querySelector("iframe");
    iframe?.contentWindow?.postMessage(
      '{"event":"command","func":"stopVideo","args":""}',
      "*"
    );
  };

  const handleCloseBtnClick = () => {
    pauseVideo();
    setShowVideoModal(false);
  };

return(
  <iframe
    src={`https://www.youtube-nocookie.com/embed/${videoId}?enablejsapi=1`}
    title="YouTube video player"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowFullScreen={true}
    frameBorder={0}
  />

  <button
    onClick={handleCloseBtnClick}
  />
)}
Callis answered 24/11, 2022 at 16:17 Comment(0)
Z
0
var vid_element = $('.youtube-player');
vid_element.detach();
$('#parent').append(vid_element);

I find detaching and then appending the element more reliable than re-assigning the src attribute.

Zane answered 20/2, 2022 at 11:21 Comment(0)
A
-1

There is a very easy way to achieve if you are in JS

  
 function pauseVideo(){
 document.getElementById("myVideoId").contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*');  

 } 
<!DOCTYPE html>
<html>
<body>

<iframe id="myVideoId" src="https://www.youtube.com/embed/Q63qjIXMqwU?enablejsapi=1"></iframe> 
<button onclick = {pauseVideo()}>Pause</button>




</body>
</html>

if you are using react js

export const VideoPlayer = () =>{
 const videoooo = useRef();
  const pauseVideo = () => {
  //at the place of pauseVideo you can use "stopVideo", "playVideo"
videoooo.current.contentWindow.postMessage(
      '{"event":"command","func":"pauseVideo","args":""}',
      "*"
    );
  };

return(<> <iframe
        ref={videoooo}
        id="myVideoId"
        src="https://www.youtube.com/embed/Q63qjIXMqwU?enablejsapi=1"
      ></iframe>
      <button
        onClick={() => {
          pauseVideo();
        }}
      >
        Pause
      </button></>)
}
Apology answered 25/8, 2022 at 17:28 Comment(1)
On Edge browser, running the JS snippet got black nothing in the video box, an uncaught error with the React snippet.Handedness

© 2022 - 2024 — McMap. All rights reserved.