我需要在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字节的标头,然后是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字节头或每个MPEGTS 188字节包?
答案 0 :(得分:3)
我终于让视频正常工作了!
以下是我提取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给了我很多帮助。