Jak wstrzymać odtwarzacz YouTube podczas ukrywania ramki iframe?


86

Mam ukryty element DIV zawierający film z YouTube w formacie <iframe>. Gdy użytkownik kliknie łącze, ten element div staje się widoczny, a użytkownik powinien mieć możliwość odtworzenia wideo.

Gdy użytkownik zamknie panel, wideo powinno zatrzymać odtwarzanie. Jak mogę to osiągnąć?

Kod:

<!-- link to open popupVid -->
<p><a href="javascript:;" onClick="document.getElementById('popupVid').style.display='';">Click here</a> to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>

<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">

  <iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40" frameborder="0" allowfullscreen></iframe>

  <br /><br /> 
  <a href="javascript:;" onClick="document.getElementById('popupVid').style.display='none';">
  close
  </a>
</div><!--end of popupVid -->

Nie jestem pewien, ale być może będziesz musiał znaleźć sposób na zatrzymanie wideo lub usunięcie go z elementu DIV, a nie tylko jego ukrycie ..
— aniri

powinieneś przyjąć odpowiedź.
— snymkpr

Odpowiedzi:


188

Najłatwiejszym sposobem zaimplementowania tego zachowania jest wywołanie metod pauseVideoi playVideo, gdy jest to konieczne. Zainspirowany wynikiem mojej poprzedniej odpowiedzi , napisałem funkcję bez wtyczek, aby osiągnąć pożądane zachowanie.

Jedyne korekty:

  • Dodałem funkcję, toggleVideo
  • Dodałem ?enablejsapi=1do adresu URL YouTube, aby włączyć tę funkcję

Demo: http://jsfiddle.net/ZcMkt/
Kod:

<script>
function toggleVideo(state) {
    // if state == 'hide', hide. Else: show video
    var div = document.getElementById("popupVid");
    var iframe = div.getElementsByTagName("iframe")[0].contentWindow;
    div.style.display = state == 'hide' ? 'none' : '';
    func = state == 'hide' ? 'pauseVideo' : 'playVideo';
    iframe.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}
</script>

<p><a href="javascript:;" onClick="toggleVideo();">Click here</a> to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>

<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">
   <iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
   <br /><br />
   <a href="javascript:;" onClick="toggleVideo('hide');">close</a>

1
Tak, zdecydowanie potrzebuję zielonego pola wyboru, jeśli to zadziałało. Ja też biorę to rozwiązanie - świetne rzeczy, mam te klatki wideo w akordeonie jQueryUI, więc muszę je dołączać do każdego zdarzenia wyzwalającego.
— jeffkee

Chciałem tylko zwrócić uwagę, że niestety API YouTube sprawia, że ​​używasz podwójnych cudzysłowów w wiadomościach wysyłanych za pośrednictwem postMessage. Nie możesz na przykład przełączyć się na zewnętrzne podwójne cudzysłowy i wewnętrzne pojedyncze cudzysłowy.
— Jordania

1
@Jordan Ma to sens, ponieważ oczekuje się, że wiadomość będzie w formacie JSON. JSON z definicji używa cudzysłowów do cytowania kluczy i wartości.
— Rob W,

2
Jeśli ktoś jest zainteresowany, zaktualizowałem kod, aby zatrzymać odtwarzanie wideo po kliknięciu przycisku „Zamknij” w module bootstrap 3. $ ("# MyModal-close") .click (function () {var div = document.getElementById ("MyModal-videoWrapper"); var iframe = div.getElementsByTagName ("iframe") [0] .contentWindow; iframe.postMessage ('{"event": "command", "func": "' + 'pauseVideo' + '", "args": ""}', '*');});
— Ryan Walton

10
Pamiętaj, że musisz dodać ?enablejsapi=1do adresu URL umieszczania <iframe class="embed-responsive-item" src="//www.youtube.com/embed/WIZUeIDFALw?html5=1&enablejsapi=1" allowfullscreen></iframe>
— ramki

23

Oto wersja jQuery dotycząca odpowiedzi RobW dotycząca użycia ukrywania / wstrzymywania elementu iframe w oknie modalnym:

    function toggleVideo(state) {
        if(state == 'hide'){
            $('#video-div').modal('hide');
            document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
        }
        else {
            $('#video-div').modal('show');
            document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
        }
    }

