使用GStreamer + Python将FLAC转换为MP3?

Lia*_*iam 3 python audio gstreamer

这是我试图复制的命令:

gst-launch filesrc location=test.flac ! flacdec ! lame ! filesink location=test.mp3
Run Code Online (Sandbox Code Playgroud)

当我运行此命令时,它工作得很漂亮.我试图使用Pythong绑定来复制它,但根本没有运气.我不会在这些脚本中出现任何错误,但它们无法按预期工作:

当我运行这个脚本时,我只得到一个空的MP3文件:

import gst
pipeline = gst.parse_launch('filesrc location="test.flac" ! flacdec ! lame ! filesink location="test.mp3"')
pipeline.set_state(gst.STATE_PLAYING)
Run Code Online (Sandbox Code Playgroud)

当我运行这个脚本时,我得到一个损坏的MP3文件:

import gst

converter = gst.Pipeline('converter')

source = gst.element_factory_make('filesrc', 'file-source')
source.set_property('location', 'test.flac')

decoder = gst.element_factory_make('flacdec', 'decoder')

encoder = gst.element_factory_make('lame', 'encoder')

sink = gst.element_factory_make('filesink', 'sink')
sink.set_property('location', 'test.mp3')

converter.add(source, decoder, encoder, sink)

source.link(sink)

converter.set_state(gst.STATE_PLAYING)
Run Code Online (Sandbox Code Playgroud)

谁知道我做错了什么?

max*_*kin 6

Gstreamer使用GObject作为框架,因此您需要运行gobject.MainLoop()以在管道中启动消息流:

import gobject
import gst
pipeline = gst.parse_launch('filesrc location="test.flac" ! flacdec ! lame ! filesink location="test.mp3"')
pipeline.set_state(gst.STATE_PLAYING)

gobject.threads_init()
gobject.MainLoop().run()
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,您还需要运行MainLoop并链接所有管道元素(例如with element_link_many).您只将源连接到接收器,因此您的实际管道就是filesrc ! filesink.

这是更正后的代码:

import gobject
import gst

converter = gst.Pipeline('converter')

source = gst.element_factory_make('filesrc', 'file-source')
source.set_property('location', 'test.flac')

decoder = gst.element_factory_make('flacdec', 'decoder')
encoder = gst.element_factory_make('lame', 'encoder')

sink = gst.element_factory_make('filesink', 'sink')
sink.set_property('location', 'test.mp3')

converter.add(source, decoder, encoder, sink)
gst.element_link_many(source, decoder, encoder, sink)

converter.set_state(gst.STATE_PLAYING)

gobject.threads_init()
gobject.MainLoop().run()
Run Code Online (Sandbox Code Playgroud)