EDGE 浏览器视频标签在 IOS(Vue.js 和 ASP.NET)上不起作用

分享于2022年07月17日 browser ios javascript video vue.js 问答
【问题标题】:EDGE 浏览器视频标签在 IOS(Vue.js 和 ASP.NET)上不起作用(EDGE browser's video tag not working on IOS (Vue.js & ASP.NET))
【发布时间】:2022-06-10 21:27:35
【问题描述】:

上下文

我正在尝试在边缘浏览器中播放视频。 项目框架是
.NET 6 MVC VUE 用于客户端
.NET 6 WebApi 用于api服务器
客户端的 Vue 组件将发送带有范围标头 (1MB) 的请求以请求分段 MP4,并使用媒体源将 arrayBuffer 附加到指向 video.src 的 blobUrl。
这在窗口的 EDGE 中工作正常, 在手机上不起作用(由 Iphone SE 测试)
视频标签不起作用 => 喜欢这张图片(EDGE 版本 100.0.1185.50 ) EDGE browser's video tag not working on IOS (Vue.js & ASP.NET)

在窗口的 EDGE 版本 100.0.1185.50 上工作正常 => 图像 EDGE browser's video tag not working on IOS (Vue.js & ASP.NET)

尝试过的解决方案

我曾尝试将 playinline 属性添加到视频标签,如 HTML5 Video tag not working in Safari , iPhone and iPad ,但仍然无法正常工作

代码片段

Vue 组件的方法如下:

    /*
         * check the videoId is equal to course or not.
         * if not, fetch new video stream, and create blob url to this.videoUrl
         */
        async displayVideo() {
          if (this.videoId != this.course) {
            //common.loader.show("#255AC4", 1.5, "Loading...");
            this.videoId = this.course;
    
            let video = document.querySelector("video");
            let assetURL = FrontEndUrl + `/Stream/${this.videoId}`;
            let mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
            let sourceBuffer;
            let chunkSize;
            let contentRange;
            let loop;
            let index;
    
            const token = common.cookieManager.getCookieValue(`signin`);
    
            if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
              let mediaSource = new MediaSource;
              mediaSource.addEventListener('sourceopen', sourceOpen);
              video.src = URL.createObjectURL(mediaSource);
            } else {
              console.error('Unsupported MIME type or codec: ', mimeCodec);
            }
    
            function sourceOpen() {
              // chunkSize set to 1MB
              chunkSize = 1024 * 1024 * 1;
    
              // index set to 1 because the fetchNextSegment start from second fragment
              index = 1;
    
              // 取出 mediaSource 並且把sourceBuffer加上 updateend event
              let mediaSoruce = this;
              sourceBuffer = mediaSoruce.addSourceBuffer(mimeCodec);
              sourceBuffer.addEventListener("updateend", fetchNextSegment);
    
              fetchArrayBuffer(assetURL, chunkSize * 0, appendBuffer);
    
              // ???? 這裡會報一個 DOM interact 的 錯誤
              //video.play();
            }
    
            function fetchNextSegment() {
              if (index > loop) {
                sourceBuffer.removeEventListener("updateend", fetchNextSegment);
                return;
              }
    
              fetchArrayBuffer(assetURL, chunkSize * index, appendBuffer);
    
              index++;
            }
    
            function fetchArrayBuffer(url, range, appendBuffer) {
              fetch(url, {
                headers: {
                  "Range": `bytes=${range}-`,
                  "Authorization": `Bearer ${token}`,
                }
              })
                .then(response => {
                  if (!loop) {
                    contentRange = response.headers.get("x-content-range-total");
                    loop = Math.floor(contentRange / chunkSize);
                  }
    
                  return response.arrayBuffer();
                })
                .then(data => { appendBuffer(data) });
            }
    
            function appendBuffer(videoChunk) {
              if (videoChunk) {
                sourceBuffer.appendBuffer(videoChunk);
              }
            }
    
            // ???? 這是原本舊的方式,此方式無法附上 JWT token
            // this.videoUrl = await this.fetchVideoStream(this.videoId); //FrontEndUrl + `/Stream/${this.videoId}`;
    
            //common.loader.close();
          }
        },

还有我的 Vue 的模板

    
              
              
              
              
              
              

我的机器上也有日志,但我看到日志是正常的。

有人知道为什么它可以在 IOS 的 EDGE 上运行吗?谢谢


【解决方案1】:

原因是iPhone的IOS不支持MSE(Media Source Extension)。 所以 MSE 没有工作。

iPhone 的 IOS 原本支持 HLS。 所以需要将MP4转换成HLS格式。(可以使用 bento4 HLS )然后让HLS资源的URL指向video标签的src属性。 喜欢这个示例代码


也可以使用videoJS库,srcObject的类型是“application/x-mpegURL”

var player = videojs("videoId");
player.src({ src:"https://XXX/master.m3u8", type: "application/x-mpegURL" })