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 -->
0161-Jon
źródło
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>
Rob W
źródło
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.

DrewT
źródło
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":""}', '*')
});
kwaterarz
źródło
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>
Paula
źródło
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).

Nick F.
źródło
5

Możesz zatrzymać wideo, dzwoniąc pod numer stopVideo() metodę w instancji odtwarzacza YouTube przed ukryciem div np

player.stopVideo()

Więcej informacji można znaleźć tutaj: http://code.google.com/apis/youtube/js_api_reference.html#Playback_controls

david
źródło
co to jest obiekt gracza i jak uzyskujesz do niego dostęp? Otrzymuję odtwarzacz jest nieokreślony, a wideo nadal jest odtwarzane
Claudiu Creanga
Jest dostępny, gdy utworzyłeś go za pomocą JS API.
david
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.

skribbz14
źródło
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.

Poldon
źródło
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','');;
});
rakesh kejriwal
źródło
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

Fahim Hossain
źródło
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.

hong4rc
źródło
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!

Brian
źródło
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 ();

HuyLe
źródło
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.

Patrick Dark
źródło