解决IOS通过HTML5播放Video或者Audio直接输出数据的问题_video标签怎么读取ios本地文件-程序员宅基地

技术标签: C#  数据  html5  视频  audio  ios  

大家都知道HTML5通过Video或者Audio标签的src属性可以直接播放网络路径的视频或者音频,IOS对于直接读取文件是没问题的,但是如果需要输出数据的方式读取就有问题,是打不开文件的,为了完美支持html5的视频播放,必须支持byte-range请求。因为html5播放视频之前会发送一个只需文件少数字节的请求,确认服务端是否支持byte-range请求,支持才会继续发送请求剩余的文件数据。

下载代码:

private void RangeDownload(string fullpath, HttpContext context)
    {
        long size, start, end, length, fp = 0;
        using (StreamReader reader = new StreamReader(fullpath))
        {
            size = reader.BaseStream.Length;
            start = 0;
            end = size - 1;
            length = size;
            context.Response.AddHeader("Accept-Ranges", "0-" + size);

            if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
            {
                long anotherStart = start;
                long anotherEnd = end;
                string[] arr_split = context.Request.ServerVariables["HTTP_RANGE"].Split(new char[] { Convert.ToChar("=") });
                string range = arr_split[1];

                // Make sure the client hasn't sent us a multibyte range
                if (range.IndexOf(",") > -1)
                {
                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");
                }
                
                if (range.StartsWith("-"))
                {
                    // The n-number of the last bytes is requested
                    anotherStart = size - Convert.ToInt64(range.Substring(1));
                }
                else
                {
                    arr_split = range.Split(new char[] { Convert.ToChar("-") });
                    anotherStart = Convert.ToInt64(arr_split[0]);
                    long temp = 0;
                    anotherEnd = (arr_split.Length > 1 && Int64.TryParse(arr_split[1].ToString(), out temp)) ? Convert.ToInt64(arr_split[1]) : size;
                }

                anotherEnd = (anotherEnd > end) ? end : anotherEnd;

                if (anotherStart > anotherEnd || anotherStart > size - 1 || anotherEnd >= size)
                {
                    context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
                    throw new HttpException(416, "Requested Range Not Satisfiable");
                }
                start = anotherStart;
                end = anotherEnd;

                length = end - start + 1; // Calculate new content length
                fp = reader.BaseStream.Seek(start, SeekOrigin.Begin);
                context.Response.StatusCode = 206;
            }
        }
        // Notify the client the byte range we'll be outputting
        context.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + size);
        context.Response.AddHeader("Content-Length", length.ToString());
        // Start buffered download
        context.Response.WriteFile(fullpath, fp, length);
        //context.Response.End();
    }


调用:

if (System.IO.File.Exists(fullPath))
            {
                HttpContext context = System.Web.HttpContext.Current;
                
                string mimetype = GetContentType(path);
                if (System.IO.File.Exists(fullPath))
                {
                    context.Response.ContentType = mimetype;
                    if (!String.IsNullOrEmpty(context.Request.ServerVariables["HTTP_RANGE"]))
                    {
                        //request for chunk
                        RangeDownload(fullPath, context);
                    }
                    else
                    {
                        //ask for all 
                        long fileLength = File.OpenRead(fullPath).Length;
                        context.Response.AddHeader("Content-Length", fileLength.ToString());
                        context.Response.WriteFile(fullPath);
                    }
                }
                else
                {
                    throw new HttpException(404, "Video Not Found Path:" + fullPath);
                }
            }



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mojocube/article/details/71170421

智能推荐

40W+年薪算法岗,面试官都在问些什么?_算法岗年薪40-程序员宅基地

文章浏览阅读2.2k次。2015年自从我担任当时算法组的小组leader,我作为面试官面试了不少同学。前前后后面试了超过200名同学,其中有不少入职的同学后来发展都不错,也坚定了自己对于选人的标准的自信心。今年2020年找工作尤其艰难,我把这些年作为面试官一些重要的面试题整理出来,一共80道,希望能够帮助到大家,为了方便大家,我做了一个归类,一共分成了6大类,分别是:机器学习,特征工程,深度学习,NLP,CV,推荐系统。这些知识既是面试中的常见问题,也可以作为大家整理自己思路的参考资料。机器学习理论类:1. ._算法岗年薪40

STM32串行通信理解_stm32最大支持的串行通信个数-程序员宅基地

文章浏览阅读492次。文章目录一、通信接口的背景知识1.处理器与外部设备通信的两种方式2.串行通信按照数据传送方向分为:3.串行通信的通信方式:二、STM32串口通信基础1.STM32的串口通信接口2.UART异步通信方式引脚连接方法:3.UART异步通信方式特点:4.STM32串口通信过程:5.STM32异步通信要定义哪些参数:6.串口通信框图7.串口设置的一般步骤可以总结为如下几个步骤:一、通信接口的背景知识1.处理器与外部设备通信的两种方式(1)并行通信 -传输原理:数据各个位同时传输-优点:速度快-缺点:_stm32最大支持的串行通信个数

