首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >IOS客户端的视频流问题(在ASP.NET WEB API2上开发的服务器)

IOS客户端的视频流问题(在ASP.NET WEB API2上开发的服务器)
EN

Stack Overflow用户
提问于 2017-11-22 16:44:30
回答 2查看 974关注 0票数 6

我对流媒体视频有点问题。我在ASP.NET Web API2上开发了服务器,并实现了两种方法:

第一种方法:

代码语言:javascript
复制
if (Request.Headers.Range != null)
    {
        try
        {
            var httpResponce = Request.CreateResponse();
            httpResponce.Content =
                new PushStreamContent((Action<Stream, HttpContent, TransportContext>) WriteContentToStream);

            return httpResponce;
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
    }
    else
    {
        return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable);
    }

/*method for streaming*/

private async void WriteContentToStream(Stream outputStream, HttpContent content, TransportContext transportContext)
{
    string relativeFilePath = "~/App_Data/Videos/4.mp4";
    try
    {
        var filePath = System.Web.Hosting.HostingEnvironment.MapPath(relativeFilePath);

        int bufferSize = 1000;
        byte[] buffer = new byte[bufferSize];
        using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            int totalSize = (int)fileStream.Length;
            while (totalSize > 0)
            {
                int count = totalSize > bufferSize ? bufferSize : totalSize;
                int sizeOfReadedBuffer = fileStream.Read(buffer, 0, count);
                await outputStream.WriteAsync(buffer, 0, sizeOfReadedBuffer);
                totalSize -= sizeOfReadedBuffer;
            }
        }
    }
    catch (HttpException ex)
    {
        if (ex.ErrorCode == -2147023667)  
        {
            return;
        }
    }
    finally
    {
        outputStream.Close();
    }
}

2)第二种方法:

代码语言:javascript
复制
public HttpResponseMessage Test()
{
    if (Request.Headers.Range != null)
    {
        try 
        {
            string relativeFilePath = "~/App_Data/Videos/4.mp4";
            var filePath = System.Web.Hosting.HostingEnvironment.MapPath(relativeFilePath);
            HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
            partialResponse.Headers.AcceptRanges.Add("bytes");
            var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            partialResponse.Content = new ByteRangeStreamContent(stream, Request.Headers.Range, new MediaTypeHeaderValue("video/mp4")); 
            return partialResponse;
        }
        catch (Exception)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
    }   
    else
    {
        return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable);    
    }
}

这两种方法在Web客户端和Android客户端都有效,但iOS客户端不显示视频。

我认为,这个问题可能出在视频编解码器(但我使用的是编解码器,建议使用Apple)或http-headers。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-01 03:33:58

我刚刚解决了这个问题,这是因为Content-Length标头( iOS认为是)有一个无效值。

我的解决方案是基于上面的方法#2。以下是我的代码中实际有效的重要部分。

代码语言:javascript
复制
if (!file.Exists) {
    response.StatusCode = HttpStatusCode.NotFound;
    response.ReasonPhrase = "Deleted";
} else {
    var range = Request.Headers.Range?.Ranges?.FirstOrDefault();
    if (range == null) {
        using (var stream = new MemoryStream()) {
            using (var video = file.OpenRead()) await video.CopyToAsync(stream);
            response.Content = new ByteArrayContent(stream.ToArray());
        }
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
        response.Content.Headers.ContentLength = file.Length;
    } else {
        var stream = new MemoryStream();
        using (var video = file.OpenRead()) await video.CopyToAsync(stream);
        response.Content = new ByteRangeStreamContent(
            stream,
            new RangeHeaderValue(range.From, range.To),
            new MediaTypeHeaderValue("video/mp4")
        );
        //  response.Content.Headers.ContentLength = file.Length;
        // this is what makes iOS work
        response.Content.Headers.ContentLength = (range.To.HasValue ? range.To.Value + 1 : file.Length) - (range.From ?? 0);
    }
    response.StatusCode = HttpStatusCode.OK;
}

在处理范围时,我可能应该将HTTP206(部分内容)状态设置为HTTP206(部分内容),但在提出解决方案之前,我已经为此工作了将近两天。

我还没有完全追踪到的唯一问题是,时不时地,Application_EndRequest不会触发其中的一些。我能够记录端点发送的响应,但就像iOS在某个地方断开连接一样,请求会挂起,直到内部超时。

票数 2
EN

Stack Overflow用户

发布于 2017-11-22 18:19:57

检查iOS所需的HLS流。您不能直接播放指向视频文件的视频文件。

https://developer.apple.com/streaming/

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47430205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档