Dynamic Recording Audio and Video with Gstreamer
I want to use muxer and save video and audio on same file. Is there any way to start and stop this pipeline.
My Pipelines:
1 - videosrcbin = v4l2src ! video/x-raw, width=640, height=480 ! videoconvert ! tee name=videoTee ! queue ! autovideosink
2- audiosrcbin = autoaudiosrc name=audiosrc ! audioconvert ! tee name=audioTee ! queue ! autoaudiosink
3- videorecordbin = queue name="videoQueue" ! x264enc name="encoder" tune=zerolatency bitrate=1000 key-int-max=30 ! video/x-h264, profile=constrained-baseline ! queue
4- audiorecordbin = queue name="audioQueue" ! opusenc name="encoder" ! audio/x-opus, profile=constrained-baseline ! queue
5- recordbin = mp4mux name=recordMux ! filesink name="recordFileSink" sync=false async=false location="x%1.mp4"
My start recording function:
PlayerResult Player::startRecording() {
_recordBin = createRecordBin();
_recordBinVideo = createRecordBinForVideo();
_recordBinAudio = createRecordBinForAudio();
gst_bin_add_many(GST_BIN(GST_PIPELINE_CAST(_pipeline)), _recordBin, NULL);
gst_bin_add_many(GST_BIN(_recordBin), _recordBinVideo, _recordBinAudio, NULL);
gst_element_sync_state_with_parent (_recordBin);
gst_element_sync_state_with_parent (_recordBinVideo);
gst_element_sync_state_with_parent (_recordBinAudio);
GstElement* videoTee = gst_bin_get_by_name (GST_BIN(_videoSrcBin), "videoTee");
GstElement* audioTee = gst_bin_get_by_name (GST_BIN(_audioSrcBin), "audioTee");
GstElement* muxer = gst_bin_get_by_name (GST_BIN(_recordBin), "recordMux");
GstElement* videoQueue = gst_bin_get_by_name (GST_BIN(_recordBinVideo), "videoQueue");
GstElement* audioQueue = gst_bin_get_by_name (GST_BIN(_recordBinAudio), "audioQueue");
if(!videoTee || !audioTee || !muxer || !videoQueue || !audioQueue) {
qInfo("Element not found !");
return ElementCreateError;
}
_videoTeeSrc = gst_element_get_request_pad (videoTee, "src_%u");
_audioTeeSrc = gst_element_get_request_pad (audioTee, "src_%u");
GstPad* videoQueueSink = gst_element_get_static_pad(videoQueue, "sink");
GstPad* audioQueueSink = gst_element_get_static_pad(audioQueue, "sink");
if(!gst_element_link_pads (videoTee, GST_OBJECT_NAME(_videoTeeSrc), _recordBinVideo,GST_OBJECT_NAME(videoQueueSink))) {
qInfo("Error on linking video with record bin!");
return ElementLinkError;
}
if(!gst_element_link_pads (audioTee, GST_OBJECT_NAME(_audioTeeSrc), _recordBinAudio,GST_OBJECT_NAME(audioQueueSink))) {
qInfo("Error on linking audio with record bin!");
return ElementLinkError;
}
if(!gst_element_link(_recordBinVideo, muxer) || !gst_element_link(_recordBinAudio, muxer)) {
qInfo("Error on linking muxers");
return ElementLinkError;
}
videoRecordSinkPad = gst_pad_get_peer (_videoTeeSrc);
audioRecordSinkPad = gst_pad_get_peer (_audioTeeSrc);
g_object_unref (videoTee);
g_object_unref (audioTee);
g_object_unref (videoQueueSink);
g_object_unref (audioQueueSink);
g_object_unref (muxer);
_isRecording = true;
return Success;
}
This function works good but how can I stop recording. I am sending EOS signals both video and audio encoders. Then when eos signals come on filesink, I am removing all record elements from pipeline and memory.
I am clicking record button on my app and sometimes my app is crashing. When I press my record button the recording must be saved on seperate file. If I press n times record button, the program must save n/2 different recordings. But program stucks randomly and some threads freezing. Buttons and display can't be work.I guess it is a deadlock. How can I resolve this problem ?
Thanks..