Как приостановить проигрыватель YouTube при скрытии iframe?

86

У меня есть скрытый div, содержащий видео YouTube в формате <iframe>. Когда пользователь щелкает ссылку, этот div становится видимым, и пользователь должен иметь возможность воспроизводить видео.

Когда пользователь закрывает панель, воспроизведение видео должно прекращаться. Как я могу этого добиться?

Код:

<!-- 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-Джон
источник
Я не уверен, но вам, возможно, придется найти способ остановить видео или удалить видео из div, а не просто скрыть его ..
анири
вы должны принять ответ.
snymkpr 07

Ответы:

188

Самый простой способ реализовать такое поведение является вызовом pauseVideoи playVideoметоды, когда это необходимо. Вдохновленный результатом моего предыдущего ответа , я написал функцию без плагинов для достижения желаемого поведения.

Единственные корректировки:

  • Я добавил функцию, toggleVideo
  • Я добавил ?enablejsapi=1в URL-адрес YouTube, чтобы включить функцию

Демо: http://jsfiddle.net/ZcMkt/
Код:

<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
Да, определенно нужен зеленый флажок, если это сработало. Я тоже использую это решение - отличный материал, у меня есть эти видеокадры в jQueryUI Accordion, поэтому мне нужно прикрепить его к каждому событию запуска.
jeffkee
Просто хотел отметить, что, к сожалению, API YouTube заставляет вас использовать двойные кавычки для сообщения, отправляемого через postMessage. Например, вы не можете переключиться на внешние двойные кавычки и внутренние одинарные кавычки.
Jordan
1
@Jordan В этом есть смысл, потому что ожидается, что сообщение будет в формате JSON. JSON по определению использует двойные кавычки для обозначения ключей и значений.
Rob W
2
Если кому-то интересно, я обновил код, чтобы остановить воспроизведение видео, когда вы нажимаете кнопку «Закрыть» в модальном окне 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": ""}', '*');});
Райан Уолтон,
10
Обратите внимание, что вы должны добавить ?enablejsapi=1к URL-адресу внедрения iframe вот так: <iframe class="embed-responsive-item" src="//www.youtube.com/embed/WIZUeIDFALw?html5=1&enablejsapi=1" allowfullscreen></iframe>иначе это не сработает :)
dineth 01
23

Вот пример jQuery ответа RobW для использования скрытия / приостановки iframe в модальном окне:

    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":""}', '*');
        }
    }

Упомянутые элементы html - это сам модальный div (# video-div), вызывающий методы show / hide, и iframe (# video-iframe), который имеет URL-адрес видео, как src = "", и суффикс enablejsapi = 1. ? который обеспечивает программное управление плеером (например,

Для получения дополнительной информации о html см. Ответ RobW.

DrewT
источник
5
Какая улучшенная читаемость меняла? условно для if / else, но спасибо, что начали меня с этого. Я просто почувствовал, что мне есть что добавить, вот и все.
DrewT 06
15

Вот простой фрагмент jQuery для приостановки всех видео на странице, основанный на ответах RobW и DrewT:

jQuery("iframe").each(function() {
  jQuery(this)[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*')
});
квартирник
источник
если вы не хотите использовать jQuery, код внутри функции 'each' останется таким же после отмены ссылки на объект jQuery. то есть node.contentWindow. ...
mattdlockyer
Как мне отменить это, чтобы снова воспроизвести, когда видео снова отображается?
Карл
Просто замените pauseVideo на playVideo. Пример: jsfiddle.net/ora2kqzq/1
квартирник
Это больше не работает ... даже когда я пытаюсь, {"event":"command","func":"playVideo","args":[],"id":1,"channel":"widget"}после {"event":"listening","id":1,"channel":"widget"}чего YT.Player iframe api публикует на YouTube Embed.
NoBugs 08
9

Эй, простой способ - просто установить для src видео значение none, чтобы видео исчезало, пока оно скрыто, а затем установите src обратно на видео, которое вы хотите, когда вы нажимаете ссылку, которая открывает видео ... чтобы сделать которые просто устанавливают идентификатор для iframe youtube и вызывают функцию src, используя этот идентификатор, например:

<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
Предупреждение: Изменения к iframe«s srcс Javascript непреднамеренно нажать на window.history, вызывая проблемы кнопки назад.
Джордан Арсено
Спасибо, Джордан! Я просто начал использовать этот ответ и не знал об этом. Лучше узнать сейчас, чем позже :)
MMachinegun
Справедливое предупреждение всем, кто пробует этот метод: это может вызвать чрезвычайно заметную задержку, если вы используете его для переключения между div, которые содержат встроенные iframe для YouTube. Быть осторожен.
Мухаммад Абдул-Рахим
6

Поскольку вам необходимо установить ?enablejsapi=truesrc iframe, прежде чем вы сможете использовать команды playVideo/, pauseVideoупомянутые в других ответах , может быть полезно добавить это программно через Javascript (особенно если, например, вы хотите, чтобы это поведение применялось к видео, встроенным другими пользователи, которые только что скопировали и вставили код для встраивания YouTube). В этом случае может пригодиться что-то вроде этого:

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";
    }
  }
}

... если вы вызовете это, document.readyвсе iframe в div с классом "video" будут enablejsapi=trueдобавлены в свой источник, что позволяет командам playVideo / pauseVideo работать с ними.

