使用MseStreamSource播放MPEG-2 TS

Nic*_*eno 6 c# video ffmpeg mpeg2-ts uwp

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

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

ffplay -fflags nobuffer -f:v mpegts udp://:8554
Run Code Online (Sandbox Code Playgroud)

我想在不使用第三方库的情况下使用MediaPlayerElement.

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

我收到了带有UdpClient的MPEG-2 TS流.它运作良好.我在每个UdpReceiveResult中收到一个12字节的标头,然后是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);
Run Code Online (Sandbox Code Playgroud)

这是我将消息发送到MseStreamSource的方式:

    UdpReceiveResult receiveResult = await _udpClient.ReceiveAsync();
    byte[] bytes = receiveResult.Buffer;
    mseSourceBuffer.AppendBuffer(bytes.AsBuffer());
Run Code Online (Sandbox Code Playgroud)

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

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

Nic*_*eno 3

我终于让视频工作了!

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

MseSourceBuffer 需要处于“Sequence”模式:

_mseSourceBuffer.Mode = MseAppendMode.Sequence;
Run Code Online (Sandbox Code Playgroud)

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

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

我将数据包从队列中出列,并将它们分组发送到 MseSourceBuffer。我为每个 PAT 数据包创建一个新组 (pid = 0):

byte[] bytes;
// [...] combine the packets of the group
mseSourceBuffer.AppendBuffer(bytes.AsBuffer());
Run Code Online (Sandbox Code Playgroud)

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

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

希望它可以帮助别人。

这个维基百科 MPEG-TS 页面对我帮助很大。