前言:
目前我们对“ubuntu播放音频c”大约比较关切,姐妹们都需要分析一些“ubuntu播放音频c”的相关文章。那么小编也在网络上网罗了一些有关“ubuntu播放音频c””的相关文章,希望你们能喜欢,我们一起来了解一下吧!功能简介:
使用QT+FFMPEG实现了RTSP视频流播放的基础操作,点击按钮后,将拉取指定地址的RTSP流,并在QT界面中通过Label显示
开发环境:系统环境:UbuntuQT:5.12.12FFmpeg:4.4(当前最新)完整工程:
参考代码:
FFMPEG官方示例:FFmpeg: decode_video.c
详细介绍:(一)添加库文件
新建一个QT工程,在pro添加lib目录和include目录的路径。
##ffmpegFFMPEG_LIB = /usr/local/ffmpeg/libFFMPEG_INCLUDE = /usr/local/ffmpeg/include 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 \(二)界面配置
在MainWindow.ui中,添加一个QPushButton和QLabel控件,并添加“转到槽”,添加on_pushButton_clicked()。
(三)Delay函数
#include <QTime>//以毫秒为单位设置延时void Delay(int msec){ QTime dieTime = QTime::currentTime().addMSecs(msec); while(QTime::currentTime() < dieTime){ QCoreApplication::processEvents(QEventLoop::AllEvents,100); }}
相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】
音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~
(四)FFmpeg视频解码
总体处理步骤有8步,如图所示
1.定义相关变量
AVFormatContext *pFormatCtx = NULL; AVCodecContext *pCodecCtx = NULL; const AVCodec *pCodec = NULL; AVFrame *pFrame,*pFrameRGB; AVPacket *packet; struct SwsContext *img_convert_ctx; unsigned char *out_buffer; int i,videoIndex; int ret; char errors[1024] = ""; //rtsp地址: char url[] = "rtsp://192.168.111.60:554/LiveMedia/ch1/Media1";
2.初始化相关模块
//初始化FFMPEG 调用了这个才能正常适用编码器和解码器 pFormatCtx = avformat_alloc_context(); //init FormatContext //初始化FFmpeg网络模块 avformat_network_init(); //init FFmpeg network
3.打开视频文件并获取视频信息
//open Media File ret = avformat_open_input(&pFormatCtx,url,NULL,NULL); if(ret != 0){ av_strerror(ret,errors,sizeof(errors)); cout <<"Failed to open video: ["<< ret << "]"<< errors << endl; exit(ret); } //Get audio information ret = avformat_find_stream_info(pFormatCtx,NULL); if(ret != 0){ av_strerror(ret,errors,sizeof(errors)); cout <<"Failed to get audio info: ["<< ret << "]"<< errors << endl; exit(ret); }
4.查找视频中的流信息
//循环查找视频中包含的流信息,直到找到视频类型的流 //便将其记录下来 videoIndex //这里我们现在只处理视频流 音频流先不管他 for (i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { videoIndex = i; } } //如果videoIndex为-1 说明没有找到视频流 if (videoIndex == -1) { printf("Didn't find a video stream.\n"); return; }
5.配置编码上下文,AVCodecContext内容
//配置编码上下文,AVCodecContext内容 //1.查找解码器 pCodec = avcodec_find_decoder(pFormatCtx->streams[videoIndex]->codecpar->codec_id); //2.初始化上下文 pCodecCtx = avcodec_alloc_context3(pCodec); //3.配置上下文相关参数 avcodec_parameters_to_context(pCodecCtx,pFormatCtx->streams[videoIndex]->codecpar); //4.打开解码器 ret = avcodec_open2(pCodecCtx, pCodec, NULL); if(ret != 0){ av_strerror(ret,errors,sizeof(errors)); cout <<"Failed to open Codec Context: ["<< ret << "]"<< errors << endl; exit(ret); }
6.建立视频帧,并对相关参数进行配置
//初始化视频帧 pFrame = av_frame_alloc(); pFrameRGB = av_frame_alloc(); //为out_buffer申请一段存储图像的内存空间 out_buffer = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB32,pCodecCtx->width,pCodecCtx->height,1)); //实现AVFrame中像素数据和Bitmap像素数据的关联 av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize, out_buffer, AV_PIX_FMT_RGB32,pCodecCtx->width, pCodecCtx->height,1); //为AVPacket申请内存 packet = (AVPacket *)av_malloc(sizeof(AVPacket)); //打印媒体信息 av_dump_format(pFormatCtx,0,url,0); //初始化一个SwsContext img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
7.通过while循环,处理每一个视频帧,并渲染到Label上
//读取帧数据,并通过av_read_frame的返回值确认是不是还有视频帧 while(av_read_frame(pFormatCtx,packet) >=0){ //判断视频帧 if(packet->stream_index == videoIndex){ //解码视频帧 ret = avcodec_send_packet(pCodecCtx, packet); ret = avcodec_receive_frame(pCodecCtx, pFrame); if(ret != 0){ av_strerror(ret,errors,sizeof(errors)); cout <<"Failed to decode video frame: ["<< ret << "]"<< errors << endl; } if (ret == 0) { //处理图像数据 sws_scale(img_convert_ctx, (const unsigned char* const*) pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); QImage img((uchar*)pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB32); ui->label->setPixmap(QPixmap::fromImage(img)); //释放前需要一个延时 Delay(1); } } //释放packet空间 av_packet_unref(packet); }
8.结束后释放资源
//close and release resource av_free(out_buffer); av_free(pFrameRGB); sws_freeContext(img_convert_ctx); avcodec_close(pCodecCtx); avcodec_free_context(&pCodecCtx); avformat_close_input(&pFormatCtx); exit(0);
原文 FFMPEG 播放 RTSP视频流
标签: #ubuntu播放音频c