Qt fmpeg保存裸流怎么实现
这篇文章主要介绍"Qt fmpeg保存裸流怎么实现",在日常操作中,相信很多人在Qt fmpeg保存裸流怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Qt fmpeg保存裸流怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、前言
最开始做的ffmpeg保存视频文件,就是直接保存的裸流数据,裸流数据一般是H264格式的数据,这种数据文件可以用部分播放器播放,由于不是标准的格式,很多播放器其实不支持的,需要安装对应的解码器才行。后面发现安装好K-Lite解码器后,连系统自带的播放器都可以正常播放H264视频流文件,而且如果同步保存了同名文件的aac音频文件放在同目录下的话,声音都能正常同步播放,可能这是播放器做的处理吧。
直接保存裸流基本上没有什么难度,大致流程就是先打开文件,然后在循环解码的地方直接将解码好的数据write到文件即可,如果采用的是定时存储的话,那就开个定时器,到了点就先关闭文件,然后重新打开新的名字的文件,这里要注意的是,rtmp视频流的话,需要添加pps sps等信息,所以在每帧写入文件前,要先用AVBitStreamFilter采用h364_mp4toannexb处理下才行。
二、功能特点
多线程实时播放视频流+本地视频+USB摄像头等。
支持windows+linux+mac,支持ffmpeg3和ffmpeg4,支持32位和64位。
多线程显示图像,不卡主界面。
自动重连网络摄像头。
可设置边框大小即偏移量和边框颜色。
可设置是否绘制OSD标签即标签文本或图片和标签位置。
可设置两种OSD位置和风格。
可设置是否保存到文件以及文件名。
可直接拖曳文件到ffmpegwidget控件播放。
支持h365视频流+rtmp等常见视频流。
可暂停播放和继续播放。
支持存储单个视频文件和定时存储视频文件。
自定义顶部悬浮条,发送单击信号通知,可设置是否启用。
可设置画面拉伸填充或者等比例填充。
可设置解码是速度优先、质量优先、均衡处理。
可对视频进行截图(原始图片)和截屏。
录像文件存储支持裸流和MP4文件。
支持qsv、dxva2、d3d11va等硬解码。
支持opengl绘制视频数据,极低CPU占用。
支持嵌入式linux,交叉编译即可。
三、效果图
四、核心代码
void FFmpegThread::initSave(){ if (!saveFile) { return; } //如果存储间隔大于0说明需要定时存储 if (saveInterval > 0) { QString dirName = QString("%1/%2").arg(savePath).arg(QDATE); newDir(dirName); fileName = QString("%1/%2_%3.mp4").arg(dirName).arg(fileFlag).arg(STRDATETIME); emit sig_startSave(); } if (saveMp4) { saveVideoMp4(fileName); } else { saveVideoH264(fileName); }}void FFmpegThread::startSave(){ timerSave->start(saveInterval * 1000);}void FFmpegThread::stopSave(){ //停止存储文件以及存储定时器 closeVideo(); if (timerSave->isActive()) { timerSave->stop(); }}void FFmpegThread::saveVideo(){ if (!saveFile) { return; } //重新设置文件名称 QString dirName = QString("%1/%2").arg(savePath).arg(QDATE); newDir(dirName); fileName = QString("%1/%2_%3.mp4").arg(dirName).arg(fileFlag).arg(STRDATETIME); if (saveMp4) { saveVideoMp4(fileName); } else { saveVideoH264(fileName); }}void FFmpegThread::closeVideo(){ if (!saveFile) { return; } if (saveMp4) { if (formatOut != NULL) { //写入结束标识 av_write_trailer(formatOut); avcodec_close(formatOut->streams[0]->codec); av_freep(&formatOut->streams[0]->codec); av_freep(&formatOut->streams[0]); avio_close(formatOut->pb); av_free(formatOut); initSaveOk = false; formatOut = NULL; } } else { if (fileVideo.isOpen()) { fileVideo.close(); } if (fileAudio.isOpen()) { fileAudio.close(); } }}void FFmpegThread::saveVideoH264(const QString &fileName){ QMutexLocker locker(&mutex); closeVideo(); if (videoStreamIndex >= 0) { fileVideo.setFileName(fileName); fileVideo.open(QFile::WriteOnly); } //存在音频文件则同时保存音频文件 if (audioStreamIndex >= 0 && playAudio) { QString audioName = fileName; audioName = audioName.replace(QFileInfo(audioName).suffix(), "aac"); fileAudio.setFileName(audioName); fileAudio.open(QFile::WriteOnly); }}
到此,关于"Qt fmpeg保存裸流怎么实现"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!