Dear Team,
I’ve been working on a task that involves splitting an MP4 file containing both audio and video into segments of 10 seconds each. Initially, I was successful in achieving this through a raw pipeline. However, I’m currently facing challenges while attempting to replicate this behavior in C++ code.
The specific hurdle I encountered involves linking the splitmuxsink
element to handle both the audio and video elements within the code. Below, I’ve provided the pipeline command and a snippet of the code I’ve been working on:
Pipeline:
gst-launch-1.0 -ev v4l2src ! video/x-raw ! videoconvert ! queue ! x264enc tune=zerolatency ! queue ! splitmuxsink max-size-time=10000000000 muxer=avimux name=mux location=video%04d.avi autoaudiosrc ! voaacenc ! queue ! mux.audio_0
Code Snippet:
// Compile commend = g++ -o splitmuxsink splitmuxsink.cpp `pkg-config --cflags --libs gstreamer-1.0`
#include <gst/gst.h>
int main(int argc, char *argv[]) {
GstElement *pipeline, *v4l2src, *video_convert, *x264enc, *muxer, *splitmuxsink, *autoaudiosrc, *queue ,*voaacenc;
GstPad *video_pad, *audio_pad;
// Initialize GStreamer
gst_init(&argc, &argv);
// Create elements
pipeline = gst_pipeline_new("pipeline");
v4l2src = gst_element_factory_make("v4l2src", "v4l2src");
video_convert = gst_element_factory_make("videoconvert", "video_convert");
x264enc = gst_element_factory_make("x264enc", "x264enc");
muxer = gst_element_factory_make("avimux", "mux");
splitmuxsink = gst_element_factory_make("splitmuxsink", "splitmuxsink");
autoaudiosrc = gst_element_factory_make("autoaudiosrc", "autoaudiosrc");
voaacenc = gst_element_factory_make("voaacenc", "voaacenc");
queue = gst_element_factory_make("queue", "enc-queue");
if (!pipeline || !v4l2src || !video_convert || !x264enc || !muxer || !splitmuxsink || !autoaudiosrc || !voaacenc) {
g_printerr("One or more elements could not be created. Exiting.\n");
return -1;
}
// Set properties
g_object_set(splitmuxsink, "max-size-time", G_GUINT64_CONSTANT(10000000000),
"muxer", muxer,
"name", "mux",
"location", "video%04d.avi", NULL);
// Build the pipeline
gst_bin_add_many(GST_BIN(pipeline), v4l2src, video_convert, x264enc, splitmuxsink, NULL);
// Link video elements
if (!gst_element_link_many(v4l2src, video_convert, x264enc,splitmuxsink, NULL)) {
g_printerr("Video elements could not be linked.\n");
gst_object_unref(pipeline);
return -1;
}
gst_bin_add_many(GST_BIN(pipeline),autoaudiosrc,voaacenc,queue, NULL);
// Link audio elements
if (!gst_element_link_many(autoaudiosrc,voaacenc,queue,splitmuxsink, NULL)) {
g_printerr("Audio elements could not be linked.\n");
gst_object_unref(pipeline);
return -1;
}
// Get pads and link them
// video_pad = gst_element_get_request_pad(x264enc, "src");
// audio_pad = gst_element_get_request_pad(voaacenc, "src");
// gst_pad_link(video_pad, gst_element_get_request_pad(splitmuxsink, "video_%u"));
// gst_pad_link(audio_pad, gst_element_get_request_pad(splitmuxsink, "audio_%u"));
// Set the pipeline state to playing
GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(pipeline);
return -1;
}
// Wait until error or EOS
GstBus *bus = gst_element_get_bus(pipeline);
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
// Free resources
if (msg != NULL)
gst_message_unref(msg);
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
Issue = Audio elements could not be linked.
I kindly request your assistance in resolving this issue. It seems that linking the splitmuxsink
element in the C++ code to handle both audio and video is proving to be challenging. Your guidance or any fixes you can provide would be immensely helpful.
Thank you for your attention to this matter.
Best regards,
Sulthan