我正在尝试通过HTTP将来自ffmpeg的视频流传输到智能电视。它工作大约5-10分钟,然后电视结束播放。我调查了wireshark的问题,发现电视在停止播放时会发送Zero Window数据包。我怀疑电视已经到了I/O或CPU过载的地步。我已经附上了wireshark捕获FILE(修剪下来)和一个截图。
192.168.0.103三星电视( => UE42F5500)
192.168.0.101 => PC (电视和pc都使用不带wifi的电缆连接到路由器)

流式传输是通过使用HTTPListener的C#应用程序完成的。我已经尝试了很多东西很多日夜,但改变编解码器,比特率,容器和各种错误校正的ffmpeg选项对播放时间没有影响。最近,我尝试在将流发送到电视时添加一个小睡眠,效果很好,在这个电视在~2-4分钟内停止之前,20ms的睡眠在~30分钟内停止。因此,这让我认为PC发送的速度比电视所能处理的速度还要快。如果我增加睡眠时间,如果我减少睡眠时间,播放就会变得抖动和失真。这就是我没有任何想法去尝试的地方,任何提示或想法都会非常感谢,谢谢。
下面是向电视发送数据的代码片段。
void AcceptRequest(IAsyncResult result)
{
HttpListenerContext ctx = null;
try
{
HttpListener listener = (HttpListener)result.AsyncState;
ctx = listener.EndGetContext(result);
listener.BeginGetContext(new AsyncCallback(AcceptRequest), listener);
ctx.Response.StatusCode = 200;
ctx.Response.Headers.Clear();
ctx.Response.AddHeader("Content-Type", "video/x-ms-asf");
ctx.Response.AddHeader("transferMode.dlna.org", "Streaming");
// tv first sends a HEAD to get the headers then a GET to get the actual content then it plays
if (ctx.Request.HttpMethod != "HEAD")
{
using (Stream outputStream = ctx.Response.OutputStream)
{
try
{
//input stream comes from ffmpeg, i get it making a TcpClient connection in this method
using (Stream inputStream = GetVideoStream())
{
int bytesRead = 1;
while (bytesRead != 0)
{
//buffer size is 4096
byte[] buff = new byte[TransmitBufferSize + 1];
bytesRead = inputStream.Read(buff, 0, TransmitBufferSize);
outputStream.Write(buff, 0, bytesRead);
outputStream.Flush();
//this is the silly workaround that "slows" down the stream and allows the tv to play longer
Thread.Sleep(20);
}
}
}
catch (HttpListenerException ex)
{
if (ex.ErrorCode != 62)//The specified network name is no longer available
Globals.Log("Error on VideoServer Buffer copy loop exception={0} callerInfo={1} ", ex.ToString(), PrintDebugCallerInfo(ctx));
}
catch (Exception ex2)
{
Globals.Log("Error on VideoServer Buffer copy loop exception={0} callerInfo={1} ", ex2.ToString(), PrintDebugCallerInfo(ctx));
}
}
}
}
catch (Exception ex)
{
Globals.Log("Error on Accept request, callerInfo={0} exception={1}",PrintDebugCallerInfo(ctx), ex.ToString());
}
finally
{
try
{
ctx.Response.Close();
}
catch (HttpListenerException ex)
{
if (ex.ErrorCode != 1229)//connection invalid, normal it can occur
Globals.Log("Error closing response, error code:{0} ex:{1}",ex.ErrorCode, ex.ToString());
}
catch(Exception ex2)
{
Globals.Log("Error closing response, error ex:{0}",ex2.ToString());
}
}
}数据流是: Sopcast流->解码和编码与ffmpeg (以避免任何错误从sopcast) ->我的c#代码(使流->兼容)->电视
发布于 2021-03-05 21:46:27
我知道这已经晚了5年,但也许有人会发现这个答案很有用。所有这些电视设备都有有限的内存,它们可以在其中解码帧。可能是您将DPB (解码图片缓冲区)设置得太高。如果将参考帧的数量设置为较大,则此缓冲区将较大。
例如,如果您使用-refs 16,这意味着对于使用16个周围帧压缩的帧,TV需要解码所有这16个帧才能完全显示该帧。如果你的电视不能把所有这些帧都存入内存,那你就有问题了。
例如,测试这种情况的最好方法是仅使用I帧。
https://stackoverflow.com/questions/33759434
复制相似问题