alsa 싱크를 삭제하고 런타임에 새 싱크를 만들고 싶습니다. 이전 요소와 새 요소가 모두 삭제되고 성공적으로 만들어졌습니다. 그리고 오디오를 다시 시작하려고 시도했지만 오디오가 재생되지 않았습니다. 잘못된 부분을 알려주십시오.gstreamer - 런타임에 오디오 싱크 교체
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <gst/gst.h>
#include <pthread.h>
GstElement *pipeline, *src_, *conv_, *alsaaudiosink, *volume_, *fake_sink_;
gint64 pos, len;
GstPad *src_pad;
GstFormat fmt = GST_FORMAT_TIME;
GstSeekFlags gst_flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT);
void OnNewPadAdded (GstElement* src, GstPad* new_pad, gpointer data);
GstBusSyncReply GstreamerMessageHandler(GstBus* gst_bus, GstMessage* message, gpointer data);
GstBusSyncReply GstreamerMessageHandler(GstBus* gst_bus, GstMessage* message, gpointer data) {
printf("GstreamerMessageHandler\n");
switch(GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_EOS:
break;
case GST_MESSAGE_BUFFERING:
break;
case GST_MESSAGE_DURATION:
break;
case GST_MESSAGE_ERROR:
break;
case GST_MESSAGE_STATE_CHANGED:
break;
case GST_MESSAGE_STREAM_STATUS:
default:
break;
}
return GST_BUS_DROP;
}
void OnNewPadAdded (GstElement* src, GstPad* new_pad, gpointer data) {
GstPad *sink_pad_audio = gst_element_get_static_pad (conv_, "sink");
if (GST_PAD_IS_LINKED (sink_pad_audio)) {
g_object_unref (sink_pad_audio);
return;
}
gst_pad_link (new_pad, sink_pad_audio);
g_object_unref (sink_pad_audio);
}
void reset_fake_sink() {
//remove fakesink
gst_element_unlink(conv_, fake_sink_);
gst_bin_remove (GST_BIN (pipeline), fake_sink_);
gst_element_set_state (fake_sink_, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (fake_sink_));
}
void create_alsa_sink() {
printf("create alsa\n");
alsaaudiosink = gst_element_factory_make ("alsasink", "sink");
// g_object_set(alsaaudiosink, "device", "AdevWebMainOut", NULL);
gst_bin_add (GST_BIN (pipeline), alsaaudiosink);
gst_element_link(conv_, alsaaudiosink);
gst_element_sync_state_with_parent (alsaaudiosink);
gst_element_sync_state_with_parent (conv_);
}
void remove_alsa_sink() {
printf("remove alsa\n");
gst_element_unlink(conv_, alsaaudiosink);
gst_bin_remove (GST_BIN (pipeline), alsaaudiosink);
gst_element_set_state (alsaaudiosink, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (alsaaudiosink));
gst_element_sync_state_with_parent (conv_);
}
int main (int argc, char *argv[]) {
gst_init(&argc, &argv);
if (argc != 2) {
printf("%s <mp3 filename>\n", __FUNCTION__, argv[0]);
exit (-1);
}
src_ = gst_element_factory_make ("uridecodebin", "source");
conv_ = gst_element_factory_make ("audioconvert", "convert");
fake_sink_ = gst_element_factory_make ("fakesink", NULL);
pipeline = gst_pipeline_new ("pipeline");
if (!pipeline || !src_ || !conv_ || !fake_sink_) {
return -1;
}
gst_bin_add_many (GST_BIN (pipeline), src_, conv_, fake_sink_, NULL);
if (!gst_element_link (conv_, fake_sink_)) {
gst_object_unref(pipeline);
return -1;
}
// Bus - Sync.
GstBus* gst_bus;
gst_bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
gst_bus_set_sync_handler(gst_bus, GstreamerMessageHandler, NULL);
gst_object_unref(gst_bus);
g_signal_connect (src_, "pad-added", G_CALLBACK (OnNewPadAdded), NULL);
g_object_set (src_, "uri", argv[1], NULL);
gst_element_set_state(pipeline, GST_STATE_PAUSED);
//remove fakesink
reset_fake_sink();
//create new sink
create_alsa_sink();
gst_element_set_state (pipeline, GST_STATE_PLAYING);
static int is_quiting = 0;
while (1) {
if(!(gst_bin_iterate_elements (GST_BIN (pipeline)))) break;
printf(" q:Quit, press'c' : Pause -> remove sink -> create sink -> Play\n");
char ch =0 ;
ch=getchar();
switch (ch) {
case 'c':
/* pause */
gst_element_set_state (pipeline, GST_STATE_PAUSED);
remove_alsa_sink();
create_alsa_sink();
gst_element_set_state (pipeline, GST_STATE_PLAYING);
break;
case 'q':
is_quiting = 1;
break;
default:
break;
}
if(is_quiting) break;
}
/* stop the pipeline */
gst_element_set_state (pipeline, GST_STATE_NULL);
/* we don't need a reference to these objects anymore */
gst_object_unref (GST_OBJECT (pipeline));
/* unreffing the pipeline unrefs the contained elements as well */
exit (0);
}
오디오가 출력되지 않으면 아래를 검색하여 재생하십시오.
gst_element_seek_simple (파이프 라인, GST_FORMAT_TIME, gst_flags, 0);
gst_element_set_state (파이프 라인, GST_STATE_PLAYING);
나는 정확한 이유를 모른다.