【问题标题】:video streaming to smart tv (dlna/upnp)视频流式传输到智能电视 (dlna/upnp)
【发布时间】:2016-02-18 23:18:41
【问题描述】:

我正在尝试通过 HTTP 将来自 ffmpeg 的视频流传输到智能电视。它工作大约 5-10 分钟,然后电视结束播放。我调查了wireshark的问题,发现电视在停止播放时会发送一个零窗口数据包。我怀疑 tv 达到了其 I/O 或 CPU 过载的程度。 我附上了wireshark 捕获FILE(修剪下来)和屏幕截图。
192.168.0.103 => 电视(三星 UE42F5500)
192.168.0.101 => PC(电视和电脑都使用电缆连接到路由器,没有 wifi)
流是通过使用 HTTPListener 的 C# 应用程序完成的。我已经尝试了很多天和夜,但是更改编解码器、比特率、容器和各种 ffmpeg 选项以进行错误校正对播放时间没有影响。最近,我尝试在将流发送到电视时添加一个小睡眠,效果很好,在这台电视现在在大约 2-4 分钟内停止之前,现在有 20 毫秒的睡眠,它在大约 30 分钟内停止。所以这让我认为 PC 发送的速度比电视可以处理的快。如果我增加睡眠,如果我减少它,播放会变得生涩和失真,电视会更快停止。这是我达到的一点,我对尝试什么没有任何想法,任何提示或想法将不胜感激,谢谢。

下面是向电视发送数据的 sn-p。

  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 Stream -> Decoded&Encoded with ffmpeg (以避免任何错误形式sopcast) -> 我的c#代码(使stream upnp兼容) -> TV

【问题讨论】:

    标签: c# tcp network-programming streaming samsung-smart-tv


    【解决方案1】:

    我知道这已经晚了 5 年,但也许有人会发现这个答案很有用。所有这些电视设备都具有有限的内存,它们可以在其中解码帧。您可能将 DPB(解码图片缓冲区)设置得太高。如果您将参考帧的数量设置得很大,这个缓冲区会很大。

    例如,如果您使用 -refs 16,这意味着对于使用 16 个周围帧压缩的帧,电视需要解码所有这 16 个帧才能完全显示该帧。如果您的电视无法将所有这些帧都放入内存中,那么您就有问题了。

    测试是否是这种情况的最佳方法是仅使用 I 帧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多