使用 gstreamer 将 PCM 数据发送到 VLC 播放器

Posted

技术标签:

【中文标题】使用 gstreamer 将 PCM 数据发送到 VLC 播放器【英文标题】:Send PCM data to VLC player using gstreamer 【发布时间】:2015-12-10 05:32:39 【问题描述】:

我想将原始音频数据 (PCM) 发送到 RTP 上的 VLC 播放器,以便使用 gstreamer 播放 PCM。

这是发送 PCM 的命令

gst-launch-1.0 -v filesrc location=/home/webos/pcm_data_dump !音频/x-raw,速率=44100,通道=2,字节序=1234,格式=S16LE,布局=交错,时钟速率=44100!音频转换!音频重采样!音频/x-raw,速率=44100,通道=2,格式=S32LE,布局=交错!音频转换! rtpL16pay pt=10 !应用程序/x-rtp,pt=10,编码名称=L16,有效负载=10,时钟速率=44100,通道=2! udpsink 主机=192.168.0.2 端口=5555

这是接收 PCM 的 VLC 选项

rtp://192.168.0.2:5555

VLC 播放器可以从 gstreamer 获取 PCM,但无法播放。 VLC 显示如下调试消息。 最后,“core debug: Buffering 0%”消息在 VLC 调试消息中反复显示。

core debug: output 'f32l' 44100 Hz Stereo frame=1 samples/8 bytes 
core debug: looking for audio volume module matching "any": 2 candidates
core debug: using audio volume module "float_mixer"
core debug: input 's16l' 44100 Hz Stereo frame=1 samples/4 bytes
core debug: looking for audio filter module matching "scaletempo": 14         candidates
scaletempo debug: format: 44100 rate, 2 nch, 4 bps, fl32
scaletempo debug: params: 30 stride, 0.200 overlap, 14 search
scaletempo debug: 1.000 scale, 1323.000 stride_in, 1323 stride_out, 1059 
standing, 264 overlap, 617 search, 2204 queue, fl32 mode
core debug: using audio filter module "scaletempo"
core debug: conversion: 's16l'->'f32l' 44100 Hz->44100 Hz Stereo->Stereo
core debug: looking for audio converter module matching "any": 12 candidates
audio_format debug: s16l->f32l, bits per sample: 16->32
core debug: using audio converter module "audio_format"
core debug: conversion pipeline complete
core debug: conversion: 'f32l'->'f32l' 44100 Hz->44100 Hz Stereo->Stereo
core debug: Buffering 0%
core debug: conversion pipeline complete
core debug: looking for audio resampler module matching "any": 3 candidates
core debug: Buffering 0%
core debug: Buffering 0%
core debug: Buffering 0%
core debug: Buffering 0%
core debug: Buffering 0%
.......

并且,一旦 gstreamer 命令开始发送 PCM,就会显示下面的日志。 通常,当命令启动时,gstreamer 会被此消息“新时钟:GstSystemClock”阻止。

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = audio/x-    raw, format=(string)S32LE, layout=(string)interleaved, rate=(int)44100,     channels=(int)2
/GstPipeline:pipeline0/GstQueue:queue0.GstPad:sink: caps = audio/x-raw,   format=(string)S32LE, layout=(string)interleaved, rate=(int)44100, channels=  (int)2
/GstPipeline:pipeline0/GstQueue:queue0.GstPad:sink: caps = audio/x-raw,   format=(string)S32LE, layout=(string)interleaved, rate=(int)44100, channels= (int)2
/GstPipeline:pipeline0/GstAudioConvert:audioconvert0.GstPad:src: caps =   audio/x-raw, layout=(string)interleaved, rate=(int)44100, format=(string)S16BE,                                             channels=(int)2, channel-mask=(bitmask)0x0000000000000003
/GstPipeline:pipeline0/GstQueue:queue1.GstPad:sink: caps = audio/x-raw, layout=(string)interleaved, rate=(int)44100, format=(string)S16BE, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
/GstPipeline:pipeline0/GstQueue:queue1.GstPad:sink: caps = audio/x-raw, layout=(string)interleaved, rate=(int)44100, format=(string)S16BE, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
/GstPipeline:pipeline0/GstRtpL16Pay:rtpl16pay0.GstPad:src: caps = application/x-rtp, media=(string)audio, clock-rate=(int)44100, encoding-name=(string)L16, encoding-params=(string)2, channels=(int)2, payload=(int)10, s-s-rc=(uint)2226113402, timestamp-offset=(uint)1744959080, seqnum-offset=(uint)62815
/GstPipeline:pipeline0/GstUDPSink:udpsink0.GstPad:sink: caps = application/x-rtp, media=(string)audio, clock-rate=(int)44100, encoding-name=(string)L16, encoding-params=(string)2, channels=(int)2, payload=(int)10, s-s-rc=(uint)2226113402, timestamp-offset=(uint)1744959080, seqnum-offset=(uint)62815
/GstPipeline:pipeline0/GstRtpL16Pay:rtpl16pay0.GstPad:sink: caps = audio/x-raw, layout=(string)interleaved, rate=(int)44100, format=(string)S16BE, channels=(int)2, channel-mask=(bitmask)0x0000000000000003
/GstPipeline:pipeline0/GstAudioConvert:audioconvert0.GstPad:sink: caps = audio/x-raw, format=(string)S32LE, layout=(string)interleaved, rate=(int)44100, channels=(int)2
/GstPipeline:pipeline0/GstRtpL16Pay:rtpl16pay0: timestamp = 1744959080
/GstPipeline:pipeline0/GstRtpL16Pay:rtpl16pay0: seqnum = 62815
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 0:00:00.622147167
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

gst-launch-0.1 没有问题,只有 1.0 有问题。 有什么问题吗?

【问题讨论】:

【参考方案1】:

如果我将您的 filesrc 替换为 audiotestsrc,则该示例适用于我。还是让我指出一些改进的空间。

    使用 audioparse 代替第一个 capsfilter 不要进行两次音频转换。

这是一个适合我的简化管道:

gst-launch-1.0 -v audiotestsrc ! audioresample ! audioconvert ! rtpL16pay pt=10 ! application/x-rtp, pt=10, encoding-name=L16, payload=10, clock-rate=44100, channels=2 ! udpsink host=localhost port=5555

【讨论】:

据我所知,audiotestsrc 听起来就像采样的正弦波。 当然,这只是让我尝试,因为我没有你的文件。您可以继续使用 filesrc。

以上是关于使用 gstreamer 将 PCM 数据发送到 VLC 播放器的主要内容,如果未能解决你的问题,请参考以下文章

使用 GStreamer 播放保存在数组中的原始 PCM

如何使用 GStreamer 以编程方式创建视频(来自 RGB 和 PCM)?

Gstreamer RTP传输视频+文字

如何使用 Gstreamer 通过 RTMP 流式传输?

iOS录制时如何将PCM缓冲区实时转换为AAC数据?

通过 gstreamer udpsink 流式传输 h.264 时如何解决图像问题