0

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.

0 Answers0