Afternoon,
I am trying to get gstreamer to simply loop a .wav file to a filesink. for testing purposes the filesink will be a .wav file but actually want to write raw audio to a fifo. I tried to combine these two concepts: https://tristanswork.blogspot.com/2010/10/looping-playback-with-gstreamer.html https://gstreamer.freedesktop.org/documentation/tutorials/playback/custom-playbin-sinks.html?gi-language=c and the pipeline does run but the audio in the .wav is corrupted. I then tried adding a decodebin with audio/x-raw caps but now there is no audio written out. So in essence I think it should be simple, I just need the playbin to playout raw audio or to somehow convert whatever playbin outputs to raw-audio. any help would be greatly appreciated. gboolean bus_callback(GstBus* bus, GstMessage* msg, gpointer data) { GstElement* play = GST_ELEMENT(data); switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: /* restart playback if at end */ if (!gst_element_seek(play, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_print("Seek failed!\n"); } break; default: break; } return TRUE; } void Playfile() { GMainLoop* loop; GstElement* play; GstBus* bus; /* init GStreamer */ gst_init(NULL, NULL); loop = g_main_loop_new(NULL, FALSE); /* set up */ play = gst_element_factory_make("playbin", "play"); g_object_set(G_OBJECT(play), "uri", "file:/tmp/tone_sink_1.wav", NULL); GstElement *audio_sink{nullptr}, *wav_convert{nullptr}, *wavenc{nullptr}; GstElement* decodebin{nullptr}; decodebin = gst_element_factory_make("decodebin", NULL); audio_sink = gst_element_factory_make("filesink", NULL); wav_convert = gst_element_factory_make("audioconvert", NULL); wavenc = gst_element_factory_make("wavenc", NULL); if (!decodebin || !audio_sink || !wav_convert || !wavenc) { throw std::runtime_error("sink elements could be created."); } g_object_set(audio_sink, "location", "tester.wav", NULL); GstCaps* in_filtercaps = gst_caps_new_simple("audio/x-raw", "format", G_TYPE_STRING, "F32LE", "rate", G_TYPE_INT, 48000, NULL); g_object_set(decodebin, "caps", in_filtercaps, NULL); gst_caps_unref(in_filtercaps); GstElement* bin = gst_bin_new("audio_sink_bin"); gst_bin_add_many(GST_BIN(bin), decodebin, wav_convert, wavenc, audio_sink, NULL); gst_element_link_many(decodebin, wav_convert, wavenc, audio_sink, NULL); GstPad *pad, *ghost_pad; pad = gst_element_get_static_pad(decodebin, "sink"); ghost_pad = gst_ghost_pad_new("sink", pad); gst_pad_set_active(ghost_pad, TRUE); gst_element_add_pad(bin, ghost_pad); gst_object_unref(pad); g_object_set(GST_OBJECT(play), "audio-sink", bin, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(play)); gst_bus_add_watch(bus, bus_callback, play); gst_object_unref(bus); gst_element_set_state(play, GST_STATE_PLAYING); std::string name = "test"; GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(play), GST_DEBUG_GRAPH_SHOW_ALL, name.c_str()); /* now run */ g_main_loop_run(loop); /* also clean up */ gst_element_set_state(play, GST_STATE_NULL); gst_object_unref(GST_OBJECT(play)); } -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Update,
I now get valid audio out, but the data written to file is never longer than the input file. But if I switch the sink from file sink to autoaudiosink then the audio out my speaker does loop. I'm not sure if the EOS signal is resetting the filesink file? gboolean bus_callback(GstBus* bus, GstMessage* msg, gpointer data) { GstElement* play = GST_ELEMENT(data); switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: /* restart playback if at end */ //std::cout << "Replay" << std::endl; if (!gst_element_seek(play, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_print("Seek failed!\n"); } break; default: break; } return TRUE; } void Playfile() { GMainLoop* loop; GstElement* pipeline; GstBus* bus; GstMessage* msg; /* init GStreamer */ gst_init(NULL, NULL); loop = g_main_loop_new(NULL, FALSE); /* set up */ pipeline = gst_element_factory_make("playbin", "play"); g_object_set(G_OBJECT(pipeline), "uri", "file:///home/nick/devel/tnm/analysis/modules/gcc_release_build/ssf_tests/bin/8ch_24bit_1s.wav", NULL); //------------- GstElement *bin, *convert, *sink, *filter; GstCaps* caps; GstPad *pad, *ghost_pad; convert = gst_element_factory_make("audioconvert", "convert"); //sink = gst_element_factory_make("filesink", "audio_sink"); sink = gst_element_factory_make("autoaudiosink", "audio_sink"); filter = gst_element_factory_make("capsfilter", "capsfilter"); if (!convert || !sink) { g_printerr("Not all elements could be created.\n"); } caps = gst_caps_new_simple("audio/x-raw", "format", G_TYPE_STRING, "F32LE", "rate", G_TYPE_INT, 48000, "channel-mask", GST_TYPE_BITMASK, 0xff, NULL); g_object_set(G_OBJECT(filter), "caps", caps, NULL); gst_caps_unref(caps); //g_object_set(sink, "location", "stinker", NULL); /* Create the sink bin, add the elements and link them */ bin = gst_bin_new("audio_sink_bin"); gst_bin_add_many(GST_BIN(bin), filter, convert, sink, NULL); gst_element_link_many(filter, convert, sink, NULL); pad = gst_element_get_static_pad(filter, "sink"); ghost_pad = gst_ghost_pad_new("sink", pad); gst_pad_set_active(ghost_pad, TRUE); gst_element_add_pad(bin, ghost_pad); gst_object_unref(pad); /* Set playbin's audio sink to be our sink bin */ g_object_set(GST_OBJECT(pipeline), "audio-sink", bin, NULL); //------------- gst_element_set_state(pipeline, GST_STATE_PLAYING); // gst_element_set_state(pipeline, GST_STATE_PLAYING); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); gst_bus_add_watch(bus, bus_callback, pipeline); gst_object_unref(bus); //msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, static_cast<GstMessageType>(GST_MESSAGE_ERROR)); Thread_wrapper mainloop_thread; mainloop_thread.Start( "mainloop_thread", [&]() { g_main_loop_run(loop); return false; }); /* now run */ for (int i = 0; i < 30; ++i) { gst_element_set_state(sink, GST_STATE_PLAYING); sleep(1); std::string name = "test"; GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, name.c_str()); std::cout << i << " seconds" << std::endl; } g_main_loop_quit(loop); mainloop_thread.Stop(); /* also clean up */ /* Free resources */ // if (msg != NULL) // gst_message_unref(msg); gst_object_unref(bus); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); } -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |