一、獲取并寫入H264碼流數(shù)據的步驟:
二、實現(xiàn)效果:
用eseye_u.exe打開H264文件并播放
本文福利, 免費領取C++音視頻學習資料包、技術視頻,內容包括(音視頻開發(fā),面試題,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓見下面↓↓文章底部點擊免費領取↓↓?文章來源地址http://www.zghlxwxcb.cn/news/detail-416022.html
三、核心代碼:?
/*1、注冊*/
av_register_all();//
//參數(shù):1雙指針定義一顆星*,2要打開流的路徑(文件名)
//AVFormatContext保存視頻(視頻流)相關信息的結構體
AVFormatContext * formatContent = avformat_alloc_context();
char * filename="Warcraft3_End.avi";
/*2、打開視頻文件*/
int res = avformat_open_input(&formatContent,filename,nullptr,nullptr);
if(res!=0)
{
qDebug()<<"打開視頻失敗";
return ;
}
/*3、打開成功之后相關的結構體信息放在了formatContent里面,進行獲取視頻文件信息*/
//3.1先看有沒有視頻流信息(avformat_find_stream_info),進行判斷的原因是有可能打開普通文件
res = avformat_find_stream_info(formatContent,nullptr);
if(res<0)
{
qDebug()<<"打開流媒體信息";
return ;
}
//AVFormatContext(含有解碼器的id,去streams的流數(shù)組里面找視頻流)->AVStream->AVCodecContext
//->codec(有解碼器的AVCodec)->AVCodec(含有編解碼器的id、類型)
//AVCodecContext 保存視頻音頻編解碼相關的信息
int videoType = -1;
//3.2一個視頻中有多股碼流(用循環(huán)),存在AVFormatContext的streams數(shù)組中
for(int i=0;i<formatContent->nb_streams;i++)
{
if(formatContent->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)//streams->有AVStream結構體,AVStream->codec
{
//找到視頻流(只有一個)
videoType = i;//標識視頻流這個類型
break;
}
}
if(videoType == -1)
{
qDebug()<<"沒有找到視頻流相關信息";
return;
}
//對視頻的編碼只有編碼器是不夠的還要有寬高格式等
//3.3編碼器對應的上下文對象結構體,存儲編碼器以及寬高格式等
AVCodecContext *codec = formatContent->streams[videoType]->codec;
/*4、有視頻流,則查找對應視頻流的解碼器*/
AVCodec *decoder = avcodec_find_decoder(codec->codec_id);//需要解碼器的id
if(decoder ==nullptr)
{
qDebug()<<"沒有找到對應的解碼器";
return;
}
/*5、找到解碼器后打開解碼器*/
//參數(shù):1.初始化的上下文對象 2.打開的解碼器 3.類似目錄的東西(沒有)
res = avcodec_open2(codec,decoder,nullptr);
if(res!=0)
{
qDebug()<<"解碼器打開失敗";
return;
}
/*6、獲取到的每一幀碼流(視頻流)數(shù)據寫到文件中(FILE結構體)*/
/*6.1*/
FILE *fp = fopen("saveH264.h264","wb+");
AVPacket *pkt=nullptr;//pkt這時沒有指向,要我們給他分配內存空間,希望把讀出來的數(shù)據放到這塊內存去
pkt = (AVPacket *)malloc(sizeof(AVPacket));
//碼流數(shù)據是存到buffer里面,也需要我們動態(tài)開空間(AVBufferRef *buf;)
//開空間不知道一幀的碼流數(shù)據是多少?其實編解碼器告訴了寬高,以此可以計算出給碼流數(shù)據開多大空間
int bufSize = codec->width*codec->height;//計算一幀(圖)數(shù)據的大小
av_new_packet(pkt,bufSize);
//一幀一幀讀[av_read_frame](循環(huán))
//參數(shù):1最初保存信息的結構體 2包
while(av_read_frame(formatContent,pkt) == 0)//成功讀到了數(shù)據
{
/*6.2AVPacket->AVStream,要判斷讀到的每一幀的碼流數(shù)據是不是視頻流*/
if(pkt->stream_index == videoType)
{
//是視頻流則寫到文件中
fwrite(pkt->data,pkt->size,1,fp);//每次寫一個結構體
}
//每次都存在同一塊內存空間里,要清空上一次的操作
av_packet_unref(pkt);//不是free
}
qDebug()<<"保存碼流數(shù)據成功";
fclose(fp);
main中創(chuàng)建對象即可測試:fdecode code;
如果你對音視頻開發(fā)感興趣,覺得文章對您有幫助,別忘了點贊、收藏哦!或者對本文的一些闡述有自己的看法,有任何問題,歡迎在下方評論區(qū)與我討論!文章來源:http://www.zghlxwxcb.cn/news/detail-416022.html
本文福利, 免費領取C++音視頻學習資料包、技術視頻,內容包括(音視頻開發(fā),面試題,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓見下面↓↓文章底部點擊免費領取↓↓?
到了這里,關于Qt基于FFmpeg解碼本地視頻生成H264文件并播放的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!