【问题标题】:Unable to load youtube video using <video> tag where youtube url is inputted in textfield无法使用在文本字段中输入 youtube url 的 <video> 标签加载 youtube 视频
【发布时间】:2018-07-08 03:40:27
【问题描述】:

我正在开发一个模态窗口,它允许用户1.) 粘贴视频网址2.) 从本地驱动器中选择一个文件,然后使用 html5 预览 &lt;video&gt;tag。

选项 2.) 在本地选择视频文件效果很好。但是,当我在输入文本字段上粘贴 youtube 视频 url 时,视频播放器会显示一个加载指示器然后停止。您无法播放视频,并且似乎没有成功加载。

我检查了谷歌浏览器的检查器并收到了这条消息

跨域读取阻塞 (CORB) 阻止了跨域响应 https://www.youtube.com/... MIME 类型为 text/html。

我怀疑问题出在这一行。

$('#modalInput_pasteURL').on('input',function(e){
    var videoUrl = $('#modalInput_pasteURL').val().trim();
    $(".video").attr("src", videoUrl);
});

我在研究时读到,&lt;iframe&gt; 必须用于包含或播放来自 url 的 youtube 视频。在这种情况下,我只想使用&lt;video&gt; 标签,这样我就只有一个视频容器。

我错过了什么?有什么建议吗?

下面是sn-ps的代码

HTML 文件

<label>Paste Url here</label>
<input type="text" class="modal_inputbox" id="modalInput_pasteURL"/><br>

<label>Select Video</label>
<input type="file" class="modalbtn_browseFiles" id="modalBtn_choose_video_file"  value="Browse Video" accept="video/*"/><br>

<label>Video Preview</label>
<div class="modalContainer_filePreview" id="modalContainer_videoPreview">
<video controls class="video" width="510" height="200">
</video >
</div>

JS 文件

$('#modalInput_pasteURL').on('input',function(e){
    var videoUrl = $('#modalInput_pasteURL').val().trim();
    $(".video").attr("src", videoUrl);
});

$("#modalBtn_choose_video_file").on('change',function(event){
    var fileInput = document.getElementById('modalBtn_choose_video_file');
    var fileUrl = window.URL.createObjectURL(fileInput.files[0]);
    $(".video").attr("src", fileUrl);
});

谢谢。

【问题讨论】:

  • 我不记得 YT 视频是由预编码的视频标签播放的。 YT API 使用 iframe
  • @zer00ne 没错,iframe 是最好的选择。我没有意识到这一点,因为我对做前端的东西还很陌生。感谢您的评论。它有帮助。
  • 太好了,如果您希望看到您的代码被修改以便它可以播放两种类型的网址,请查看我的回答。

标签: javascript jquery html


【解决方案1】:

在做了一些研究并考虑到 zer00neAdam McGurk 的评论后,我意识到加载 youtube 视频 url 的最佳方式是通过 @987654321 @然后隔离或获取youtube视频的id的问题出现了。

然后,我最终在SO 找到了相关资源和答案,这解决了我的问题。

function getYoutubeVideoId(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 {
        return 'error';
    }
}

$('#modalInput_pasteURL').on('input',function(e){
    var videoUrl = $('#modalInput_pasteURL').val().trim();
    var videoId = getYoutubeVideoId(videoUrl);
    $('#modalContainer_videoPreview').html('<iframe width="510" height="200" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe>');
});

这应该作为其他人的参考,他们在将 youtube url 粘贴到文本字段中并将其加载到最有效的容器(例如 &lt;iframe&gt;)时达到相同的效果。

