使用libavcodec将mp3音频文件解码为pcm音频采样数据【[mp3float @ 0x561c1ec49940] Header missing】 天天信息
一.打开和关闭输入文件和输出文件
想要解决上面提到的问题,我们需要对mp3文件的格式有个大致了解,为了方便讲解,我这里画了个示意图:
(资料图片)
ID3V2 | 包含了作者,作曲,专辑等信息,长度不固定,扩展了 ID3V1 的信息量。 |
Frame | 一系列的帧,个数由文件大小和帧长决定 |
ID3V1 | 包含了作者,作曲,专辑等信息,长度为 128BYTE |
由于av_parser_parse2()这个方法的输入必须是只包含音频编码数据的“裸流”,所以,我们在读取mp3文件的时候,必须跳过ID3V2标签部分,从Frame开始。所以,我们就必须知道ID3V2标签的总长度。下面,我画了个ID3V2标签头的示意图,方便讲解。
File ID(3) | Version(2) | Flags(1) | Size(4) |
ID3V2标签头固定为10byte,其中,Size部分的值是指除ID3V2标签头之外数据的总长度。需要注意的是,在实际计算长度的时候,这4个字节的最高位需要舍弃,也就是说,只用到了28bit,即:0xxxxxxx0xxxxxxx0xxxxxxx0xxxxxxx
#define AUDIO_INBUF_SIZE 20480#define AUDIO_REFILL_THRESH 4096static FILE* input_file= nullptr;static FILE* output_file= nullptr;static const AVCodec* codec= nullptr;static AVCodecContext* codec_ctx= nullptr;static AVPacket* pkt= nullptr;static AVFrame* frame= nullptr;static AVCodecParserContext* parser= nullptr;static enum AVCodecID audio_codec_id;void close_input_output_files(){ if(input_file!= nullptr){ fclose(input_file); input_file= nullptr; } if(output_file!= nullptr){ fclose(output_file); output_file= nullptr; }}int32_t open_input_output_files(const char* input_name,const char* output_name){ if(strlen(input_name)==0||strlen(output_name)==0){ cout<<"Error:empty input or output file name."<二.音频解码器的初始化以及销毁
int32_t init_audio_decoder(const char* audio_codec){ if(strcasecmp(audio_codec,"MP3")==0){ audio_codec_id=AV_CODEC_ID_MP3; cout<<"Select codec id:MP3"<id); if(!parser){ cerr<<"Error:could not init parser."< 三.解码循环体
解码循环体至少需要实现以下三个功能:
1.从输入源中循环获取码流包
2.将当前帧传入解码器,获取输出的音频采样数据
3.输出解码获取的音频采样数据到输出文件
从输入源中读取音频数据到缓存:
int32_t read_data_to_buf(uint8_t* buf,int32_t size,int32_t& out_size){ int32_t read_size=fread(buf,1,size,input_file); if(read_size==0){ cerr<<"Error:read_data_to_buf failed."<解码循环体:
int32_t end_of_input_file(){ return feof(input_file);}static int32_t decode_packet(bool flushing){ int32_t result=0; result= avcodec_send_packet(codec_ctx,flushing? nullptr:pkt); if(result<0){ cerr<<"Error:avcodec_send_packet failed,result:"<=0){ result= avcodec_receive_frame(codec_ctx,frame); if(result==AVERROR(EAGAIN)||result==AVERROR_EOF){ return 1; } else if(result<0){ cerr<<"Error:avcodec_receive_frame failed."< nb_samples:"<<frame->nb_samples<<",frame->channels:"<<frame->channels< 0){ result=av_parser_parse2(parser,codec_ctx,&pkt->data,&pkt->size,data,data_size,AV_NOPTS_VALUE,AV_NOPTS_VALUE,0); if(result<0){ cerr<<"Error:av_parser_parse2 failed."< size){ cout<<"Parsed packet size:"< size< 0) data_size += len; } } } decode_packet(true); return 0;} 输出解码的音频采样数据:
int32_t write_samples_to_pcm(AVFrame* frame,AVCodecContext* codec_ctx){ int data_size= av_get_bytes_per_sample(codec_ctx->sample_fmt); if(data_size<0){ cerr<<"Error:failed to calculate data size."<channels;ch++){ fwrite(frame->data[ch]+i*data_size,1,data_size,output_file); } } return 0;} 最终,main函数的实现如下:
int main(){ const char* input_file_name="../input.mp3"; const char* output_file_name="../output.pcm"; const char* codec_name="MP3"; int32_t result= open_input_output_files(input_file_name,output_file_name); if(result<0){ return result; } result=init_audio_decoder(codec_name); if(result<0){ return result; } result=audio_decoding(); if(result<0){ return result; } destroy_audio_decoder(); close_input_output_files(); return 0;}解码完成后,可以使用ffplay播放output.pcm文件:
ffplay -ar 44100 -ar 2 -f f32le -i output.pcm
关键词:
下一篇:最后一页
- 广州科技活动周进入预热 明日正式启动300多场主题活动接踵而来
- 深化重点领域信用建设 广州正式出台新型监管机制实施方案
- 女童不慎掉入20米深井 18岁小姨三次下井成功营救
- 西安3个区域12月28日起每日开展全员核酸 官方提倡民众居家健身
- 浙江乐清一核酸检测结果异常人员 复采复检为阴性
- 浙江本轮疫情报告确诊病例490例 提倡“双节”非必要不出省
- 西安警方通报6起涉疫违法案件
- 西安新一轮核酸筛查日检测能力达160万管
- 西安市累计报告本土确诊病例811例
- 重庆曝光4起违反中央八项规定精神典型问题 警示党员干部清新过节
-
我的世界漏斗怎么做新手_我的世界漏斗怎么做 每日聚焦
1、漏斗需要用五个铁锭加一个箱子来合成漏斗这款道具,旨在收集掉落的
-
阴阳师归鹿之途什么时候开 阴阳师全新版本归鹿之途一览 热点
近日阴阳师官方发布新版本归鹿之途即将开启,很多奇这个版本都有些什么
-
全新梅赛德斯奔驰GLC轿跑SUV发布 7月上市
近日,全新梅赛德斯奔驰GLC轿跑SUV插电混动版在海外正式发布。从外观上
-
提前批高职第一志愿_提前批高职
1、特殊考生,比如艺术生,体育生,音乐生。2、提前填报志愿的。本文就
-
香港一客机中止起飞 11人受伤 8人稳定3人已出院
国泰航空一班前往洛杉矶的客机中止起飞,11名乘客在逃生时报称受
-
动态:6月中旬流通领域生产资料价格:26种上涨 21种下降
中国网财经6月24日讯国家统计局今日发布2023年6月中旬流通领域重要生产
-
环球信息:海草床严重退化!该如何守护海洋的“发际线”?
海草床严重退化!该如何守护海洋的“发际线”?
-
今日要闻!十强城市一季度经济数据出炉:是“量”还是“质”?
十强城市一季度经济数据出炉:是“量”还是“质”?经济增速:深圳称雄
-
【天天聚看点】怎么做自己的手账本(手把手教你定制电子手账本)
hello大家好,我是城乡经济网小晟来为大家解答以上问题,怎么做自己的
-
5G聚合平台应用中心成立 快资讯
本报电(杨晶晶、李江南、赵梓亦)近日,广东深圳虚拟电厂管理中心、中
X 关闭
霍思燕几几年结婚的_霍思燕结过几次婚
银川烧烤店燃气爆炸事故原因公布 世界热资讯
600分还是600万?学历和财富都不是人生唯一标准 热点评
微资讯!如何认定的责任?
X 关闭
得知西安疫情防控“升级” 男子夜骑共享单车回咸阳淳化
中国医生将任SIU主席背后:从追随者同行者到引领者
海南省通报政法队伍教育整顿成果
云南两地发现核酸阳性人员 西安实行最严格的社会面管控
广东梅州大埔中央红色交通线沿线发现多株百岁古树