Wspomniane elementy html to sam modalny element div (# video-div) wywołujący metody show / hide oraz element iframe (# video-iframe), który ma adres URL wideo taki jak src = "" i sufiks enablejsapi = 1 ? który umożliwia programowe sterowanie odtwarzaczem (np.

Więcej informacji na temat html można znaleźć w odpowiedzi RobW.


5
Jaka zwiększona czytelność zmieniła? zależne od if / else, ale dziękuję za rozpoczęcie tego. Po prostu poczułem, że mam coś ważnego do dodania.
— DrewT

15

Oto prosty fragment kodu jQuery do wstrzymywania wszystkich filmów na stronie na podstawie odpowiedzi RobW i DrewT:

jQuery("iframe").each(function() {
  jQuery(this)[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*')
});

jeśli nie chcesz używać jQuery, kod wewnątrz funkcji „each” jest taki sam po usunięciu odniesienia do obiektu jQuery. tj. node.contentWindow. ...
— mattdlockyer

Jak mogę to odwrócić, aby odtworzyć ponownie po ponownym wyświetleniu wideo?
— Carl Papworth

Wystarczy zamienić „pauseVideo” na „playVideo”. Przykład: jsfiddle.net/ora2kqzq/1
— quartarian

To już nie działa ... nawet gdy próbuję, {"event":"command","func":"playVideo","args":[],"id":1,"channel":"widget"}po {"event":"listening","id":1,"channel":"widget"}czym jest to, co interfejs API iframe YT.Player publikuje na YouTube embed.
— NoBugs,

9

Hej, prostym sposobem jest po prostu ustawienie źródła wideo na zero, aby wideo znikało, gdy jest ukryte, a następnie ustawić źródło z powrotem na wideo, które chcesz, po kliknięciu linku otwierającego wideo. które po prostu ustawiają identyfikator na iframe youtube i wywołują funkcję src, używając tego identyfikatora w następujący sposób:

<script type="text/javascript">
function deleteVideo()
{
document.getElementById('VideoPlayer').src='';
}

function LoadVideo()
{
document.getElementById('VideoPlayer').src='http://www.youtube.com/embed/WHAT,EVER,YOUTUBE,VIDEO,YOU,WHANT';
}
</script>

<body>

<p onclick="LoadVideo()">LOAD VIDEO</P>
<p onclick="deleteVideo()">CLOSE</P>

<iframe id="VideoPlayer" width="853" height="480" src="http://www.youtube.com/WHAT,EVER,YOUTUBE,VIDEO,YOU,HAVE" frameborder="0" allowfullscreen></iframe>

</boby>

4
Ostrzeżenie: modyfikacji iframejest srcz JavaScript zostanie przypadkowo nasunąć window.history, powodując problemy przycisk Wstecz.
— Jordan Arseno

Dzięki Jordan! Właśnie zacząłem używać tej odpowiedzi i nie byłem świadomy tego zachowania. Lepiej wiedzieć teraz niż później :)
— MMachinegun

Uczciwe ostrzeżenie dla każdego, kto spróbuje tej metody: może to spowodować bardzo zauważalne opóźnienie, jeśli używasz jej do przełączania się między elementami div, które zawierają osadzone elementy iframe dla YouTube. Bądź ostrożny.
— Muhammad Abdul-Rahim

6

Ponieważ musisz ustawić ?enablejsapi=truew src elementu iframe, zanim będziesz mógł użyć poleceń playVideo/ pauseVideowymienionych w innych odpowiedziach , przydatne może być dodanie tego programowo za pomocą JavaScript (szczególnie jeśli np. Chcesz, aby to zachowanie miało zastosowanie do filmów osadzonych przez inne użytkownicy, którzy właśnie wycięli i wkleili kod do umieszczenia w serwisie YouTube). W takim przypadku przydatne może być coś takiego:

function initVideos() {

  // Find all video iframes on the page:
  var iframes = $(".video").find("iframe");

  // For each of them:
  for (var i = 0; i < iframes.length; i++) {
    // If "enablejsapi" is not set on the iframe's src, set it:
    if (iframes[i].src.indexOf("enablejsapi") === -1) {
      // ...check whether there is already a query string or not:
      // (ie. whether to prefix "enablejsapi" with a "?" or an "&")
      var prefix = (iframes[i].src.indexOf("?") === -1) ? "?" : "&amp;";
      iframes[i].src += prefix + "enablejsapi=true";
    }
  }
}

... jeśli wywołasz tę document.readyopcję, wszystkie elementy iframe w elemencie div z klasą „video” zostaną enablejsapi=truedodane do źródła, co pozwoli na działanie poleceń playVideo / pauseVideo.

(Uwaga. ten przykład używa jQuery dla tej jednej linii, która ustawia var iframes, ale ogólne podejście powinno działać równie dobrze z czystym Javascriptem, jeśli nie używasz jQuery).



4

Sposób RobW był dla mnie świetny. Dla osób używających jQuery jest to uproszczona wersja, z której skończyłem:

var iframe = $(video_player_div).find('iframe');

var src = $(iframe).attr('src');      

$(iframe).attr('src', '').attr('src', src);

W tym przykładzie „video_player” to nadrzędny element div zawierający element iframe.


4

Chciałem podzielić się rozwiązaniem, które wymyśliłem przy użyciu jQuery, które działa, jeśli masz wiele filmów z YouTube osadzonych na jednej stronie. W moim przypadku zdefiniowałem wyskakujące okienko modalne dla każdego filmu w następujący sposób:

<div id="videoModalXX">
...
    <button onclick="stopVideo(videoID);" type="button" class="close"></button>
    ...
    <iframe width="90%" height="400" src="//www.youtube-nocookie.com/embed/video_id?rel=0&enablejsapi=1&version=3" frameborder="0" allowfullscreen></iframe>
...
</div>

W tym przypadku videoModalXX reprezentuje unikalny identyfikator wideo. Następnie następująca funkcja zatrzymuje wideo:

function stopVideo(id)
{
    $("#videoModal" + id + " iframe")[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}

Podoba mi się to podejście, ponieważ zatrzymuje wideo w miejscu, w którym zostało przerwane, na wypadek, gdybyś chciał wrócić i kontynuować oglądanie później. U mnie działa dobrze, ponieważ szuka elementu iframe wewnątrz modalu wideo z określonym identyfikatorem. Nie jest wymagany żaden specjalny identyfikator elementu YouTube. Miejmy nadzieję, że to również komuś się przyda.


To działało świetnie bez mnóstwa kodu. Mam na stronie wiele filmów z YouTube i po prostu pokazuję kciuk w YouTube i potrzebuję rozwiązania zatrzymania / wstrzymania. Zmieniając pauseVideo na playVideo, mogłem uruchomić wideo, gdy rozszerzyło się do pełnej szerokości kolumny
— WebDude0482

2

po prostu usuń src z iframe

$('button.close').click(function(){
    $('iframe').attr('src','');;
});

Ale może chcieć kontynuować grę, gdy użytkownicy klikną otwarte.
— Coda Chang,

bracie, onclick ponownie dodaj src przez jquery, to zadziała
— rakesh kejriwal

1

Odpowiedź Rob W pomogła mi dowiedzieć się, jak zatrzymać wideo w ramce iframe, gdy suwak jest ukryty. Jednak potrzebowałem pewnych modyfikacji, zanim zacząłem działać. Oto fragment mojego kodu HTML:

<div class="flexslider" style="height: 330px;">
  <ul class="slides">
    <li class="post-64"><img src="http://localhost/.../Banner_image.jpg"></li>
    <li class="post-65><img  src="http://localhost/..../banner_image_2.jpg "></li>
    <li class="post-67 ">
        <div class="fluid-width-video-wrapper ">
            <iframe frameborder="0 " allowfullscreen=" " src="//www.youtube.com/embed/video-ID?enablejsapi=1 " id="fitvid831673 "></iframe>
        </div>
    </li>
  </ul>
</div>

Zauważ, że to działa na localhost , a także jako Rob W wspomniano " enablejsapi = 1 ” został dodany do końca zawartości wideo.

Oto mój plik JS:

jQuery(document).ready(function($){
    jQuery(".flexslider").click(function (e) {
        setTimeout(checkiframe, 1000); //Checking the DOM if iframe is hidden. Timer is used to wait for 1 second before checking the DOM if its updated

    });
});

function checkiframe(){
    var iframe_flag =jQuery("iframe").is(":visible"); //Flagging if iFrame is Visible
    console.log(iframe_flag);
    var tooglePlay=0;
    if (iframe_flag) {                                //If Visible then AutoPlaying the Video
        tooglePlay=1;
        setTimeout(toogleVideo, 1000);                //Also using timeout here
    }
    if (!iframe_flag) {     
        tooglePlay =0;
        setTimeout(toogleVideo('hide'), 1000);  
    }   
}

function toogleVideo(state) {
    var div = document.getElementsByTagName("iframe")[0].contentWindow;
    func = state == 'hide' ? 'pauseVideo' : 'playVideo';
    div.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}; 

Jako prostszy przykład, sprawdź to na JSFiddle


1

To podejście wymaga jQuery. Najpierw wybierz element iframe:

var yourIframe = $('iframe#yourId');
//yourId or something to select your iframe.

Teraz wybierz przycisk odtwórz / wstrzymaj ten element iframe i kliknij go

$('button.ytp-play-button.ytp-button', yourIframe).click();

Mam nadzieję, że ci to pomoże.


0

Odpowiedzi RobW tutaj i gdzie indziej były bardzo pomocne, ale moje potrzeby okazały się znacznie prostsze. Odpowiedziałem na to gdzie indziej , ale być może przyda się również tutaj.

Mam metodę, w której tworzę ciąg HTML do załadowania w UIWebView:

NSString *urlString = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@",videoID];

preparedHTML = [NSString stringWithFormat:@"<html><body style='background:none; text-align:center;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>var player; function onYouTubeIframeAPIReady(){player=new YT.Player('player')}</script><iframe id='player' class='youtube-player' type='text/html' width='%f' height='%f' src='%@?rel=0&showinfo=0&enablejsapi=1' style='text-align:center; border: 6px solid; border-radius:5px; background-color:transparent;' rel=nofollow allowfullscreen></iframe></body></html>", 628.0f, 352.0f, urlString];

Możesz zignorować elementy stylizacji w przygotowanym ciągu znaków HTML. Ważnymi aspektami są:

  • Użycie interfejsu API do utworzenia obiektu „YT.player”. W pewnym momencie miałem tylko wideo w tagu iFrame, co uniemożliwiło mi późniejsze odwoływanie się do obiektu „player” w JS.
  • Widziałem kilka przykładów w Internecie, w których pierwszy tag skryptu (ten z tagiem src iframe_api) został pominięty, ale zdecydowanie potrzebowałem go, aby to działało.
  • Utworzenie zmiennej „player” na początku skryptu API. Widziałem również kilka przykładów, w których pominięto tę linię.
  • Dodanie tagu id do elementu iFrame, do którego ma się odwoływać skrypt API. Prawie zapomniałem o tej części.
  • Dodanie „enablejsapi = 1” na końcu tagu źródłowego iFrame. To mnie zawiesiło na chwilę, ponieważ początkowo miałem to jako atrybut tagu iFrame, który nie działa / nie działa dla mnie.

Kiedy muszę wstrzymać wideo, po prostu uruchamiam to:

[webView stringByEvaluatingJavaScriptFromString:@"player.pauseVideo();"];

Mam nadzieję, że to pomoże!


Jeśli zastanawiasz się, dlaczego nie ma głosów za, to dlatego, że nie jest to javascript, więc nie jest przydatne w przypadku użycia OP, który jest ramką iframe odwołującą się do adresu URL osadzania YouTube, a nie aplikacji na iOS.
— Vroo

@Vroo Yeah, rozumiem. Chciałem tylko zostawić tę odpowiedź tutaj, na wypadek gdyby przyszła tu inna osoba z iOS i znalazła to pytanie tak, jak ja.
— Brian

0

To działa dobrze dla mnie z odtwarzaczem YT

 createPlayer(): void {
  return new window['YT'].Player(this.youtube.playerId, {
  height: this.youtube.playerHeight,
  width: this.youtube.playerWidth,
  playerVars: {
    rel: 0,
    showinfo: 0
  }
});
}

this.youtube.player.pauseVideo ();


0

Bardziej zwięzła, elegancka i bezpieczna odpowiedź: dodaj „? Enablejsapi = 1” na końcu adresu URL wideo, a następnie utwórz i dodaj do ciągu zwykły obiekt reprezentujący polecenie pauzy:

const YouTube_pause_video_command_JSON = JSON.stringify(Object.create(null, {
    "event": {
        "value": "command",
        "enumerable": true
    },
    "func": {
        "value": "pauseVideo",
        "enumerable": true
    }
}));

Użyj Window.postMessagemetody, aby wysłać wynikowy ciąg JSON do osadzonego dokumentu wideo:

// |iframe_element| is defined elsewhere.
const video_URL = iframe_element.getAttributeNS(null, "src");
iframe_element.contentWindow.postMessage(YouTube_pause_video_command_JSON, video_URL);

Upewnij się, że określasz adres URL wideo dla argumentu Window.postMessagemetody, targetOriginaby upewnić się, że Twoje wiadomości nie zostaną wysłane do żadnego niezamierzonego odbiorcy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.