I have never used GStreamer before now, and I am not a c++ developer. This is all extremely confusing to me but I really need to acheive this functionality and ffmpeg was performing too slow for my needs. I have seen from multiple sources that muxing video into other formats and resolutions can be done faster using G Streamer. Eventually I intend on writing this as a micro-service for my golang application to inter-op with however meanwhile I cant even get it to just convert one fully valid formatted video into 4 different bit rates and resolutions. Could someone please provide me with some insight as to whats going on and keep in mind I barely know or understand any of the G Streamer functionality?
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
Gst.init(None)
input_file = 'C:/msys64/home/User/share/BlueMeringue/media/input/upload_originalaETX.mp4'
output_path = 'C:/msys64/home/User/share/BlueMeringue/media/output/upload_dist'
resolutions = [240, 480, 720, 1080]
bitrates = [300, 600, 1200, 2400]
for i, res in enumerate(resolutions):
# Create a pipeline for each resolution and output format
pipeline = Gst.Pipeline()
# Create elements for reading input file and writing output files
filesrc = Gst.ElementFactory.make("filesrc", "filesrc")
filesrc.set_property("location", input_file)
decode = Gst.ElementFactory.make("decodebin", "decode")
queue = Gst.ElementFactory.make("queue", "queue")
filter = Gst.ElementFactory.make("capsfilter", "filter")
filter.set_property("caps", Gst.Caps.from_string(f"video/x-raw,format=I420,width={res},height={res},framerate=30/1"))
encoder = Gst.ElementFactory.make("x264enc", "encoder")
encoder.set_property("speed-preset", 1)
encoder.set_property("tune", 0x00000004)
encoder.set_property("bitrate", bitrates[i])
encoder.set_property("key-int-max", 15)
mux = Gst.ElementFactory.make("mp4mux", "mux")
filesink = Gst.ElementFactory.make("filesink", "filesink")
filesink.set_property("location", f"{output_path}_{res}p.mp4")
# Add elements to the pipeline
pipeline.add(filesrc)
pipeline.add(decode)
pipeline.add(queue)
pipeline.add(filter)
pipeline.add(encoder)
pipeline.add(mux)
pipeline.add(filesink)
# Link elements together
filesrc.link(decode)
decode.link(queue)
queue.link(filter)
filter.link(encoder)
encoder.link(mux)
mux.link(filesink)
# Set pipeline to playing state
pipeline.set_state(Gst.State.PLAYING)
# Wait for completion or error
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)
pipeline.send_event(Gst.Event.new_eos())
if msg:
if msg.type == Gst.MessageType.ERROR:
err, debug = msg.parse_error()
print(f"Error: {err}. Debug: {debug}")
elif msg.type == Gst.MessageType.EOS:
print(f"Pipeline for resolution {res}p and bitrate {bitrates[i]} completed successfully.")
else:
print("Unknown error occurred.")
# Clean up
pipeline.set_state(Gst.State.NULL)
The error this produces when running is:
Error: gst-stream-error-quark: Internal data stream error. (1). Debug: ../gst-plugins-good-1.22.0/gs
t/isomp4/qtdemux.c(6937): gst_qtdemux_loop (): /GstPipeline:pipeline0/GstDecodeBin:decode/GstQTDemux
:qtdemux0:
streaming stopped, reason not-linked (-1)
Error: gst-stream-error-quark: Internal data stream error. (1). Debug: ../gst-plugins-good-1.22.0/gs
t/isomp4/qtdemux.c(6937): gst_qtdemux_loop (): /GstPipeline:pipeline1/GstDecodeBin:decode/GstQTDemux
:qtdemux1:
streaming stopped, reason not-linked (-1)
Error: gst-stream-error-quark: Internal data stream error. (1). Debug: ../gst-plugins-good-1.22.0/gs
t/isomp4/qtdemux.c(6937): gst_qtdemux_loop (): /GstPipeline:pipeline2/GstDecodeBin:decode/GstQTDemux
:qtdemux2:
streaming stopped, reason not-linked (-1)
Error: gst-stream-error-quark: Internal data stream error. (1). Debug: ../gst-plugins-good-1.22.0/gs
t/isomp4/qtdemux.c(6937): gst_qtdemux_loop (): /GstPipeline:pipeline3/GstDecodeBin:decode/GstQTDemux
:qtdemux3:
streaming stopped, reason not-linked (-1)
I am expecting it to output 4 videos in different bitrates and resolutions based on the input video. I have tried scavenging the documentation but I dont understand any of it and everyone seems to have a completely different setup and enviroment and I cant find anyone with my specific issue that I can understand whats even being expressed in the solution because of complicated GStreamer terminology that makes no sense to me.