ffmpeg本地图片(摄像头)推rtmp流
程序员文章站
2022-03-04 23:28:10
...
方法原理
此部分包括三部分:ffmpeg推流、web服务器(nginx)、videojs拉流/Vlc播放器。
ffmpeg
- ffmpeg加入编码器选项(libx264)
- ffmpeg编译程序时注意版本兼容问题以及链接库的顺序问题
nginx服务器搭建
- .安装gcc g++依赖库
sudo apt-get install build-essential
sudo apt-get install libtool - 安装pcre依赖库
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev - .安装zlib依赖库
sudo apt-get install zlib1g-dev - 安装SSL依赖库
sudo apt-get install openssl libssl-dev - 安装NGINX
#下载NGINX(到HOME目录)
wget http://nginx.org/download/nginx-1.13.10.tar.gz
#解压
tar -zxvf nginx-1.13.10.tar.gz
#下载RTMP(到HOME目录)
git clone https://github.com/arut/nginx-rtmp-module.git
#进入NGINX解压目录
cd nginx-1.13.10
#配置
./configure --prefix=/usr/local/nginx --add-module=~/nginx-rtmp-module --with-http_ssl_module
#编译
make
#安装
sudo make install
#打开nginx配置文件
cd /usr/local/nginx/conf/
sudo gedit nginx.conf
#下拉至文档末尾,添加RTMP服务
rtmp {
server {
listen 2018; #服务端口,避开重要端口即可
application live {
live on;
}
application hls_alic{
live on;
hls on;
hls_path /tmp/hls;
}
}
#不要关闭文档,回到http服务配置处,按以下样式对其修改,最后保存并退出
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/nginx/nginx-rtmp-module/;
}
location / {
root html;
index index.html index.htm;
}
error_page 404 /404.html
location = /50x.html {
root html;
}
}
}
#开启nginx服务
cd /usr/local/nginx/sbin
sudo ./nginx
#如要查看NGINX服务是否开启,请打开浏览器并输入localhost,如果看到nginx页面即为成功,或使用以下代码
ps -ef|grep nginx
videojs/vlc拉流
- vlc自行百度下载,打开网络串流即可
- videojs播放,关键html代码截图如下,利用插件flash播放
ffmpeg本地推流部分关键代码
//nginx-rtmp 直播服务器rtmp推流URL
char *outUrl = "rtmp://192.168.3.105:2019/live";
//注册所有的编解码器
avcodec_register_all();
//注册所有的封装器
av_register_all();
//注册所有网络协议
avformat_network_init();
VideoCapture cam;
Mat frame;
//像素格式转换上下文
SwsContext *vsc = NULL;
//输出的数据结构
AVFrame *yuv = NULL;
//编码器上下文
AVCodecContext *vc = NULL;
//rtmp flv 封装器
AVFormatContext *ic = NULL;
/// 1 使用opencv打开rtsp相机
cam.open(0); // 本地相机
if (!cam.isOpened())
{
cout<<"camera is not open<<endl;";
}
if (!cam.grab())
{
continue;
}
///yuv转换为rgb
if (!cam.retrieve(frame))
{
continue;
}
waitKey(20);
gettimeofday(&endtime1,NULL);
double timeuse1 = endtime1.tv_sec - starttime1.tv_sec + (endtime1.tv_usec - starttime1.tv_usec)/(double)1000000;
cout<<"cap:"<<timeuse1<<endl;
///rgb to yuv
//输入的数据结构
uint8_t *indata[AV_NUM_DATA_POINTERS] = { 0 };
indata[0] = frame.data;
int insize[AV_NUM_DATA_POINTERS] = { 0 };
//一行(宽)数据的字节数
insize[0] = frame.cols * frame.elemSize();
int h = sws_scale(vsc, indata, insize, 0, frame.rows, //源数据
yuv->data, yuv->linesize);
if (h <= 0)
{
continue;
}
///h264编码
yuv->pts = vpts;
vpts++;
int got_picture=0;
avcodec_encode_video2(vc,&pack,yuv,&got_picture);
if (ret != 0 || pack.size > 0)
{
cout << "*" << pack.size << flush;
}
else
{
cout<<"continue";
continue;
}
//推流
pack.pts = av_rescale_q(pack.pts, vc->time_base, vs->time_base);
pack.dts = av_rescale_q(pack.dts, vc->time_base, vs->time_base);
pack.duration = av_rescale_q(pack.duration, vc->time_base, vs->time_base);
ret = av_interleaved_write_frame(ic, &pack);
if (ret == 0)
{
cout << "#" << flush;
}
cout<<"okokokokok"<<endl;
上一篇: centos coreseek安装
下一篇: P2P网络概念的背景和基础认识