使用HTML视频标签播放m3u8文件

83
我试图使用HTTP Live Streaming(HLS)将视频流传输到我的电脑和iPhone。在阅读了苹果公司的“HTTP Live Streaming概述”以及“为iPhone和iPad创建和部署HTTP Live Streaming媒体的最佳实践”之后,我有点困惑。
我拿出了源文件(一个mkv文件),并使用ffmpeg将其编码为MPEG-TS格式,并采用了苹果推荐的设置和基线3.0配置文件。
ffmpeg -i "example.mkv" -f mpegts -threads:v 4 -sws_flags bicubic -vf "scale=640:352,setdar=16/9,ass=sub.ass" -codec:v libx264 -r 29.970 -b:v 1200k -profile:v baseline -level:v 3.0 -movflags faststart -coder 1 -flags +loop -cmp chroma -partitions +parti8x8+parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 239 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -direct-pred 1 -fast-pskip 1 -af "aresample=48000" -codec:a libvo_aacenc -b:a 96k -ac 2  -y "output.ts"

没有问题。我使用了一个预编译分段工具来对视频进行分段,并构建了一个.m3u8播放列表。生成的文件看起来像这样:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:10,
http://localhost/media/stream/stream-1.ts
#EXTINF:10,
http://localhost/media/stream/stream-2.ts
#EXTINF:10,
http://localhost/media/stream/stream-3.ts
#EXT-X-ENDLIST

我检查了一些与HTTP Live Streaming一起使用的示例播放列表文件,并没有发现任何问题。我还尝试在VLC中播放.m3u8文件,效果非常好。
我创建了一个HTML页面来播放文件:
<html lang="en">
    <head>
        <meta charset=utf-8/>
    </head>
    <body>
        <div id='player'>
            <video width="352" height="288" src="stream.m3u8" controls autoplay>
            </video>
        </div>
    </body>
</html>

这个页面在Chrome、Safari和我的iPhone上都无法正常工作。w3schools上的HTML5视频标签示例在我的电脑上可以正常工作,而上面提到的官方苹果概述给出了一个与我的页面非常相似的HTML示例。然而,当我访问自己的.m3u8页面时,我的视频播放器完全没有响应。

1
你能展示mediastreamvalidator工具的输出吗? - vipw
1
谢谢回复!不幸的是,我还没有花钱成为“真正”的苹果开发者,所以我没有那个特定的工具。我一直在寻找一个可能的替代品,但成功率很低。如果您有任何建议,欢迎提供! - drucifer
2
也许你可以把文件放在公共网络服务器上。如果你需要一个免费的网络服务器,可以使用微型Amazon EC2实例。这样,有权限访问更多工具的人就可以查看了。实际上,这让我想到了你的Web服务器返回的MIME类型...看看这个是否有帮助:http://stackoverflow.com/questions/6438680/http-live-streaming-not-working-on-apache/15696465 - vipw
2
你尝试过直接在Safari中浏览m3u8文件而不是通过HTML吗?例如,如果你的m3u8文件存在于服务器上的http://myserver/mymoviue.m3u8下,那么在这里浏览应该会显示视频。如果这样仍然无法解决问题,那么你的问题就不在HTML中。 - NiRR
1
HLS仍未被Windows桌面版Chrome原生支持 https://caniuse.com/#search=hls 但在我的老iPhone上正常工作。 - Ryan
这个回答是否解决了你的问题?iOS/Safari 上的HLS视频流 - Amo Wu
6个回答

72

可能有点晚了,但你需要在视频标签中提供MIME类型属性:type="application/x-mpegURL"。我用于16:9流的视频标签如下所示。

<video width="352" height="198" controls>
    <source src="playlist.m3u8" type="application/x-mpegURL">
</video>

39
如果有其他人测试此答案,应注意它在Chrome浏览器上无法使用。在Edge浏览器中正常工作。请查看此答案以获取有关解决浏览器兼容性的更多信息。 - Mauricio Arias Olave
4
由于Chrome不支持原生的HLS播放,所以在仅使用视频标签时,无法在Chrome上流式传输HLS。 - HeidiWF
它在我的Edge浏览器中无法播放。也许是因为我正在使用video-react包。 - Zeeshan Ahmad Khalil

46

您可以使用video js库轻松播放HLS视频。它允许直接播放视频。

<!-- CSS  -->
 <link href="https://vjs.zencdn.net/7.2.3/video-js.css" rel="stylesheet">


<!-- HTML -->
<video id='hls-example'  class="video-js vjs-default-skin" width="400" height="300" controls>
<source type="application/x-mpegURL" src="http://www.streambox.fr/playlists/test_001/stream.m3u8">
</video>


<!-- JS code -->
<!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
<script src="https://vjs.zencdn.net/ie8/ie8-version/videojs-ie8.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.14.1/videojs-contrib-hls.js"></script>
<script src="https://vjs.zencdn.net/7.2.3/video.js"></script>

