如何使用 HTML 5 仅播放 Youtube 视频的音频?

IT技术 javascript html audio youtube
2021-02-24 19:41:05

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

6个回答

2021 年更新

您可以解析适用于此特定视频的所有流的 Youtube HTML 页面,并提取纯音频流。

这是一个使用公共 Google 图片代理的示例(但您可以使用任何免费或您自己的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();
    })
  }
});
<audio id="youtube" autoplay controls loop></audio>

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

很好的答案。herokuapp 对我来说很新,CORS 是 javascript 无法解决的问题,但这种方法解决了这个问题。
2021-04-21 19:41:05
看起来 YouTube在 2019 年 9 月更改了url_encoded_fmt_stream_mapadaptive_fmts。请参阅下面我的帖子...我稍微修改了您的解决方案以使其正常工作。
2021-04-28 19:41:05
如果不是真的需要,最好在没有 JS 库的情况下展示示例代码。
2021-05-11 19:41:05
它有效,但我认为您从视频信息中遗漏了一些东西......比如签名。
2021-05-13 19:41:05

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

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

是的,这是一个解决方案,但 YouTube 视频广告呢?即使你把它作为背景音乐,用户也会被隐藏的音频广告轰炸。
2021-04-20 19:41:05
它违反 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
2021-04-30 19:41:05
这是否真的违反了 YouTube TOS。据我了解,TOS 仅讨论其 API。嵌入视频播放器并使用 css 隐藏视频不使用 YouTube API。所以我认为它没有违反 YouTube TOS。
2021-05-04 19:41:05
好的..我将上传带有黑色图像的视频并使用黑色背景:D
2021-05-20 19:41:05

2020 年更新

这似乎在Septeber 2019年,YouTube的更新的值由返回get_video_info

而不是data.url_encoded_fmt_stream_mapand data.adaptive_fmts(如在其他旧示例中使用的那样),现在我们正在寻找data.formatsand data.adaptiveFormats

无论如何,这就是将 YouTube 视频加载到<audio>元素中的一些代码在 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;
  }, {});
}
<audio id="youtube" controls></audio>

知道为什么它不适合我吗?这里的代码片段也不起作用。它只显示音频播放器,不播放任何内容。在控制台中,您会收到此错误:无法加载资源:服务器以 403 状态响应(禁止,请参阅cors-anywhere.herokuapp.com/corsdemo
2021-04-27 19:41:05

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

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

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>
感谢您的回答。有没有办法在特定时间开始和停止音频?要使用的属性是什么?
2021-04-24 19:41:05
您可以通过在 youtube 网址中添加这些查询参数来实现这一点: start=00:30&end=03:20
2021-05-18 19:41:05