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

Posted

技术标签:

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

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

【问题讨论】:

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   
  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 values 由 get_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;

【讨论】:

嗨,欢迎来到 SO !请阅读How to write a good answer!包括有关您的解决方案的一些背景和解释!【参考方案11】:

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

通过 CSS...

 filter: brightness(0%);

通过 JS...

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

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

【讨论】:

虽然这可能有效,但在数据使用方面效率非常低,因为视频数据仍将在后台加载,并且比音频数据量大得多。

以上是关于如何使用 HTML 5 仅播放 Youtube 视频的音频?的主要内容,如果未能解决你的问题,请参考以下文章

强制 YouTube 播放列表为 HTML5 播放

YouTube 限制播放问题

YouTube 视频的播放速度控制? HTML5?

FFmpeg学习5:多线程播放视音频

如何仅流式传输来自 YouTube 的视频的声音? [关闭]

如何在我的应用程序上仅流式传输来自 youtube 视频的音频数据?