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

折腾中成长

一:源起:
某天,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越来越近了,对于平常的视频加载来说,存在的分割范围就是实际上请求的文件大小时,这种机制存在的意义可能更多是功能性,而非传输瓶颈
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容