【讨论】:

    【解决方案2】:

    可以通过使用&lt;div&gt;&lt;iframe&gt; 标签并加载YouTube IFrame Player API 将YouTube 视频嵌入到网页中。下面的Demo是对OP代码的修改。它可以播放标准视频或 YT 视频。 Stack Snippet 无法在 SO 网站上播放 YouTube 视频,因此要正确测试它,您可以将整个代码复制并粘贴到其他地方或转到此 Plunker

    注意:如果您想加载 YT API 以便以编程方式控制 YT 播放器,则会包含一些注释掉的代码。


    Plunker

    演示

    Demo中评论的细节

    由于沙盒,YouTube 视频无法在 SO 上播放,请转到 Plunker 以获得完整功能的演示


    /* If you want programattic control over the YT Player uncomment
    || the following block and the block after the next block
    */
    /*/ Load YouTube IFrame Player API
    var tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    */
    
    // Reference video tag
    var vid = document.getElementById('vid');
    
    /*/ Declare YT Player
    var ytv;
    // Define YT Player 
    function onYouTubeIframeAPIReady() {
      ytv = new YT.Player('ytv');
    }
    */
    
    // Seup switch behavior
    $('.switchBtn').on('click', function(e) {
      $('.switchBtn').removeClass('act');
      $(e.target).addClass('act');
    });
    
    // Delegate input event to #pasteURL
    $('#pasteURL').on('input', function(e) {
    
      // Get the url string
      var videoUrl = $('#pasteURL').val().trim();
      // if the "Standard Video" switch is active...
      if ($('.v').is('.act')) {
        // ...enable controls on vid...
        vid.controls = true;
        // ...set src to url string...
        vid.src = videoUrl;
        // ...reset vid so it cues new url
        vid.load();
        // ...otherwise...
      } else {
        // ...pause vid...
        vid.pause();
        // ...reset vid...
        vid.currentTime = 0;
        // ...remove vid controls...
        vid.controls = false;
        // ...set ytv src to new url
        $('#ytv').attr('src', videoUrl);
      }
    });
    
    $("#file").on('change', function(event) {
      var fileInput = $('#file')[0];
      var fileUrl = window.URL.createObjectURL(fileInput.files[0]);
      $("#vid").attr("src", fileUrl).prop("controls", true);
    });
    input,
    label {
      display: inline-block;
      font: inherit;
      margin: 10px 0 0 0;
    }
    
    input[type=text] {
      width: 350px;
    }
    
    .group {
      pointer-events: none;
      opacity: 0.4;
    }
    
    .switchBtn {
      width: 110px;
      height: 18px;
      margin: 15px -2px 10px -2px;
      border: 3px outset grey;
      padding: 2px 3px 0;
      cursor: pointer;
    }
    
    .switchBtn.act {
      background: tomato;
      color: #fff
    }
    
    .switchBtn.act~.group {
      pointer-events: auto;
      opacity: 1;
    }
    
    .switchBtn.v {
      border-top-left-radius: 12px;
      border-bottom-left-radius: 12px;
      text-align: right;
    }
    
    .switchBtn.y {
      border-top-right-radius: 12px;
      border-bottom-right-radius: 12px;
    }
    
    .switch {
      display: none
    }
    
    .switch:checked+* {
      height: 405px;
      transition: 1s;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <!--<link rel="stylesheet" href="style.css">-->
    
    </head>
    
    <body>
    
      <label for='vidURL' class='switchBtn v'>Standard Video</label>
    
      <label for='ytvURL' class='switchBtn y'>You Tube Video</label>
      <br>
      <fieldset class='group'>
    
        <label>Test Std URL: </label>
        <input type='text' readonly value='https://ia800209.us.archive.org/24/items/WildlifeSampleVideo/Wildlife.mp4'>
        <br>
        <label>Test YT URL: </label>
        <input type='text' readonly value='https://www.youtube.com/embed/Ch5MEJk5ZCQ?enablejsapi=1'>
        <br>
    
        <label>Paste Url here </label>
        <input type="text" id="pasteURL" />
    
      </fieldset>
    
      <label>Select Video </label>
      <input type="file" id="file" value="Browse Video" accept="video/*" />
      <br>
    
      <label>Video Preview</label>
      <figure class="filePreview">
    
        <input id='vidURL' type='radio' name='switch' class='switch'>
    
        <video id="vid" width="100%" height="0"></video>
    
        <input id='ytvURL' type='radio' name='switch' class='switch'>
    
        <iframe id="ytv" type="text/html" width="100%" height="0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
    
      </figure>
    
    
    
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
      <!--<script src="script.js"></script>-->
    </body>
    
    </html>

    【讨论】:

      【解决方案3】:

      这里有几个问题,甚至不一定与您的代码有关。我什至没有在这里查看您的代码,因为它不重要。

      您将无法获取 YouTube 网址并将其粘贴到 video 标记的 src 属性中并播放。这不是 YouTube 的工作方式。

      1. YouTube 不通过纯 URL 提供视频。想象一下,如果他们这样做,任何人都可以进入检查工具并直接从 YouTube 下载视频。

      那么他们如何投放视频?通过 BLOB:

      1. 下面是对什么是 BLOB 的很好解释:https://developer.mozilla.org/en-US/docs/Web/API/Blob

      因此,您不能只获取 URL,这不是 YouTube 的工作方式。因此,我为您的代码构建框架的方式是使用一个控制语句来检测是否存在 iframe 标签,如果有,则仅插入 iFrame,如果没有,则插入您的视频 URL。

      显然那里存在许多安全漏洞,但这超出了此答案的范围。如果您想走更多我概述的路线,请进行一些研究,提出另一个问题,我们很乐意为您提供帮助!

      【讨论】:

        猜你喜欢
        • 2012-10-22
        • 2016-03-15
        • 2014-01-16
        • 1970-01-01
        • 2012-01-18
        • 1970-01-01
        • 2011-11-23
        • 2013-04-23
        • 1970-01-01
        相关资源
        最近更新 更多