iOS/Safari 上的 Hls 视频流

Posted

技术标签:

【中文标题】iOS/Safari 上的 Hls 视频流【英文标题】:Hls video streaming on iOS/Safari 【发布时间】:2017-09-03 09:01:00 【问题描述】:

我正在尝试使用 Aframe 在 safari ios 上流式传输 hls,该框架下具有三个.js。但视频显示黑屏,仅播放音频。视频 src 的类型为 .m3u8。我试图阅读很多相关的帖子,但似乎没有一个合适的解决方案。让 HLS 和 WebGL 在 iOS 上运行是不是一厢情愿?如果没有,请有人帮我解决一下。

关于 github 上可用问题的几个讨论:

HLS m3u8 video streaming

HLS on Safari

【问题讨论】:

Web 服务器使用哪些 MIME 类型以及视频片段使用哪些编解码器?奇怪的是,苹果不支持他们自己开发的系统。 【参考方案1】:

你的问题:

让 HLS 和 WebGL 在 iOS 上运行是不是一厢情愿?

是的,一厢情愿 :-) 问题/问题/错误出在 Apple,而不是任何库。不管是什么 JS 库,A-FrameThree 等,这在 iOS 中的任何浏览器(iOS 上的所有浏览器基本上都是 Safari 的包装器)和 OSX Safari 上都是一个问题。

问题是这样的(根据我的理解):

    在 WebGL 历史的某个时刻,对跨域内容(视频、图像等)存在限制。我找不到这方面的来源,但我记得在某处读过它,所以这可能不是 100% 准确的。 最近(几年前?2015 年?)所有主流浏览器都得出结论,在 WebGL 中使用的跨域媒体是安全的。 Apple/Safari 除外。 对于大多数浏览器,<video> 元素上的crossorigin 属性可能表明此内容来自其他来源。在 Safari 中,无论出于何种原因,此属性都被忽略或未实现。事实上,它看起来像 Safari 所基于的 WebKit,fixed this as far back as 2015,但苹果仍然没有实现它。甚至苹果refuses to comment on any progress。

可能的解决方法:

    Safari 上的 WebGL 适用于渐进式(不是像 HLS/Dash 这样的流).mp4 视频。在 iOS/Safari 中查看 Facebook(网站,而非应用)上的任何 360 度视频,您会注意到来源是 .mp4。 使用 HLS(或 Dash),但播放视频平面,不使用 WebGL。查看 YouTube 上的任何 360 度视频(网站,而不是应用程序),我认为他们正在使用 HLS 或 Dash,但关键是他们流式传输视频,而 Facebook 没有。

这是真正问题的一个很好的起点:link。

这是另一个详细的帖子:link。

【讨论】:

提供的链接谈到 CORS 是问题所在,如果您从托管 hls 播放器的同一网络服务器流式传输视频,这仍然是一个问题吗? 这可能行得通。我已经有一段时间没有使用这项技术了,但是我们的视频很大并且托管在 CDN 后面,所以即使是代理流也会引起问题。不过,它可能在本地工作。【参考方案2】:

https://github.com/video-dev/hls.js#compatibility

请注意:iOS Safari“Mobile”不支持 MediaSource API。 然而,Safari 浏览器通过普通的内置 HLS 支持 视频“标签”源 URL。看上面的例子(Getting Started)来运行 适当的特征检测并在使用 Hls.js 或 原生内置 HLS 支持。

当平台既不支持 MediaSource 也不支持原生 HLS 时,您 将无法播放 HLS。

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<!-- Or if you want a more recent canary version -->
<!-- <script src="https://cdn.jsdelivr.net/npm/hls.js@canary"></script> -->
<video id="video"></video>
<script>
  var video = document.getElementById('video');
  if (Hls.isSupported()) 
    var hls = new Hls();
    hls.loadSource('https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8');
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function() 
      video.play();
    );
  
  // hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
  // When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element through the `src` property.
  // This is using the built-in support of the plain video element, without using hls.js.
  // Note: it would be more normal to wait on the 'canplay' event below however on Safari (where you are most likely to find built-in HLS support) the video.src URL must be on the user-driven
  // white-list before a 'canplay' event will be emitted; the last video event that can be reliably listened-for when the URL is not on the white-list is 'loadedmetadata'.
  else if (video.canPlayType('application/vnd.apple.mpegurl')) 
    video.src = 'https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8';
    video.addEventListener('loadedmetadata', function() 
      video.play();
    );
  
</script>

【讨论】:

以上是关于iOS/Safari 上的 Hls 视频流的主要内容,如果未能解决你的问题,请参考以下文章

在 android 上的 hls 流上选择质量视频

带有自定义控件的视频无法在 iOS 上播放(Safari 和 Chrome)

WebRTC 远程视频在 ios Safari 上一直冻结

视频无法在 iOS Safari 上播放 - iphone 6s

HTML5 视频加载数据事件在 IOS Safari 中不起作用

使用 Nginx 或 Node 流式传输保存的 HLS 视频