【问题标题】:How to play only the audio of a Youtube video using HTML 5?如何使用 HTML 5 仅播放 Youtube 视频的音频?
【发布时间】:2012-01-31 04:38:28
【问题描述】:

是否可以使用 HTML 5 和 Javascript 仅播放 YouTube 视频中的音频?

【问题讨论】:

  • youtube 提供视频,因此只有视频从他们的服务器流式传输,除非他们有一个不太可能的纯音频选项。

标签: javascript html audio youtube


【解决方案1】:

嵌入视频播放器并使用 CSS 隐藏视频。如果操作得当,您甚至可以只隐藏视频而不是其下方的控件。

但是,我建议不要这样做,因为它会违反YouTube TOS。如果您真的只想播放音频,请改用您自己的服务器。

【讨论】:

  • 违反服务条款:[Prohibited] separate, isolate, or modify the audio or video components of any YouTube audiovisual content made available through the YouTube API;code.google.com/apis/youtube/terms.html
  • 好吧..我将上传带有黑色图像的视频并使用黑色背景:D
  • 确实违反了 YouTube TOS。据我了解,TOS 仅谈论其 API。嵌入视频播放器并使用 css 隐藏视频不使用 YouTube API。所以我认为它没有违反 YouTube TOS。
  • 是的,这是一个解决方案,但 YouTube 视频广告呢?即使您将其作为背景音乐,用户也会被隐藏的音频广告轰炸。
【解决方案2】:

我同意 Tom van der Woerdt 的观点。您可以使用 CSS 隐藏视频(可见性:隐藏或溢出:隐藏在受高度限制的 div 包装器中),但这可能违反 Youtube 的政策。此外,您如何控制音频(暂停、停止、音量等)?

您可以转而使用 http://www.houndbite.com/ 等资源来管理音频。

【讨论】:

  • 其他资源似乎是最好的解决方案
【解决方案3】:

答案很简单: 使用第三方产品,如 jwplayer 或类似产品, 然后将其设置为最小播放器尺寸,即音频播放器尺寸(仅显示播放器控件)。

瞧。

使用这个已经超过 8 年了。

【讨论】:

  • 这并没有真正为现有答案添加任何内容。
  • 当然可以。它让我们知道 jwplayer 是一个可行的替代方案。
  • “使用 html5 和 javascript”不是一个可行的替代方案。
  • 这是否仍会花费您流式传输视频的数据?
【解决方案4】:

这可能是一个旧帖子,但人们可能仍在搜索它,所以你去吧:

<div style="position:relative;width:267px;height:25px;overflow:hidden;">
<div style="position:absolute;top:-276px;left:-5px">
<iframe width="300" height="300" 
  src="https://www.youtube.com/embed/youtubeID?rel=0">
</iframe>
</div>
</div>