(nb. в этом примере используется jQuery для одной устанавливаемой строки var iframes, но общий подход должен работать так же хорошо с чистым Javascript, если вы не используете jQuery).

Ник Ф
источник
5

Вы можете остановить видео, вызвав stopVideo()метод в экземпляре проигрывателя YouTube, прежде чем скрывать div, например

player.stopVideo()

Дополнительную информацию см. Здесь: http://code.google.com/apis/youtube/js_api_reference.html#Playback_controls.

Дэвид
источник
что такое объект игрока и как получить к нему доступ? Я получаю player is undefined, а видео все еще воспроизводится
Claudiu
Он доступен, когда вы создали его с помощью JS API.
Дэвид
4

Путь RobW отлично сработал для меня. Для людей, использующих jQuery, вот упрощенная версия, которую я в итоге использовал:

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

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

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

В этом примере video_player является родительским элементом div, содержащим iframe.

skribbz14
источник
4

Я хотел поделиться решением, которое я придумал, используя jQuery, который работает, если у вас есть несколько видеороликов YouTube, встроенных на одну страницу. В моем случае я определил модальное всплывающее окно для каждого видео следующим образом:

<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>

В этом случае videoModalXX представляет собой уникальный идентификатор видео. Затем следующая функция останавливает видео:

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

Мне нравится этот подход, потому что он приостанавливает воспроизведение видео с того места, где вы остановились, на случай, если вы захотите вернуться и продолжить просмотр позже. Это хорошо работает для меня, потому что он ищет iframe внутри модального видео с определенным идентификатором. Никакого специального идентификатора элемента YouTube не требуется. Надеюсь, кому-то это тоже пригодится.

Полдон
источник
Это отлично работало без тонны кода. У меня есть несколько видеороликов YT на странице, и я просто показываю большой палец YT, и мне нужно решение для остановки / паузы. И, изменив pauseVideo на playVideo, я смог запустить видео, когда оно расширилось до полной ширины столбца
WebDude0482
2

просто удалите src iframe

$('button.close').click(function(){
    $('iframe').attr('src','');;
});
Rakesh Kejriwal
источник
Но он может захотеть продолжить игру, когда пользователь щелкнет мышью.
Coda Chang
брат, onclick снова добавьте src через jquery, это сработает
rakesh kejriwal 06
1

Ответ Роба В. помог мне понять, как приостановить видео поверх iframe, когда слайдер скрыт. Тем не менее, мне потребовались некоторые модификации, прежде чем я смог заставить его работать. Вот фрагмент моего 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>

Заметим , что это работает на localhosts , а также как Rob W упоминается « enablejsapi = 1 » была добавлена в конце видео URL.

Ниже приведен мой файл 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":""}', '*');
}; 

Также, как более простой пример, проверьте это на JSFiddle

Фахим Хоссейн
источник
1

Для этого подхода требуется jQuery. Сначала выберите свой iframe:

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

Теперь вы выбираете кнопку воспроизведения / паузы этого iframe и нажимаете на нее

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

Надеюсь, это вам поможет.

hong4rc
источник
0

Ответы RobW здесь и в других местах были очень полезны, но я обнаружил, что мои потребности были намного проще. Я отвечал на это в другом месте , но, возможно, и здесь это будет полезно.

У меня есть метод, в котором я формирую HTML-строку для загрузки в 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];

Вы можете игнорировать стили в подготовленной строке HTML. Важными аспектами являются:

  • Использование API для создания объекта «YT.player». В какой-то момент у меня было только видео в теге iFrame, и это помешало мне впоследствии ссылаться на объект «player» с помощью JS.
  • Я видел несколько примеров в Интернете, где первый тег скрипта (тот, что с тегом iframe_api src) опущен, но мне определенно это нужно, чтобы это работало.
  • Создание переменной "player" в начале скрипта API. Я также видел несколько примеров, в которых эта строка опускалась.
  • Добавление тега id в iFrame, на который будет ссылаться сценарий API. Я чуть не забыл эту часть.
  • Добавление enablejsapi = 1 в конец тега iFrame src. Это меня на время подвесило, так как изначально это было атрибутом тега iFrame, который у меня не работает / не работает.

Когда мне нужно приостановить видео, я просто запускаю это:

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

Надеюсь, это поможет!

Брайан
источник
Если вам интересно, почему нет голосов, это потому, что это не javascript, поэтому он бесполезен для варианта использования OP, который представляет собой iframe, ссылающийся на URL-адрес для встраивания youtube, а не на приложение iOS.
Vroo 03
@Vroo Да, я понял. Просто хотел оставить этот ответ здесь на случай, если другой пользователь iOS пришел сюда и нашел этот вопрос, как и я.
Брайан
0

У меня это нормально работает с проигрывателем 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
источник
0

Более краткий, элегантный и безопасный ответ: добавьте «? Enablejsapi = 1» в конец URL-адреса видео, а затем создайте и преобразуйте обычный объект, представляющий команду паузы:

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

Используйте этот Window.postMessageметод для отправки полученной строки JSON во встроенный видео документ:

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

Убедитесь, что вы указали URL-адрес видео в Window.postMessageкачестве targetOriginаргумента метода, чтобы гарантировать, что ваши сообщения не будут отправлены непреднамеренному получателю.

Патрик Дарк
источник