使用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
关键词:
相关阅读
-
使用libavcodec将mp3音频文件解码为pcm...
一 打开和关闭输入文件和输出文件想要解决上面提到的问题,我们需要对m -
【天天热闻】世界各国央行出手加息,应...
近日,世界各国央行纷纷出手,加息提高基准利率。土耳其央行宣布将基准 -
全球微头条丨dnf喊话怎么重复上一句_dnf喊话
1、01进入游戏后,点击下方功能栏中的“菜单键”或直接按下“ESC”... -
天天新资讯:雷佳音吴越分获白玉兰最佳...
第二十八届上海电视节白玉兰奖23日在上海揭晓。雷佳音凭借《人世间》获 -
点雄黄、钓粽子、猜谜、投壶…端午最后...
6月24日是端午假期最后一天大家端午节过得开心吗?在叙州区南岸西区财 -
焦点快报!工银新材料新能源基金
本文内容是由小编为大家搜集关于工银新材料新能源,以及工银新材料新能 -
美亚柏科股票-美亚柏科股票诊断-世界视点
本文内容是由小编为大家搜集关于美亚柏科股票,以及美亚柏科股票诊断的 -
金税盘怎么开票视频教程_金税盘怎么开票
1、网上领票管理主要功能:企业可以领用纸质发票后,通过网络方式下载 -
端午文创走俏 传统文化创新表达
央视网消息(新闻联播):传统文化,创新表达。今年端午节,各地的端午 -
焦点日报:客厅养什么花好(客厅养什么花...
客厅养什么花最吉利1、客厅财位盆景花叶须圆且大,忌针叶类及杜鹃。尤 -
尚太科技:二季度应用于储能电池的负极...
证券时报e公司讯,尚太科技近日接受机构调研时表示,目前,公司储能电 -
秦穆公尝出而亡其骏马自往求之翻译 秦...
1、1.见人已杀其马/方共食其肉。2、2.骏马被人宰杀后,秦穆公不但不 -
每日快播:【驾春秋】2025款大众探歌谍...
今年4月,大众官宣下一代的T-Roc,也就是国内版本的探歌将是大众最后的 -
奥运冠军李雪芮传递成都大运会火炬 呼...
华龙网-新重庆客户端讯(余文欣)6月24日上午,成都第31届世界大学生夏 -
仅4人踢遍五大联赛:拉杜乔尤&鲍尔森&约...
直播吧6月24日讯至今只有4名球员在欧洲五大联赛都效力过,最新实现这一 -
狼人杀综艺马东_狼人杀综艺
1、《饭局的诱惑》《饭局的诱惑》是国内首档明星狼人杀访谈综艺节目。2 -
每日资讯:租借女友288话剧透
这张大家应该都有了 288女友与女友的朋友2封面:千鹤抱著一个和也的布 -
商标续展需要提交什么材料_商标续展需要...
1、如何办理商标续展,需要准备哪些材料呢?(一)准备申请书件应提交 -
当前焦点!端午假期交通部门加强多种出行...
央视网消息(新闻联播):今天(6月23日)是端午假期的第二天,全国铁 -
【天天时快讯】金针菇怎么保存? 金针...
家里的金针菇已经买了有10天了,这样的金针菇还能不能继续吃呢?日常生