我正在尝试使用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 :(得分:0)
我在[{3}}的comment的帮助下找到了一个可行的解决方案。
thiagoss列出与时间戳相关的所有字段
struct GstBuffer {
[...]
/* timestamp */
GstClockTime pts;
GstClockTime dts;
GstClockTime duration;
[...]
};
其中演示文稿时间戳pts
是相关值。在第二次使用样本之前将其设置为Gst.CLOCK_TIME_NONE
将解决问题:
# loop over all samples
def samples(app_sink):
samples = []
sample = app_sink.pull_sample()
while sample:
yield sample
sample.get_buffer().pts = Gst.CLOCK_TIME_NONE #unset the pts
samples.append(sample)
sample = app_sink.pull_sample()
print('looping')
for sample in itertools.cycle(samples):
yield sample