基于gstreamer与GTK的函数封装,可直接与GtkWidget事件绑定调用。实现了触发事件开始视频录像,再次触发结束录制并保存。注意gstreamer结点tee的绑定与设置。
typedef struct _MediaData
{
GstElement *pipeline;
GstElement *tee_video_stream ;
GstElement *videomux, *record_queue,*file_sink;
GstPad *queue_record_pad, *tee_record_pad;
GstPad *queue_capture_pad, *tee_capture_pad;
} MediaData;
typedef struct _AppData
{
GstElement *pipeline_app;
GstElement *video_sink;
MediaData mediaData;
} AppData;
static AppData appdata;
static bool video_record_enable = false;
static int video_recording_cb (GtkButton * button, CustomData * data)
{
static int record_time = 1;
MediaData* recordingData = &appdata.mediaData;
GstPadTemplate *templ;
templ = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (recordingData->tee_video_stream), "src_%u");
recordingData->tee_record_pad = gst_element_request_pad (recordingData->tee_video_stream, templ, NULL, NULL);
if (video_record_enable == false)
{
printf("\nVideo Press!\n");
button_operations((gpointer)DISABLE_ALLBUTTONS);
recordingData->record_queue = gst_element_factory_make ("queue", "record_queue");
recordingData->videomux = gst_element_factory_make ("matroskamux", "video_mux");
recordingData->file_sink = gst_element_factory_make ("filesink", "file_sink");
g_object_set(recordingData->videomux, "offset-to-zero", TRUE, NULL);
g_object_set (GST_OBJECT(recordingData->file_sink),"buffer-size", 67108864 ,NULL );
g_object_set (GST_OBJECT(recordingData->file_sink),"async", false ,NULL );
char filename[1000];
sprintf(filename, "/home/123/test%d.mp4", record_time);
g_object_set (G_OBJECT(recordingData->file_sink),"location",filename,NULL);
record_time++;
gst_bin_add_many (GST_BIN (recordingData->pipeline),(recordingData->record_queue), (recordingData->videomux), (recordingData->file_sink),NULL);
if (gst_element_link_many (recordingData->record_queue, recordingData->videomux, recordingData->file_sink, NULL) != TRUE)
{
g_printerr ("Elements could not be linked in record branch\n");
return 1;
}
gst_element_sync_state_with_parent (recordingData->record_queue);
gst_element_sync_state_with_parent (recordingData->videomux);
gst_element_sync_state_with_parent (recordingData->file_sink);
recordingData->queue_record_pad = gst_element_get_static_pad (recordingData->record_queue, "sink");
if (gst_pad_link (recordingData->tee_record_pad, recordingData->queue_record_pad) != GST_PAD_LINK_OK)
{
g_printerr ("Tee capture could not be linked.\n");
}
video_record_enable = true;
}
else
{
printf("\nVideo Release!\n");
gst_element_set_state (recordingData->file_sink, GST_STATE_NULL);
gst_element_set_state (recordingData->videomux, GST_STATE_NULL);
gst_element_set_state (recordingData->record_queue, GST_STATE_NULL);
recordingData->queue_record_pad = gst_element_get_static_pad (recordingData->record_queue, "sink");
gst_pad_unlink(recordingData->tee_record_pad, recordingData->queue_record_pad);
gst_bin_remove(GST_BIN (recordingData->pipeline), recordingData->record_queue);
gst_bin_remove(GST_BIN (recordingData->pipeline), recordingData->videomux);
gst_bin_remove(GST_BIN (recordingData->pipeline), recordingData->file_sink);
gst_element_release_request_pad (recordingData->tee_video_stream, recordingData->tee_record_pad);
gst_object_unref (recordingData->queue_record_pad);
gst_object_unref (recordingData->tee_record_pad);
video_record_enable = false;
}
return 1;
}