我需要在UWP应用程序中显示实时视频流。

视频流来自GoPro。它通过UDP消息进行传输。它是MPEG-2 TS流。我可以使用FFPlay通过以下命令行成功播放它:

ffplay -fflags nobuffer -f:v mpegts udp://:8554

我想在不使用第三方库的情况下使用MediaPlayerElement进行播放。

根据下一页:
https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/supported-codecs
UWP应该可以播放它。 (我在Windows应用商店中安装了“Microsoft DVD”应用程序)。

我通过UdpClient收到MPEG-2 TS流。它运作良好。
我在每个UdpReceiveResult中接收一个12字节的 header ,后跟4、5、6或7个MPEGTS数据包(每个数据包为188字节,以0x47开头)。

我创建了一个MseStreamSource:
_mseStreamSource = new MseStreamSource();
_mseStreamSource.Opened += (_, __) =>
{
    _mseSourceBuffer = _mseStreamSource.AddSourceBuffer("video/mp2t");
    _mseSourceBuffer.Mode = MseAppendMode.Sequence;
};
_mediaPlayerElement.MediaSource = MediaSource.CreateFromMseStreamSource(_mseStreamSource);

这就是我将消息发送到MseStreamSource的方式:
    UdpReceiveResult receiveResult = await _udpClient.ReceiveAsync();
    byte[] bytes = receiveResult.Buffer;
    mseSourceBuffer.AppendBuffer(bytes.AsBuffer());

MediaPlayerElement显示消息“不支持视频或文件名不正确”。 (不确定消息,我的Windows是法语)。

使用MseAppendMode.Sequence模式是一个好主意吗?
我应该传递给AppendBuffer方法什么?原始udp消息包括12个字节的 header 或每个MPEGTS 188字节的数据包?

最佳答案

我终于可以播放视频了!

这是我提取MPEG-TS数据包并将其正确发送到MseStreamSource的步骤:

MseSourceBuffer必须处于“序列”模式:

_mseSourceBuffer.Mode = MseAppendMode.Sequence;

对于每个收到的UDP数据报,我提取MPEG-TS数据包。为此,我忽略了UDP数据报的前12个字节。然后,我将每个188字节的数据包提取到一个单独的数组中(每个数据包均以0x47开头)。

我将每个数据包发送到同步队列。

我从队列中取出数据包,并将它们分组发送到MseSourceBuffer。我为每个PAT数据包(pid = 0)创建一个新组:
byte[] bytes;
// [...] combine the packets of the group
mseSourceBuffer.AppendBuffer(bytes.AsBuffer());

我试图使用MemoryStream并调用AppendStream()方法,但没有成功。

还应注意线程同步:数据包顺序不应丢失。这就是同步队列的原因。

希望它可以帮助别人。

这个wikipedia MPEG-TS page帮助了我很多。

关于c# - 使用MseStreamSource播放MPEG-2 TS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49878796/

10-12 04:00
查看更多