A problem about lamemp3enc: how to push audio to rtmp server
han_ge_2005
han_ge_2005 at 163.com
Tue Sep 25 05:29:29 UTC 2018
Hi,All
I am pushing my PC camera and microphone to rtmp server by using lamemp3enc element. Currently,it can only push video h264 to rtmp server,but the time-delay is over 5 seconds,how to reduce it . After I add audio code into the project, VLC player failed to pull video/audio stream . Could you help me find the bug ? Code as following.
Thanks a lot!
#include <gst/gst.h>
typedef struct _CustomData {
GstElement *pipeline;
GstElement *vsource;
GstElement *vconvert;
GstElement *x264enc;
GstElement *h264parse;
GstElement *vcapsfilter;
GstElement *vsink;
GstElement *asource;
GstElement *aconvert;
GstElement *amp3enc;
GstElement *acapfilter;
GstElement *ampegaudiopaser;
GstElement *asink;
GstElement *vqueue;
GstElement *aqueue;
GstElement *video_enc_queue;
GstElement *audio_enc_queue;
GstElement *flvmuxer;
GstElement *rtmpsink;
} CustomData;
int main(int argc, char *argv[]) {
CustomData data;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
gboolean terminate = FALSE;
/* Initialize GStreamer */
//gst_init (&argc, &argv);
gst_init(NULL, NULL);
/* Create the elements */
//"video/x-raw, width=(int)160, height=(int)120, framerate=(fraction)30/1, format=I420, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive"
data.vsource = gst_element_factory_make("v4l2src", "camera-source");//autovideosrc v4l2src
data.vconvert = gst_element_factory_make("videoconvert", "convert");
data.vsink = gst_element_factory_make("ximagesink", "camera-sink");
data.vqueue = gst_element_factory_make("queue", "camera-queue");
data.x264enc = gst_element_factory_make("x264enc", "x264-encoder");
data.vcapsfilter = gst_element_factory_make("capsfilter", "video-filter");
data.h264parse = gst_element_factory_make("h264parse", "mux-video-parser");;
data.asource = gst_element_factory_make("alsasrc", "audio-alsa-source");
data.aconvert = gst_element_factory_make("audioconvert", "audio-converter");
data.amp3enc = gst_element_factory_make("lamemp3enc", "mp3-encode");
data.acapfilter = gst_element_factory_make("capsfilter", "audio-capsfilter");
data.asink = gst_element_factory_make("filesink", "file-sink");
data.aqueue = gst_element_factory_make("queue", "audio-queue");
data.ampegaudiopaser = gst_element_factory_make("mpegaudioparse", "audio-paser");
data.flvmuxer = gst_element_factory_make("flvmux", "mux-flvmux");
data.rtmpsink = gst_element_factory_make("rtmpsink", "rtmp-sink");
data.video_enc_queue = gst_element_factory_make("queue", "video_enc_queue");
data.audio_enc_queue = gst_element_factory_make("queue", "audio_enc_queue");
g_object_set(G_OBJECT(data.rtmpsink), "location", "rtmp://localhost:1935/live/movie", NULL);
g_object_set(G_OBJECT(data.flvmuxer), "streamable", true, NULL);
/* Create the empty pipeline */
data.pipeline = gst_pipeline_new("push-pipeline");
if (!data.pipeline
|| !data.vsource || !data.vconvert || !data.vqueue || !data.x264enc || !data.vcapsfilter || !data.vsink
|| !data.asource || !data.aconvert || !data.amp3enc || !data.acapfilter || !data.asink || !data.aqueue) {
g_printerr("Not all elements could be created.\n");
return -1;
}
gst_bin_add_many(GST_BIN(data.pipeline), data.asource, data.aqueue, data.aconvert, data.amp3enc, data.acapfilter,
data.ampegaudiopaser, data.audio_enc_queue, NULL);
gst_bin_add_many(GST_BIN(data.pipeline), data.vsource, data.vqueue, data.vconvert, data.x264enc, data.vcapsfilter,
data.h264parse, data.video_enc_queue, NULL);
gst_bin_add_many(GST_BIN(data.pipeline), data.rtmpsink, data.flvmuxer, NULL);
//"video/x-h264, width=(int)640, height=(int)480, framerate=(fraction)30/1, stream-format=avc, alignment=au, profile=main"
GstCaps *filtercaps = gst_caps_new_simple("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream",//avc,byte-stream
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 240,
"framerate", GST_TYPE_FRACTION, 30, 1,
"alignment", G_TYPE_STRING, "au",
"profile", G_TYPE_STRING, "main",
NULL);
g_object_set(G_OBJECT (data.vcapsfilter), "caps", filtercaps, NULL);
bool v1 = gst_element_link(data.vsource, data.vconvert);
if (!gst_element_link(data.vconvert, data.vqueue)) {
g_printerr("Elements could not be linked.\n");
gst_object_unref(data.pipeline);
return -1;
}
if (!gst_element_link(data.vqueue, data.x264enc)) {
g_printerr("Elements could not be linked.\n");
gst_object_unref(data.pipeline);
return -1;
}
if (!gst_element_link(data.x264enc, data.vcapsfilter)) {
g_printerr("Elements could not be linked.\n");
gst_object_unref(data.pipeline);
return -1;
}
if (!gst_element_link(data.vcapsfilter, data.h264parse)) {
g_printerr("Elements could not be linked.\n");
gst_object_unref(data.pipeline);
return -1;
}
if (!gst_element_link(data.h264parse, data.video_enc_queue)) {
g_printerr("Elements could not be linked.\n");
gst_object_unref(data.pipeline);
return -1;
}
//"audio/mpeg, mpegversion=1, layer=3, rate=(int)11025, channels=(int)2"
GstCaps *fcaps = gst_caps_new_simple("audio/mpeg",
"stream-format", G_TYPE_STRING, "byte-stream",
"mpegversion", G_TYPE_INT, 1,
"layer", G_TYPE_INT, 3,
"rate", G_TYPE_INT, 11025,//44100
"channels", G_TYPE_INT, 2,
NULL);
g_object_set(G_OBJECT(data.acapfilter), "caps", fcaps, NULL);
//g_object_set(G_OBJECT(data.asink), "location", "/home/greg/pre-push1.mp3", NULL);
bool a0 = gst_element_link(data.asource, data.aqueue);
bool a1 = gst_element_link(data.aqueue, data.aconvert);
bool a2 = gst_element_link(data.aconvert, data.amp3enc);
bool a3 = gst_element_link(data.amp3enc, data.acapfilter);
bool aa = gst_element_link(data.acapfilter, data.ampegaudiopaser);
bool xz = gst_element_link(data.ampegaudiopaser, data.audio_enc_queue);
bool c1 = gst_element_link(data.audio_enc_queue, data.flvmuxer);
bool c2 = gst_element_link(data.video_enc_queue, data.flvmuxer);
bool c3 = gst_element_link(data.flvmuxer, data.rtmpsink);
/* Set device=/dev/video0 */
g_object_set(data.vsource, "device", "/dev/video0", NULL);
// g_object_set(G_OBJECT(data.amp3enc) , "target" , 1 , NULL) ;
// g_object_set(G_OBJECT(data.amp3enc) , "cbr" , true , NULL) ; // CBR
// g_object_set(G_OBJECT(data.amp3enc) , "bitrate" , 64 , NULL) ; // CBR
ret = gst_element_set_state(data.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(data.pipeline);
return -1;
}
/* Listen to the bus */
bus = gst_element_get_bus(data.pipeline);
do {
msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
(GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR |
GST_MESSAGE_EOS));
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug_info);
g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error(&err);
g_free(debug_info);
terminate = TRUE;
break;
case GST_MESSAGE_EOS:
g_print("End-Of-Stream reached.\n");
terminate = TRUE;
break;
case GST_MESSAGE_STATE_CHANGED:
/* We are only interested in state-changed messages from the pipeline */
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data.pipeline)) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
g_print("Pipeline state changed from %s to %s:\n",
gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));
}
break;
default:
/* We should not reach here */
g_printerr("Unexpected message received.\n");
break;
}
gst_message_unref(msg);
}
} while (!terminate);
/* Free resources */
gst_object_unref(bus);
gst_element_set_state(data.pipeline, GST_STATE_NULL);
gst_object_unref(data.pipeline);
return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20180925/b59e1e57/attachment-0001.html>
More information about the gstreamer-devel
mailing list