首页 > 解决方案 > 将 10 秒的 wav 文件添加到已经在播放的 gstreamer 管道

问题描述

我有一个从 python gst 绑定创建的 gstreamer 管道,它被设置为将耳机的麦克风播放回耳机的扬声器。这工作正常,并且正在像这样的管道中播放:

JackAudioSrc -> GstAudioMixer -> Queue -> GstJackAudioSink

然后很多秒后,我想在管道中播放一个短的 10 秒 .wav 文件,以便 wav 文件与麦克风混合并在耳机上听到。为此,将 GstFileSrc 动态添加到 GstAudioMixer 中,以将 10 秒的短 wav 文件混合到耳机的扬声器中,从而提供如下管道:

GstJackAudioSrc             -> GstAudioMixer -> Queue -> GstJackAudioSink
                             /
Gstfilesrc -> Gstwavparse ->/

当 Gstfilesrc 和 Gstwavparse 文件被动态添加到混音器的 sink pad 时,在管道启动后的 6 秒内,只听到最后 4 秒的 wav。

问题似乎是 wav 文件寻找相对于管道开始播放的时间。

我尝试在 multifilesrc 中更改“do-timestamp”,并且 GstIndentity“sync”=True,但找不到在 filesrc 上设置“live”的方法,以及许多其他方法,但无济于事。

但是,如果管道设置为 Gst.State.NULL,则整个 10 秒的 wav 文件将很好地播放,然后在 6 秒添加 filesrc 时返回 Gst.State.PLAYING。这在流水线时间设置回零时起作用,但这会在耳机上产生咔嗒声,这是不可接受的。

如果在任何随机时间添加到管道中,如何确保 wav 文件从 wav 文件的开头开始播放,以便在耳机上听到整个 10 秒?


更新:

我现在可以通过在 wavparse 之前添加时钟同步并设置其时间戳偏移来正确获取波形文件的时间:

nanosecs = pipeline.query_position(Gst.Format.TIME)[1]
clocksync.set_property("ts-offset", nanosecs)

虽然现在开始/停止时间是正确的,但 wav 音频已损坏,只能听到咔哒声和闪烁声,但至少它在正确的时间开始播放并在正确的时间结束。请注意,如果没有时钟同步,wav 文件的音频非常清晰,它只是在错误的时间开始和停止。所以 ts-offset 以某种方式破坏了音频。

为什么音频会损坏?

标签: gstreamerpython-gstreamer

解决方案


所以我得到了这个工作,答案不是使用时钟同步,而是请求一个混音器接收垫,然后在混音器接收垫上调用 set_offset(nanosecs),然后将 wavparse 链接到混音器:

    sink_pad = audio_mixer.get_request_pad("sink_%u")
    nanosecs = pipeline.query_position(Gst.Format.TIME)[1]
    sink_pad.set_offset(nanosecs)
    sink_pad.add_probe(GstPadProbeType.IDLE, wav_callback)

    def wav_callback(pad, pad_probe_info, userdata):
        wavparse.link(audio_mixer)
        wav_bin.set_state(Gst.State.PLAYING)
        return Gst.PadProbeReturn.REMOVE   

然后如果需要重绕/重放wav文件:

    def replay_wav():
        global wav_bin
        global sink_pad
        wav_bin.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 0)
        nanosecs = pipeline.query_position(Gst.Format.TIME)[1]
        sink_pad.set_offset(nanosecs)

推荐阅读