关于<video>标签所⽀持的视频格式和编码:
MP4 = MPEG 4⽂件使⽤ H264 视频编解码器和AAC⾳频编解码器
WebM = WebM ⽂件使⽤ VP8 视频编解码器和 Vorbis ⾳频编解码器
Ogg = Ogg ⽂件使⽤ Theora 视频编解码器和 Vorbis⾳频编解码器

所以在使用<video>前请确保文件格式和编码。

一:现象

在使用<video>播放视频时发现在iOS中无法播放,后台输出二进制流,ContentType = “video/mp4″。

但是直接返回一个.mp4的视频是可以播放的。说明视频格式没问题。

二:查找问题

查看客户端请求发现请求头中:

第一次请求时:Range:bytes=0-1这是范围请求,相当于一个嗅探。要求后台必须有相应格式的返回信息。

Range:分段请求头,bytes=0-1 表示获取0-1的位置的2个字节。
 
这就要求服务器返回:

Accept-Ranges: bytes          接收字节请求
Content-Length: 2                 相应长度
Content-Range: bytes 0-1/18494715    bytes后面的空格不能少,0开始位置,1结束位置。“/”后面的是文件总大小长度

HttpResponse
Status Code: 206 Partial Content      指示请求已成功并且主体包含所请求的数据范围
 
三:决解问题
知道了问题的所在
直接上代码
const bool allowMax = true;
const long maxWriteLength = 3 * 1024 * 1024; //3M
public void ProcessRequest(HttpContext context)
{
    var Request = context.Request;
    var Response = context.Response;
    string sPath = Path.GetDirectoryName(Request.PhysicalPath);

    var reqRange = Request.Headers["Range"];
    long fileLength = 0;

    string[] reqBlockRange = null;
    if (!string.IsNullOrWhiteSpace(reqRange))
    {
        reqBlockRange = reqRange.Replace("bytes=", "").Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
        Response.StatusCode = 206;
    }
    string fileName = "ShowVideo.mp4";
    string filePath = Path.Combine(sPath, fileName);

    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (var reader = new BinaryReader(stream))
        {
            fileLength = stream.Length;

            long startPosition = 0;
            long partialSize = fileLength;
            if (reqBlockRange != null)
            {
                startPosition = Convert.ToInt64(reqBlockRange[0]);
                if (reqBlockRange.Length > 1)
                {
                    long endPosition = fileLength;
                    if (long.TryParse(reqBlockRange[1], out endPosition))
                    {
                        partialSize = endPosition - startPosition + 1;
                    }
                }
                else
                {
                    partialSize = fileLength - startPosition;
                }
            }

            if (allowMax && partialSize > maxWriteLength)
            {
                partialSize = maxWriteLength;
            }
            byte[] buffer = new byte[(int)partialSize];
            reader.BaseStream.Seek(startPosition, SeekOrigin.Begin);
            reader.Read(buffer, 0, (int)partialSize);

            Response.AddHeader("Accept-Ranges", "bytes");
            Response.ContentType = "video/mp4";
            Response.AddHeader("Content-Range", $"bytes {startPosition}-{startPosition + partialSize - 1 }/{fileLength}");
            Response.AddHeader("Content-Length", $"{partialSize}");
            Response.BinaryWrite(buffer);
        }
    }
    Response.End();
}

四:扩展一下前端

使用腾讯的video插件:

<script src="https://web.sdk.qcloud.com/player/tcplayerlite/release/v2.4.1/TcPlayer-2.4.1.js" charset="utf-8"></script>

<div id="id_test_video" style="width:100%; height:320px; ">

</div>

var playUrl = "/ShowVideo.ashx?SNID=" + SNID;
var player = new TcPlayer('id_test_video', {
"m3u8": playUrl,
//"flv": "<%=""%>", //增加了一个 flv 的播放地址,用于PC平台的播放 请替换成实际可用的播放地址
"autoplay": true, //iOS 下 safari 浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
"poster": "../../../Images/Site/play.png",   //封面
//"width" : '320',//视频的显示宽度,请尽量使用视频分辨率宽度
"height" : '320'//视频的显示高度,请尽量使用视频分辨率高度
});

 

 

 

版权声明:本文为统哥原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/tongyi/p/16266035.html