Linux怎么读取内存的视频流,QT+Linux+FFmpeg+C/C++实现RTSP流存储为MP4视频文件

不过上面是在windows下的开发,直接移植到Linux环境下会编译出现问题。

下面是我将其移植到Linux下并编译通过录制成功、播放成功的代码。

(1)编译FFmpeg

下载下来先,我下的是ffmpeg-3.0.12.tar.xz

执行configure-make-make install三部曲

>./configure --enable-shared --prefix=/home/ffmpeg

>make

>make install

将include和lib两个文件夹拷贝到QT工程目录下的ffmpeg文件夹下

(2)QT工程引入FFmpeg进行开发

.pro文件增加如下

INCLUDEPATH += ./ffmpeg/include \

LIBS += ./ffmpeg/lib/libavcodec.so \

./ffmpeg/lib/libavdevice.so \

./ffmpeg/lib/libavfilter.so \

./ffmpeg/lib/libavformat.so \

./ffmpeg/lib/libavutil.so \

./ffmpeg/lib/libswresample.so \

./ffmpeg/lib/libswscale.so \

.h文件引入开发所需头文件,然后声明函数

#include#include

extern "C"{

#include"libavcodec/avcodec.h"#include"libavformat/avformat.h"#include"libswscale/swscale.h"#include"libavdevice/avdevice.h"}class recordVideo:publicQObject

{voidrecordVideoExec();static void* ReadingThrd(void * pParam);

};

.cpp编写实现代码

voidrecordVideo::recordVideoExec()

{

pthread_t thread;if(0 == pthread_create(&thread, NULL,ReadingThrd, NULL))

{

printf("thread create succ, main thread id is %u\n",(unsigned)pthread_self());

}

}static AVFormatContext *i_fmt_ctx;static AVStream *i_video_stream;static AVFormatContext *o_fmt_ctx;static AVStream *o_video_stream;static bool bStop = false;static int frame_nums = 0;void *recordVideo::ReadingThrd(void *pParam)

{

avcodec_register_all();

av_register_all();

avformat_network_init();/*should set to NULL so that avformat_open_input() allocate a new one*/i_fmt_ctx=NULL;//这是我用ONVIF协议得到的摄像头RTSP流媒体地址

char rtspUrl[] = "rtsp://10.19.17.23:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1";const char *filename = "2.mp4";if (avformat_open_input(&i_fmt_ctx, rtspUrl, NULL, NULL)!=0)

{

fprintf(stderr,"= could not open input file\n");returnnullptr;

}if (avformat_find_stream_info(i_fmt_ctx, NULL)<0)

{

fprintf(stderr,"= could not find stream info\n");returnnullptr;

}//av_dump_format(i_fmt_ctx, 0, argv[1], 0);

/*find first video stream*/

for (unsigned i=0; inb_streams; i++)

{if (i_fmt_ctx->streams[i]->codec->codec_type ==AVMEDIA_TYPE_VIDEO)

{

i_video_stream= i_fmt_ctx->streams[i];break;

}

}if (i_video_stream ==NULL)

{

fprintf(stderr,"= didn't find any video stream\n");returnnullptr;

}

avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename);/** since all input files are supposed to be identical (framerate, dimension, color format, ...)

* we can safely set output codec values from first input file*/o_video_stream=avformat_new_stream(o_fmt_ctx, NULL);

{

AVCodecContext*c;

c= o_video_stream->codec;

c->bit_rate = 400000;

c->codec_id = i_video_stream->codec->codec_id;

c->codec_type = i_video_stream->codec->codec_type;

c->time_base.num = i_video_stream->time_base.num;

c->time_base.den = i_video_stream->time_base.den;

fprintf(stderr,"= time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den);

c->width = i_video_stream->codec->width;

c->height = i_video_stream->codec->height;

c->pix_fmt = i_video_stream->codec->pix_fmt;

printf("= width: %d height: %d pix_fmt: %d\n", c->width, c->height, c->pix_fmt);

c->flags = i_video_stream->codec->flags;

c->flags |=CODEC_FLAG_GLOBAL_HEADER;

c->me_range = i_video_stream->codec->me_range;

c->max_qdiff = i_video_stream->codec->max_qdiff;

c->qmin = i_video_stream->codec->qmin;

c->qmax = i_video_stream->codec->qmax;

c->qcompress = i_video_stream->codec->qcompress;

}

avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE);

avformat_write_header(o_fmt_ctx, NULL);int last_pts = 0;int last_dts = 0;

int64_t pts, dts;while(!bStop)

{//printf("------------------------------------------------------\n");

AVPacket i_pkt;

av_init_packet(&i_pkt);

i_pkt.size= 0;

i_pkt.data=NULL;if (av_read_frame(i_fmt_ctx, &i_pkt) <0)break;/** pts and dts should increase monotonically

* pts should be >= dts*/i_pkt.flags|=AV_PKT_FLAG_KEY;

pts=i_pkt.pts;

i_pkt.pts+=last_pts;

dts=i_pkt.dts;

i_pkt.dts+=last_dts;

i_pkt.stream_index= 0;//printf("%lld %lld\n", i_pkt.pts, i_pkt.dts);

static int num = 1;

printf("= frame %d\n", num++);

av_interleaved_write_frame(o_fmt_ctx,&i_pkt);//av_free_packet(&i_pkt);//av_init_packet(&i_pkt);//Sleep(10);//sleep(1);//linux下usleep()可以接受毫秒,要包含头文件#include

if(frame_nums > 2000)

{

bStop= true;

}

frame_nums++;

usleep(10);

}

last_dts+=dts;

last_pts+=pts;

avformat_close_input(&i_fmt_ctx);

av_write_trailer(o_fmt_ctx);

avcodec_close(o_fmt_ctx->streams[0]->codec);

av_freep(&o_fmt_ctx->streams[0]->codec);

av_freep(&o_fmt_ctx->streams[0]);

avio_close(o_fmt_ctx->pb);

av_free(o_fmt_ctx);

}

(3)然后在main函数之中创建类对象,通过类对象调用成员函数 recordVideoExec()即可

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值