使用libvlc sdk库开发一个简单的推流器,参照自雷博士的博客
https://blog.csdn.net/leixiaohua1020/article/details/42363701
不过直接使用貌似有些问题,对着 vlc的源码改了下。
环境:ubuntu 18.04, vlc-linux 源码,vlc 3.0.6 已经对源码进行 configure make,并且可以执行
#./cvlc bydtest.mp4 -vvv --loop --sout "#rtp{sdp=rtsp://192.168.43.129:10086/stream}”
进行流输出。
下面在源码目录下 /bin/vlc.c中替换掉源来得 main函数,添加上以下代码,即一个推流的功能
int main(int argc, const char* argv[])
{
/* The so-called POSIX-compliant MacOS X reportedly processes SIGPIPE even
* if it is blocked in all thread.
* Note: this is NOT an excuse for not protecting against SIGPIPE. If
* LibVLC runs outside of VLC, we cannot rely on this code snippet. */
signal (SIGPIPE, SIG_IGN);
/* Restore SIGCHLD in case our parent process ignores it. */
signal (SIGCHLD, SIG_DFL);
#ifndef NDEBUG
/* Activate malloc checking routines to detect heap corruptions. */
setenv ("MALLOC_CHECK_", "2", 1);
/* Disable the ugly Gnome crash dialog so that we properly segfault */
setenv ("GNOME_DISABLE_CRASH_DIALOG", "1", 1);
#endif
#ifdef TOP_BUILDDIR
setenv ("VLC_PLUGIN_PATH", TOP_BUILDDIR"/modules", 1);
setenv ("VLC_DATA_PATH", TOP_SRCDIR"/share", 1);
#endif
/* Clear the X.Org startup notification ID. Otherwise the UI might try to
* change the environment while the process is multi-threaded. That could
* crash. Screw you X.Org. Next time write a thread-safe specification. */
unsetenv ("DESKTOP_STARTUP_ID");
printf("hello world %d %s \n",__LINE__,__FUNCTION__);
libvlc_instance_t *vlc; const char *url;
//Send File //Transcode it. Video codec use x264. Audio codec use mpga.
//Mux it to mpegts format.
//And stream it to udp://233.233.233.233:6666
/*
const char *sout = "#transcode{vcodec=h264,fps=25,venc=x264{preset=ultrafast,"\
"profile=main,tune=zerolatency},vb=512,scale=0.5," \
"acodec=mpa,aenc=ffmpeg,ab=64,channels=2}" \
":standard{access=udp,mux=ts,dst=233.233.233.233:6666}";
*/
//Send and playing at same time
#if 0
const char *sout = "#transcode{vcodec=h264,fps=25,venc=x264{preset=ultrafast," \
"profile=baseline,tune=zerolatency},vb=512," \
"acodec=mpga,ab=64,channels=2}" \
":duplicate{dst=display,dst=standard{access=udp,mux=ts,dst=233.233.233.233:6666}}";
#else
//const char *sout = "#transcode{vcodec=h264,acodec=mpga,ab=128,\
//channels=2,samplerate=44100,scodec=none}:rtp{sdp=rtsp://:8554/play} :no-sout-all :sout-keep";
#endif
const char *sout = "#rtp{sdp=rtsp://192.168.43.129:10086/stream}";
const char *media_name = "Lei's test";
url = "./bydtest.mp4";
vlc = libvlc_new(0, NULL);
if(vlc == NULL)
{
printf("wang erro %d %s \n",__LINE__,__FUNCTION__);
return -1;
}
libvlc_vlm_add_broadcast(vlc, media_name, url, sout, 0, NULL, true, true);
libvlc_vlm_play_media(vlc, media_name);
//play 30s
//usleep(10000*100*30);
while(1); //主线程不能退出,不然子线程也挂掉,播放不了了
libvlc_vlm_stop_media(vlc, media_name);
libvlc_vlm_release(vlc);
return 0;
}
主要是linux源码编译的环境中,在调用libvlc_new之前要设置好 setenv ("VLC_PLUGIN_PATH", TOP_BUILDDIR"/modules", 1);插件的目录,不然libvlc_new 失败,返回一个NULL,后续的直接报段错误。
然后推流的参数,是先使用源码编译出来的 命令行模式的vlc #./cvlc bydtest.mp4 -vvv --loop --sout "#rtp{sdp=rtsp://192.168.43.129:10086/stream}” 可以推流,就把这个写到代码中去了,这样播放的时候用vlc播放器打开网络串流:rtsp://192.168.43.129:10086/stream ,最后,要让主线程挂着。看雷博士原文:https://blog.csdn.net/leixiaohua1020/article/details/42363701