iOS/Safari 上的 HLS 视频流

Hls video streaming on iOS/Safari

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

关于 github 上可用的问题的一些讨论:

针对您的问题:

Is it some kind of a wishful thinking getting HLS & WebGL to play on iOS?

是的,一厢情愿 :-) problem/issue/bug 属于 Apple,而不是任何图书馆。无论是什么 JS 库,A-FrameThree 等,这在 iOS 中的任何浏览器上始终是一个问题(iOS 中的所有浏览器基本上都是 Safari 的包装器),以及 OSX Safari。

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

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

可能的解决方法:

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

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

这是另一个详细的线程:link

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

Please note: iOS Safari "Mobile" does not support the MediaSource API. Safari browsers have however built-in HLS support through the plain video "tag" source URL. See the example above (Getting Started) to run appropriate feature detection and choose between using Hls.js or natively built-in HLS support.

When a platform has neither MediaSource nor native HLS support, you will not be able to play 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>