使用 MseStreamSource 播放 MPEG-2 TS

Play MPEG-2 TS using MseStreamSource

我需要在 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 显示消息 "video not supported or incorrect file name"。 (不确定消息,我的 Windows 是法语)。

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

我终于可以播放视频了!

以下是我提取 MPEG-TS 数据包并将其正确发送到 MseStreamSource 所遵循的步骤:

Ms​​eSourceBuffer 需要处于 "Sequence" 模式:

_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对我帮助很大。