【讨论】:

    【解决方案5】:

    除了提到 jwplayer 和可能违反 TOS 的情况外,我想链接到 github 上的以下存储库:YouTube Audio Player Generation Library,它允许生成以下输出:

    根据视频 URL 和配置选项,库支持播放列表和 PHP 自动渲染。

    【讨论】:

    • 这是一个不错的链接,但它使用的是 Flash Player,而不是 HTML5。
    • @mbomb007,很好,完全忘记了标题中的 HTML5!不过,我会留下答案,因为如果人们没有纯 HTML 要求,他们可能仍会登陆此页面。
    【解决方案6】:

    2021 年更新

    您可以为该特定视频的所有可用流解析 Youtube HTML 页面并提取仅音频流。

    这是一个使用公共 Google Image 代理的示例(但您可以使用任何免费的或您自己的 CORS 代理):

    var vid = "3r_Z5AYJJd4",
      audio_streams = {},
      audio_tag = document.getElementById('youtube');
    
    fetch("https://images" + ~~(Math.random() * 33) + "-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURIComponent("https://www.youtube.com/watch?hl=en&v=" + vid)).then(response => {
      if (response.ok) {
        response.text().then(data => {
    
          var regex = /(?:ytplayer\.config\s*=\s*|ytInitialPlayerResponse\s?=\s?)(.+?)(?:;var|;\(function|\)?;\s*if|;\s*if|;\s*ytplayer\.|;\s*<\/script)/gmsu;
    
          data = data.split('window.getPageData')[0];
          data = data.replace('ytInitialPlayerResponse = null', '');
          data = data.replace('ytInitialPlayerResponse=window.ytInitialPlayerResponse', '');
          data = data.replace('ytplayer.config={args:{raw_player_response:ytInitialPlayerResponse}};', '');
    
    
          var matches = regex.exec(data);
          var data = matches && matches.length > 1 ? JSON.parse(matches[1]) : false;
    
          console.log(data);
    
          var streams = [],
            result = {};
    
          if (data.streamingData) {
    
            if (data.streamingData.adaptiveFormats) {
              streams = streams.concat(data.streamingData.adaptiveFormats);
            }
    
            if (data.streamingData.formats) {
              streams = streams.concat(data.streamingData.formats);
            }
    
          } else {
            return false;
          }
    
          streams.forEach(function(stream, n) {
            var itag = stream.itag * 1,
              quality = false;
            console.log(stream);
            switch (itag) {
              case 139:
                quality = "48kbps";
                break;
              case 140:
                quality = "128kbps";
                break;
              case 141:
                quality = "256kbps";
                break;
            }
            if (quality) audio_streams[quality] = stream.url;
          });
    
          console.log(audio_streams);
    
          audio_tag.src = audio_streams['128kbps'];
          audio_tag.play();
        })
      }
    });
    &lt;audio id="youtube" autoplay controls loop&gt;&lt;/audio&gt;

    不适用于所有视频,很大程度上取决于获利设置或类似设置。

    【讨论】:

    • 不错的答案。 herokuapp 对我来说很新,CORS 是 javascript 无法解决的问题,但该方法解决了问题。
    • 如果没有 JS 库,最好提供示例代码,如果它们不是真的需要的话。
    • 它有效,但我认为你在视频信息中遗漏了一些东西......比如签名。
    • YouTube 似乎在 2019 年 9 月更改了 url_encoded_fmt_stream_mapadaptive_fmts。请参阅下面的帖子...我稍微修改了您的解决方案以使其正常工作。
    【解决方案7】:

    VIDEO_ID 与您的 YouTube 视频的实际 ID。

    <div data-video="VIDEO_ID"  
            data-autoplay="0"         
            data-loop="1"             
            id="youtube-audio">
     </div>
    
     <script src="https://www.youtube.com/iframe_api"></script>
     <script src="https://cdn.rawgit.com/labnol/files/master/yt.js"></script>
    

    【讨论】:

    • 感谢您的回答。有没有办法在特定时间开始和停止音频?要使用哪些属性?
    • 您可以通过在 youtube url 中添加这些查询参数来实现此目的:start=00:30&amp;end=03:20
    【解决方案8】:

    var vid = "bpt84ceWAY0",
        audio_streams = {},
        audio_tag = document.getElementById('youtube');
    
    fetch("https://"+vid+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https%3A%2F%2Fwww.youtube.com%2Fget_video_info%3Fvideo_id%3D" + vid).then(response => {
        if (response.ok) {
            response.text().then(data => {
    
                var data = parse_str(data),
                    streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(',');
    
                streams.forEach(function(s, n) {
                    var stream = parse_str(s),
                        itag = stream.itag * 1,
                        quality = false;
                    console.log(stream);
                    switch (itag) {
                        case 139:
                            quality = "48kbps";
                            break;
                        case 140:
                            quality = "128kbps";
                            break;
                        case 141:
                            quality = "256kbps";
                            break;
                    }
                    if (quality) audio_streams[quality] = stream.url;
                });
    
                console.log(audio_streams);
    
                audio_tag.src = audio_streams['128kbps'];
                audio_tag.play();
            })
        }
    });
    
    function parse_str(str) {
        return str.split('&').reduce(function(params, param) {
            var paramSplit = param.split('=').map(function(value) {
                return decodeURIComponent(value.replace('+', ' '));
            });
            params[paramSplit[0]] = paramSplit[1];
            return params;
        }, {});
    }
    &lt;audio id="youtube" autoplay controls loop&gt;&lt;/audio&gt;

    【讨论】:

      【解决方案9】:

      2020 年更新

      似乎在 2019 年 9 月,YouTube updated the valuesget_video_info 返回。

      现在我们正在寻找data.formatsdata.adaptiveFormats,而不是data.url_encoded_fmt_stream_mapdata.adaptive_fmts(在其他较早的示例中使用)。

      不管怎样,这就是一些将 YouTube 视频加载到 &lt;audio&gt; 元素中的代码Try it on CodePen

      // YouTube video ID
      var videoID = "CMNry4PE93Y";
      
      // Fetch video info (using a proxy to avoid CORS errors)
      fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
        if (response.ok) {
          response.text().then(ytData => {
            
            // parse response to find audio info
            var ytData = parse_str(ytData);
            var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
            var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
            
            // get the URL for the audio file
            var audioURL = getAdaptiveFormats[findAudioInfo].url;
            
            // update the <audio> element src
            var youtubeAudio = document.getElementById('youtube');
            youtubeAudio.src = audioURL;
            
          });
        }
      });
      
      function parse_str(str) {
        return str.split('&').reduce(function(params, param) {
          var paramSplit = param.split('=').map(function(value) {
            return decodeURIComponent(value.replace('+', ' '));
          });
          params[paramSplit[0]] = paramSplit[1];
          return params;
        }, {});
      }
      &lt;audio id="youtube" controls&gt;&lt;/audio&gt;

      【讨论】:

      • 知道为什么它不适合我吗?这里的代码 sn-p 也不起作用。它只显示一个音频播放器,不播放任何内容。在控制台中,您会收到此错误:加载资源失败:服务器响应状态为 403(禁止,请参阅cors-anywhere.herokuapp.com/corsdemo
      【解决方案10】:

      // YouTube video ID
      var videoID = "CMNry4PE93Y";
      
      // Fetch video info (using a proxy to avoid CORS errors)
      fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
        if (response.ok) {
          response.text().then(ytData => {
            
            // parse response to find audio info
            var ytData = parse_str(ytData);
            var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
            var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
            
            // get the URL for the audio file
            var audioURL = getAdaptiveFormats[findAudioInfo].url;
            
            // update the <audio> element src
            var youtubeAudio = document.getElementById('youtube');
            youtubeAudio.src = audioURL;
            
          });
        }
      });
      
      function parse_str(str) {
        return str.split('&').reduce(function(params, param) {
          var paramSplit = param.split('=').map(function(value) {
            return decodeURIComponent(value.replace('+', ' '));
          });
          params[paramSplit[0]] = paramSplit[1];
          return params;
        }, {});
      }
      &lt;audio id="youtube" controls&gt;&lt;/audio&gt;

      【讨论】:

      【解决方案11】:

      作为替代答案,您可以将视频的亮度设置为零,视频区域将全黑,而控件仍然可见...

      通过 CSS...

       filter: brightness(0%);
      

      通过 JS...

       V.style.filter='brightness(0%)';
      

      注意:亮度的正常默认值为 100%。

      【讨论】:

      • 虽然这可能有效,但在数据使用方面效率非常低,因为视频数据仍将在后台加载,并且比音频数据量大得多。
      猜你喜欢
      • 2017-02-28
      • 1970-01-01
      • 2013-08-14
      • 2013-03-02
      • 2011-02-02
      • 2018-05-19
      • 1970-01-01
      相关资源
      最近更新 更多