php简洁版JWT加密解密适用Laravel/ThinkPHP/Yii_laravel 解密 jwt-程序员宅基地

文章浏览阅读1.9k次。composer require firebase/php-jwtgit地址:https://github.com/firebase/php-jwt栗子:<?phpuse \Firebase\JWT\JWT;$key = "example_key";$token = array( "iss" => "http://example.org", "aud"..._laravel 解密 jwt

RAID知识以及利用率-程序员宅基地

文章浏览阅读338次,点赞2次,收藏3次。作者:知乎用户链接:https://www.zhihu.com/question/20131784/answer/28026813来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。一共有0~6一共7种,这其中RAID 0、RAID1、RAID 5和RAID6比较常用。RAID 0:如果你有n块磁盘,原来只能同时写一块磁盘,写满了再下一块,做了RAID 0之..._raid4 得盘率

SQL Server如何启动_sqlserver启动程序在哪-程序员宅基地

文章浏览阅读1.2w次,点赞10次,收藏34次。1.单击开始程序,找到Microsoft SQL Server 2012,点击SQL Server配置管理器2.在弹出的窗口中点击sqlserver网络配置,点击协议在右侧点击tcp/ip,如果状态为禁用的话 先启用3.启用后右键点击tcp/ip协议,选择属性4.4.在弹出的窗口中,切换到ip地址窗口找到127.0.0.1本地IP地址,修改启用状态为是,然后点击确定5.然后返回到sqlserver服务,选择实例服务右键进行重新启动6.再次点击开始菜单,找到sql server mana_sqlserver启动程序在哪

Parsing ranges item in pcie-designware.c-程序员宅基地

文章浏览阅读1.3k次。parsing ranges item in pcie-designware.c

随便推点

Task :app:transformClassesAndResourcesWithR8ForRelease FAILED-程序员宅基地

文章浏览阅读5.5k次。这个是针对tinker报错问题,在运行gradlew assemblerelease的时候报一下错误:> Task :app:transformClassesAndResourcesWithR8ForRelease FAILEDR8 is the new Android code shrinker. If you experience any issues, ple..._transformclassesandresourceswithr8forrelease

Linux Install——SSH server_sudo apt install openssh-server-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏5次。一、确认服务端是否安装ssh的服务器端ssh -V #这一步不准确netstat -tlp #用这个直接看有没有这样的进程[::]:ssh 如果安装可以看到下图所示:二、安装ssh服务端#执行如下命令sudo apt install openssh-server三、启动ssh-server#执行如下命令:/etc/init.d/ssh restart四、确认ssh-server已经正常工作#执行如下命令netstat -tlp如果正常工作会看到如下图所示的信息:看_sudo apt install openssh-server

greenplum麒麟安装笔记_麒麟系统编译greenplum-程序员宅基地

文章浏览阅读2.2k次。本周尝试在中标麒麟操作系统下安装greenplum。中标麒麟操作系统采用强化的Linux内核,我们首先准备好三台已安装中标麒麟服务版系统的虚拟机。规划他们的IP地址分别为:Master:10.81.2.20Segment1:10.81.2.21Segment2:10.81.2.22通过查找greenplum的官方网站可知,greenplum支持的操作系统如下:Red Hat Enterprise Linux 64-bit 7.x (See the following Note.)Re_麒麟系统编译greenplum

【Python】Web自动化,Xpath快速定位元素_python webfriver xpath-程序员宅基地

文章浏览阅读329次。例:百度一下:输入百度,点击搜索,这个过程的自动化1.点击元素 右键检查/打开开发者工具;2.选择那行代码右键选择copy,选择copy Xpath;3.粘贴到自己所写的代码里;4.搜索按钮定位使用同样方法;5.结果如下;参考:https://blog.csdn.net/Hu_wen/article/details/94738559..._python webfriver xpath

VMware Workstation 15 与 Device/Credential Guard_vmware与device/credential分别采用什么虚拟化架构-程序员宅基地

文章浏览阅读133次。VMware Workstation 15 与 Device/Credential Guard不兼容解决办法参考1参考2参考3看完 参考1 能解决问题的不用看 往后看了 因为 我是两者结合起来弄得 也就是关了hv,设置了hv服务禁用,并且关闭了内核保护1. 打开本电脑-》管理-》服务和应用程序-》服务下找到如下图的HV 主机服务,双击选择禁用。2. 打开Windows Po..._vmware与device/credential分别采用什么虚拟化架构

快速Android开发系列网络篇之Android-Async-Http-程序员宅基地

文章浏览阅读280次。先来看一下最基本的用法AsyncHttpClient client = new AsyncHttpClient();client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onSuccess(String response) {..._d:\desk\android\meowsic-master\meowsic-master\app\libs\android-async-http-1.

推荐文章

热门文章

相关标签