问题在于:
为了实现这项任务,我作为文章的基础:
http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/
有效。独立地并行地为流提供视频文件。
我正在寻找。
接下来有必要解决向多个客户广播的问题(工作中的第3段)。我读了这篇文章: http://gigi.nullneuron.net/gigilabs/streaming-data-with-asp-net-web-api-and-pushcontentstream/
由于我必须在视频字节中提供证据 - 我将StreamWriter类替换为Stream 它适用于第一个客户端之一。
我创建了一个网站Asp.Net WebForms + WebApi + HTML5。
网页 - 运行视频管理器并由用户查看。
WebApi为播放器提供<video>
(HTML5)视频流。
HTML5:
<video>
<source src="http://localhost:8080/SiteVideoStreaming/api/live/?filename=nameFile" />
</video>
WebApi控制器:
//Controllers
public class LiveController : ApiController
{
private static ConcurrentBag<Stream> clients; // List of clients who need to simultaneously deliver video data
static string fileName = "";
static LiveController()
{
clients = new ConcurrentBag<Stream>();
WriteToStream(); // The first call - start to play a video file
}
[HttpGet]
public HttpResponseMessage Subscribe(string filename)
{
fileName = HostingEnvironment.MapPath("~/Videos/") + filename;
var response = Request.CreateResponse();
response.Content = new PushStreamContent((a, b, c) => { OnStreamAvailable(a, b, c); }, "video/mp4");
return response;
}
private void OnStreamAvailable(Stream stream, HttpContent content, TransportContext context)
{
clients.Add(stream); // Add new client
}
//Class record a video file into a streams
public async static void WriteToStream()
{
var buffer = new byte[65536];
using (var video = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var length = (int)video.Length;
var bytesRead = 1;
while (length > 0 && bytesRead > 0)
{
bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length));
foreach (var client in clients)// Each client in turn we return video data
{
try
{
await client.WriteAsync(buffer, 0, bytesRead); // ERROR - here !!! when you connect a second client
await client.FlushAsync();
}
catch (Exception ex)
{
Stream ignore;
clients.TryTake(out ignore);
}
}
length -= bytesRead;
}
}
}
}
如果请求首先来自一个客户端 - 则是视频。工作。 如果来自第二个客户端的请求 - 当你尝试开始给他一个流错误时会发生。 在这个连接drop和第一个客户端。
错误如下:
[System.Web.HttpException] = {“远程主机关闭了连接。 错误代码是0x800704CD。“}
据我所知,在互联网上搜索后:
0x800704CD“在不存在的网络上尝试了一项操作 连接“。
告诉我,我做得不对? 谢谢。
答案 0 :(得分:0)
我这样做了。 我用这个控制器:
public class VideoController : ApiController
{
// GET api/<controller>
public HttpResponseMessage Get(string filename)
{
if (filename == null)
return new HttpResponseMessage(HttpStatusCode.BadRequest);
string filePath = HostingEnvironment.MapPath("~/Videos/") + filename;
if (Request.Headers.Range != null)
{
//Range Specifc request: Stream video on wanted range.
try
{
//NOTE: ETag calculation only with file name is one approach (Not the best one though - GUIDs or DateTime is may required in live applications.).
Encoder stringEncoder = Encoding.UTF8.GetEncoder();
byte[] stringBytes = new byte[stringEncoder.GetByteCount(filePath.ToCharArray(), 0, filePath.Length, true)];
stringEncoder.GetBytes(filePath.ToCharArray(), 0, filePath.Length, stringBytes, 0, true);
MD5CryptoServiceProvider MD5Enc = new MD5CryptoServiceProvider();
string hash = BitConverter.ToString(MD5Enc.ComputeHash(stringBytes)).Replace("-", string.Empty);
HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
partialResponse.Headers.AcceptRanges.Add("bytes");
partialResponse.Headers.ETag = new EntityTagHeaderValue("\"" + hash + "\"");
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 ex)
{
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
else
{
return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable);
}
}
}
在客户端 - 我通过SignalR技术运行<video>
视频播放器。