Засунуть h264 в mp4 на python с gstreamer
Создаю пайп:
def encoder(name):
pipeline = Gst.Pipeline()
audioin = Gst.ElementFactory.make("appsrc", "audioin")
videoin = Gst.ElementFactory.make("appsrc", "videoin")
h264parse = Gst.ElementFactory.make("h264parse", "h264")
alaw = Gst.ElementFactory.make("rawaudioparse", "alaw")
faac = Gst.ElementFactory.make("faac", "faac")
mux = Gst.ElementFactory.make("mp4mux", "mux")
filesink = Gst.ElementFactory.make("filesink", "fsink")
filesink.set_property("location", name + ".mp4")
videoin.set_property("caps", Gst.caps_from_string('video/x-h264,width=1920,height=1080,framerate=9/1,stream-format=(string)avc'))
audioin.set_property("caps", Gst.caps_from_string('audio/x-alaw,channels=1,rate=8000'))
pipeline.add(videoin)
pipeline.add(audioin)
pipeline.add(alaw)
pipeline.add(faac)
pipeline.add(h264parse)
pipeline.add(mux)
pipeline.add(filesink)
audioin.link(alaw)
videoin.link(h264parse)
h264parse.link(mux)
alaw.link(faac)
faac.link(mux)
mux.link(filesink)
return pipeline, audioin, videoin
pipeline, audioin, videoin = encoder('filename')
Вот тут из reader.video, reader.audio получаю данные и пихаю в буфер
async def convert(reader):
async def readforever(stream, cb):
while not stream.at_eof():
cb(await stream.read(2048))
def push(src):
def pushbuffer(data):
print(rotating(), len(data), ' ', end="\r", flush=True)
buf = Gst.Buffer.new_allocate(None, len(data), None)
buf.fill(0, data)
src.emit('push-buffer', buf)
return True
return pushbuffer
pipeline.set_state(Gst.State.PLAYING)
print('started')
await asyncio.gather(readforever(reader.video, push(videoin)), readforever(reader.audio, push(audioin)))
videoin.emit("end-of-stream")
audioin.emit("end-of-stream")
print(pipeline)
bus = pipeline.get_bus()
print(await reader.picture.read())
print(await reader.bort.read())
print('eos')
#bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.EOS) # зависает
pipeline.set_state(Gst.State.NULL)
Лог gstreamer говорит что данные пришли, но в файле нет ничего.
Ответы (1 шт):
Автор решения: eri
→ Ссылка
Нужно сделать ворэраунд на баг https://bugzilla.gnome.org/show_bug.cgi?id=659489
h264parse = Gst.ElementFactory.make("h264parse", "h264")
GstBase.BaseParse.set_infer_ts(h264parse, True)
GstBase.BaseParse.set_pts_interpolation(h264parse, True)
И пропустить входящий поток через queue
pipeline = Gst.Pipeline()
audioin = Gst.ElementFactory.make("appsrc", "audioin")
videoin = Gst.ElementFactory.make("appsrc", "videoin")
h264parse = Gst.ElementFactory.make("h264parse", "h264")
GstBase.BaseParse.set_infer_ts(h264parse, True)
GstBase.BaseParse.set_pts_interpolation(h264parse, True)
alaw = Gst.ElementFactory.make("alawdec", "alaw")
faac = Gst.ElementFactory.make("faac", "faac")
mux = Gst.ElementFactory.make("mp4mux", "mux")
filesink = Gst.ElementFactory.make("filesink", "fsink")
filesink.set_property("location", name + ".mp4")
vq = Gst.ElementFactory.make('queue', 'vq')
aq = Gst.ElementFactory.make('queue', 'aq')
vf = Gst.ElementFactory.make("capsfilter", 'vf')
af = Gst.ElementFactory.make("capsfilter", 'af')
vf.set_property("caps", Gst.caps_from_string('video/x-h264,width=1920,height=1080,framerate=9/1,stream-format=(string)avc'))
af.set_property("caps", Gst.caps_from_string('audio/x-alaw,channels=1,rate=8000'))
pipeline.add(videoin)
pipeline.add(vq)
pipeline.add(vf)
pipeline.add(aq)
pipeline.add(af)
pipeline.add(audioin)
pipeline.add(alaw)
pipeline.add(faac)
pipeline.add(h264parse)
pipeline.add(mux)
pipeline.add(filesink)
audioin.link(aq)
aq.link(af)
af.link(alaw)
videoin.link(vq)
vq.link(h264parse)
h264parse.link(mux)
alaw.link(faac)
faac.link(mux)
mux.link(filesink)
return pipeline, audioin, videoin