gpt4 book ai didi

c# - IOS 客户端的流视频问题(在 ASP.NET WEB API 2 上开发的服务器)

转载 作者:可可西里 更新时间:2023-11-01 04:55:19 25 4
gpt4 key购买 nike

我对流式视频有疑问。我在 ASP.NET Web API 2 上开发了服务器并实现了 2 种方法:

第一种方法:

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)第二种方法:

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。

最佳答案

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

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

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;
}

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

我尚未完全查明的唯一问题是,Application_EndRequest 有时不会为其中的某些请求触发。我能够记录端点发送的响应,但它就像 iOS 在某处断开连接并且请求挂起,直到它在内部超时。

关于c# - IOS 客户端的流视频问题(在 ASP.NET WEB API 2 上开发的服务器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47430205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com