我有一个项目需要将实时视频流发送到网络客户端。我有一个服务器应用程序,实际上使用DirectShow从Direct3D场景中制作实时视频流。我有自己的DirectShow源过滤器,其输出使用WEBM编解码器压缩。将视频流保存到文件时效果很好,以后可以毫无问题地查看。
但下一步是将实时视频流转换为Web客户端。我试图通过TCP将它发送到我的ASP.NET MVC4应用程序。我的页面控制器看起来如下:
public class VideosController : ApiController
{
/// <summary>
/// Web API method to paste into videocontainer in "video" tag on web page
/// </summary>
/// <param name="filename">File name with location path</param>
/// <param name="ext">Videofile extension</param>
/// <returns>Return stream content</returns>
public HttpResponseMessage Get(string filename, string ext)
{
var video = new VideoStream();
var response = Request.CreateResponse();
response.Content = new PushStreamContent(video.WriteToStream, new MediaTypeHeaderValue("video/" + ext));
return response;
}
}
和video.WrtieToStream方法:
public void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[65536];
TcpClient serverSocket;
serverSocket = new TcpClient("localHost", 333);
NetworkStream netStream = serverSocket.GetStream();
StreamReader streamReader = new StreamReader(netStream);
try
{
var bytesRead = 0;
while (true)
{
bytesRead = netStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
}
}
catch (EndOfStreamException)
{
Console.WriteLine("End of file transaction");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
catch (HttpException ex)
{
return;
}
finally
{
outputStream.Close();
}
}
我调试了代码并且它似乎工作正常,即它接收传入的视频流并将其写入输出流,但我总是得到黑屏而不是视频流。
当我改变WriteToStream方法从本地文件(先前从同一场景保存)而不是从网络中读取视频时,视频运行良好。
我做错了什么?或者可能还有其他解决方案可以将视频服务器的实时视频传输到Web客户端?
答案 0 :(得分:0)
可能存在无限循环。我不知道NetStream的细节,但对我来说,大多数流都不能在文件结束时抛出异常。如果我没有遗漏某些东西,可能会发生一种情况,你永远不会到达outputStream.Close();
while (true)
{
bytesRead = netStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
}
我会把它改成
do
{
bytesRead = netStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
}
while (bytesRead > 0)
这可能对你没有帮助,但至少,循环体对我来说似乎更自然。
概念:如果你的应用程序在服务器端有状态,我只会在两边都有一个字节缓冲区,客户端可能有两个缓冲区,一个,他正在播放,另一个,他保存数据以备将来使用播放时,第一个缓冲区最初将被填满并且在播放视频时,他会向服务器请求新数据(这可能是异步发生)并将它们保存到第二个缓冲区,而在服务器上,只有文件的某些部分会在记忆中举行。
答案 1 :(得分:0)
将nginx与rtmp模块一起使用,并通过Ffmpeg将视频数据写入rtmp流,然后使用rtmp player在网页中播放视频