美文网首页
Iphone-H5-Video标签播放视频流笔记

Iphone-H5-Video标签播放视频流笔记

作者: 潇潇剑_易水阁 | 来源:发表于2020-11-17 16:11 被阅读0次

    折腾中成长

    一:源起:
    某天,A君话ios视频播放不了,但是Android和Web是可以播放的,一如当年听到 IE XXX 不行那样,可手头上并没iphone,一直用android机开发和调试,于是一头雾水的我,搜索到可能视频格式问题,结果什么格式都试过了,始终无果,直到搜索的关键词到一些帖子看到可能和请求头Range有关,但是解决过程还是跌跌撞撞,毕竟很多并没提到如何解决,当前的语言解决方案,当然解决后的自己在回看这些帖子时,才会觉得,实在也就这些,只不过当时雾中的自己看不清而已,最后,设备才是关键,一直没iphone,靠猜真是浪费青春。。。

    一:问题起因排查:

    1. 视频格式问题,其实验证这个,只需要将视频地址改为本地存在视频的地址即可,不能单看后缀名,这也是为何要验证这个的原因,需要排查,但是造成的可能性不大
    2. 排查接口是否为本地资源还是视频流,若是本地资源,这个就好办了,检查路径是否正确以及是否存在该文件,若不是,才考虑后台流传输逻辑(比如下文所提到的解决方法)
    3. 检查请求头,这也是我一开始忽略导致方向迷失的原因,网络传输,这些很重要,需要分析出现的非常规的参数,或者说,自己应该清楚这些参数代表的意义
    4. 检查页面是否存在报错导致,检查video标签是否正确,其实这个正确在第一点也能一并验证出了
    5. 平台差异的确存在,Windos和Android的浏览器大部分(其实还没看见,稳妥点)对video标签是采取常规加载,而Safari则是采取分段加载,当然要不要分段这个选择权要不要该交给服务端,还是终端去确定这个又是另一个话题了

    二:Iphone-H5-视频流播放:

    1. 第一次请求头,必包含 Range:bytes=0-1 (其实重点仅为Range这个key)
    2. 响应头必需要包含:
    // 视频流格式,iphone支持mp4,但是注意码率这些,第一次必须返回此参数,后续的分段可不返回,省事的就所有都默认发送
    Content-Type: video/mp4
    // 该参数必须且不能错误,极其重要的参数
    Content-Range: bytes 0-1/25536
    // 该参数必须且不能错误,极其重要的参数
    ContentLength: 1
    
    1. .NET 4.0 WebApi后台视频流分段传输参考源码(适用支持http协议且该协议带有Range规范的软件,也适合断点下载的场景,对于资源来说,不分是不是video还是文本,当然按上面的提到的点或者看http关于Range的规范也是不分语言或者该语言的哪种版本,此处仅仅为当时项目用到4.0而已):
    public HttpResponseMessage ResourceSegmentLoad()
            {
                // 每次请求响应状态码均为 206,无须判断最后一次分段时返回200,省事
                var response = new HttpResponseMessage(HttpStatusCode.PartialContent);
                // 获取range,若是无返回的对象为null
                var range = Request.Headers.Range?.Ranges.FirstOrDefault();
                // 分段的起始位置,若为null,默认0
                long? from = range == null ? 0 : range.From;
                // 分段的结束位置,若为null,默认1
                long? to = range == null ? 1 : range.To;
                byte[] bytes = null;
                // 具体如何获取,自行解决
                string path = "你的资源文件地址";
                // 具体如何获取,自行解决
                string mediaType = "资源的文件类型";
                long fileLength = 0;
                var file = new FileInfo(path);
                if (file.Exists)
                {
                    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        fileLength = fileStream.Length;
                        // 对应的文件流跳转到指定的分段起始位置开始读操作,Begin为从资源流0开始位置计算
                        fileStream.Seek(from.Value, SeekOrigin.Begin);
                        using (BinaryReader binaryReader = new BinaryReader(fileStream))
                        {
                            to = to == null ? fileLength - 1 : to.Value;
                            // 分段大小
                            int length = Convert.ToInt32(to - from) + 1;
                            // 仅仅加载分段指定范围的数据
                            bytes = binaryReader.ReadBytes(length);
                        }
                    }
                }
                // 切勿使用StreamContent
                response.Content = new ByteArrayContent(bytes);
                // 该类型谨谨遵循 http 规范
                response.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType);
                // 对应生成的header参数为 $"Content-Range: bytes {from}-{to}/{fileLength}"
                response.Content.Headers.ContentRange = new ContentRangeHeaderValue(from.Value, to.Value, fileLength);
                // 此处很容易误填fileLength,实际上是你放进Content 的bytes的大小
                response.Content.Headers.ContentLength = bytes?.Length ?? 0;
    
                return response;
            }
    

    三:幕:

    折腾之后,总想着为啥要这么折腾,故总结如下:
    1.使用分段加载资源的好处:
    1.0 提高大文件的响应速度(不用加载完就返回,单次来看好似是这么回事 <-< )
    1.1 减少io的占用(还是单次来看 <-< )
    1.2 减少用户等待时间(单次来看,总体断断续续的,用户会疯,毕竟用户不在意这些)
    1.3 对分片控制强烈的如植入广告或者其他之类的收费分段的有利
    1.4 容易多路不同资源的异步加载,同资源不同等级性质加载等等
    1.5 减少掉包率这些导致的重传占用时间
    1.6 对于单次需要缓冲到的数据才能快进,分段能更好跳跃到指定点加载,优化用户体验节省时间
    2.使用分段加载资源的坏处:
    2.0 增加传输的次数,毕竟原理仅仅为单次发送改为多次发送(合理的分割除外)
    2.1 在大传输速率下,若客户端没有适应性的策略,依然固定分段范围和大小的,则会导致没必要的传输次数
    2.2 多次的加载虽然缩短响应时间,但是http协议之间处理的时间加在一起,无疑会浪费,或许将来的合并犹如io复用那样,达到最佳的分割范围与请求次数
    最后,我已悄悄把之前的全加载统一改为分段加载,不管是哪种pc又或者哪种phone访问,都执行此策略,这次解决的不仅仅是iphone播放不了的问题,而是实际上目前采取的方案,虽然5G越来越近了,对于平常的视频加载来说,存在的分割范围就是实际上请求的文件大小时,这种机制存在的意义可能更多是功能性,而非传输瓶颈

    相关文章

      网友评论

          本文标题:Iphone-H5-Video标签播放视频流笔记

          本文链接:https://www.haomeiwen.com/subject/xlatiktx.html