【发布时间】:2015-06-30 21:04:16
【问题描述】:
我正在尝试使用 GStreamer 编写一个简单的音乐播放器。我想播放任意音乐文件ABS_FILE_PATH,将样本存储用于其他目的,然后在到达流的原始结尾后无限期循环。
现在播放音乐可以正常播放,直到播放完曲目的最后一个样本后不久。大多数时候只有沉默,但有时会有一两个声音样本表明曲目刚刚开始播放。这同样适用于终端输出。它表明,在循环开始后的几个样本中,need-data 信号的发送比以前更频繁。
我使用fakesink 转储数据,这似乎工作得很好。数据只是按预期循环。
那么这里会发生什么?为什么样本不播放第二次(第三次,第四次,...)?我的想法已经用完了。
下面我添加了一个没有任何 UI 的最小示例,但存在同样的问题:
import itertools, signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
from gi.repository import Gst, GstApp, Gtk
Gst.init(None)
# read samples with Gst.AppSink from a playbin
playbin = Gst.ElementFactory.make("playbin")
playbin.props.uri = "file://" + ABS_FILE_PATH # only works with absolute paths
playbin.props.audio_sink = GstApp.AppSink(sync=False, emit_signals=True)
playbin.set_state(Gst.State.PLAYING)
# loop over all samples
def samples(app_sink):
samples = []
sample = app_sink.pull_sample()
while sample:
yield sample
samples.append(sample)
sample = app_sink.pull_sample()
print('looping')
for sample in itertools.cycle(samples):
yield sample
# write samples with Gst.AppSrc
def need_data(appsrc, length, samples):
print('sample')
sample = next(samples)
appsrc.set_caps(sample.get_caps())
appsrc.push_buffer(sample.get_buffer())
src = GstApp.AppSrc(format=Gst.Format.TIME, emit_signals=True)
src.connect('need-data', need_data, samples(playbin.props.audio_sink))
# to the autoaudiosink or just a fakesink
sink = Gst.ElementFactory.make("autoaudiosink")
#sink = Gst.ElementFactory.make("fakesink")
#sink.props.dump = True # dump contents of fakesink
# playback
play = Gst.Pipeline()
play.add(src)
play.add(sink)
src.link(sink)
play.set_state(Gst.State.PLAYING)
Gtk.main()
gst-plugins-base: 1.4.4
【问题讨论】:
-
您的样本可能会循环时间戳,并且在第二次运行时,当它们返回 0 时,它们会因为迟到而被丢弃。也许您想在 appsrc 中设置 do-timestamp 让它为您添加时间戳,或者您可以累积时间戳/持续时间并在推送之前将它们设置为样本。
-
演示时间戳是问题所在。谢谢。
标签: python audio-player gstreamer