<script>
var player = videojs('hls-example');
player.play();
</script>

GitHub Video Js


videojs 在 iOS 上无法播放我的加密 HLS 视频。 - Ryan
video.js已经重写:https://github.com/videojs/http-streaming 向后兼容HLS和Dash,同时支持加密。 - Chris Hayes

18
标准的HTML5视频播放器直接支持MP4、WebM、3gp和OGV格式。
    <video controls>
      <source src=http://techslides.com/demos/sample-videos/small.webm type=video/webm>
      <source src=http://techslides.com/demos/sample-videos/small.ogv type=video/ogg>
      <source src=http://techslides.com/demos/sample-videos/small.mp4 type=video/mp4>
      <source src=http://techslides.com/demos/sample-videos/small.3gp type=video/3gp>
    </video>

我们可以在 Web 应用程序中添加外部的 HLS js 脚本。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=utf-8 />
    <title>Your title</title>
      
    
      <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
      <script src="https://unpkg.com/video.js/dist/video.js"></script>
      <script src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script>
       
    </head>
    <body>
      <video id="my_video_1" class="video-js vjs-fluid vjs-default-skin" controls preload="auto"
      data-setup='{}'>
        <source src="https://cdn3.wowza.com/1/ejBGVnFIOW9yNlZv/cithRSsv/hls/live/playlist.m3u8" type="application/x-mpegURL">
      </video>
      
    <script>
    var player = videojs('my_video_1');
    player.play();
    </script>
      
    </body>
    </html>

10
<html>
<body>
    <video width="600" height="400" controls>
        <source src="index.m3u8" type="application/x-mpegURL">
    </video>
</body> 

使用以上代码流式传输HLS或m3u8文件。

在桌面端,ms edge浏览器可用(与桌面版chrome浏览器不兼容)。 在移动端,chrome、opera mini浏览器可用。

要在所有浏览器上播放,请使用基于Flash的媒体播放器。 支持所有浏览器的媒体播放器


如果您想播放直接的.m3u8(HLS文件),那么请从Chrome Web应用商店中添加名为“Native HLS Playback”的Chrome扩展程序。 - Rakyesh Kadadas
3
这个解决方案不起作用。我在Firefox和Chrome上都试过了。即使安装了Native HLS Playback,也没用。 - smartmouse

8

补充ben.bourdin的答案,您可以在任何基于HTML的应用程序中检查浏览器是否支持其视频元素中的HLS:

假设您的视频元素ID为“myVideo”,则可以通过JavaScript使用“canPlayType”函数(http://www.w3schools.com/tags/av_met_canplaytype.asp

var videoElement = document.getElementById("myVideo");
if(videoElement.canPlayType('application/vnd.apple.mpegurl') === "probably" || videoElement.canPlayType('application/vnd.apple.mpegurl') === "maybe"){
    //Actions like playing the .m3u8 content
}
else{
    //Actions like playing another video type
}

canPlayType函数返回:

当浏览器不支持指定的音频/视频类型时,返回""

当浏览器可能支持指定的音频/视频类型时,返回"maybe"

当浏览器很可能支持指定的音频/视频类型时(您可以仅使用此值进行验证以更确保您的浏览器支持指定的类型),返回"probably"

希望这有所帮助 :)

最好的问候!


6

使用Flowplayer:

<link rel="stylesheet" href="//releases.flowplayer.org/7.0.4/commercial/skin/skin.css">
    <style>

   </style>
   <script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
  <script src="//releases.flowplayer.org/7.0.4/commercial/flowplayer.min.js"></script>
  <script src="//releases.flowplayer.org/hlsjs/flowplayer.hlsjs.min.js"></script> 
  <script>
  flowplayer(function (api) {
    api.on("load", function (e, api, video) {
      $("#vinfo").text(api.engine.engineName + " engine playing " + video.type);
    }); });
  </script>

<div class="flowplayer fixed-controls no-toggle no-time play-button obj"
      style="    width: 85.5%;
    height: 80%;
    margin-left: 7.2%;
    margin-top: 6%;
    z-index: 1000;" data-key="$812975748999788" data-live="true" data-share="false" data-ratio="0.5625"  data-logo="">
      <video autoplay="true" stretch="true">

         <source type="application/x-mpegurl" src="http://live.wmncdn.net/safaritv2/live2.stream/index.m3u8">
      </video>   
   </div>

flowplayer.org网站提供了不同的方法。


这里的api是什么? - OwlR
以上代码没有显示任何内容。为什么?将 <script> flowplayer(function(api) {... 注释掉后,媒体播放器屏幕会在浏览器中显示。为什么?脚本标签内出了问题吗?有人可以帮忙吗? - OwlR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接