使用 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 所遵循的步骤:
MseSourceBuffer 需要处于 "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对我帮助很大。
我需要在 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 所遵循的步骤:
MseSourceBuffer 需要处于 "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对我帮助很大。