当前位置: 首页>资讯 >

天天微速讯:如何将PCM格式的原始音频采样数据编码为MP3格式或AAC格式的音频文件?

来源: 博客园 | 时间: 2023-06-20 12:23:11 |

一.打开和关闭输入文件和输出文件以及判断输入文件是否读取完毕


(资料图片仅供参考)

//io_data.cppstatic FILE* input_file= nullptr;static 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."<

二.音频编码器的初始化

//audio_encoder_core.cppstatic const AVCodec* codec= nullptr;static AVCodecContext* codec_ctx= nullptr;static AVFrame* frame= nullptr;static AVPacket* pkt= nullptr;static enum AVCodecID audio_codec_id;int32_t init_audio_encoder(const char* codec_name){    if(strcasecmp(codec_name,"MP3")==0){        audio_codec_id=AV_CODEC_ID_MP3;        cout<<"Select codec id:MP3"<bit_rate=128000;    codec_ctx->sample_fmt=AV_SAMPLE_FMT_FLTP;    codec_ctx->sample_rate=44100;    codec_ctx->channel_layout=AV_CH_LAYOUT_STEREO;    codec_ctx->channels=2;    int32_t result=avcodec_open2(codec_ctx,codec, nullptr);    if(result<0){        cerr<<"Error:could not open codec."<nb_samples=codec_ctx->frame_size;//采样点数量    frame->format=codec_ctx->sample_fmt;    frame->channel_layout=codec_ctx->channel_layout;    result= av_frame_get_buffer(frame,0);    if(result<0){        cerr<<"Error:AVFrame could not get buffer."<

三.编码循环体

1.PCM文件的存储结构

音频采样格式可以分为packed和planar两类。以packed格式保存的采样数据,各声道间按照采样值交替存储;以planar格式保存的采样数据,各个采样值按照不同声道连续存储

下面以8bit为例展示planar和packed格式是如何保存音频采样数据的:

packed:
左声道0右声道0左声道1右声道1左声道2右声道2左声道3右声道3

planar:

左声道0左声道1左声道2左声道3右声道0右声道1右声道2右声道3

2.读取PCM音频采样数据

由于我们代码里设置了采样格式为fltp,即planar格式,而输入的PCM音频采样数据是packed格式的,因此我们需要将packed格式转化为planar格式进行保存:

//io_data.cppint32_t read_pcm_to_frame(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++){            fread(frame->data[ch]+i*data_size,1,data_size,input_file);        }    }    return 0;}

3.编码音频采样数据

//audio_encoder_core.cppstatic int32_t encode_frame(bool flushing){    int32_t result=0;    if(!flushing){        cout<<"Send frame to encoder with pts:"<<frame->pts<=0){        result= avcodec_receive_packet(codec_ctx,pkt);        if(result==AVERROR(EAGAIN)||result==AVERROR_EOF){//尚未完成对新一帧的编码,要传入后续帧或编码器已完全输出内部缓存的码流            return 1;        }        else if(result<0){            cerr<<"Error:avcodec_receive_packet failed."<dts<<",pts:"<pts<<", "<

4.写出码流数据  

//io_data.cppvoid write_pkt_to_file(AVPacket* pkt){    fwrite(pkt->data,1,pkt->size,output_file);}

5.实现编码循环

//audio_encoder_core.cppint32_t audio_encoding(){    int32_t result=0;    while(!end_of_input_file()){        result= read_pcm_to_frame(frame,codec_ctx);        if(result<0){            cerr<<"Error:read_pcm_to_frame failed."<

6.关闭编码器

//audio_encoder_core.cppvoid destroy_audio_encoder(){    av_frame_free(&frame);    av_packet_free(&pkt);    avcodec_free_context(&codec_ctx);}

7.最终main函数的实现如下:

int main(){    const char* input_file_name="../input.pcm";    const char* output_file_name="../output.mp3";    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_encoder(codec_name);    if(result<0){        return result;    }    result=audio_encoding();    if(result<0){        return result;    }    destroy_audio_encoder();    close_input_output_files();    return 0;}

与视频文件类似,可以使用ffplay播放输出的.mp3文件来测试效果。

关键词:

 

热文推荐

天天微速讯:如何将PCM格式的原始音频采样数据编码为MP3格式或AAC格式的音频文件?

一 打开和关闭输入文件和输出文件以及判断输入文件是否读取完毕 io_da

2023-06-20

快速背英语单词的方法和技巧_快速背英语单词的方法-每日视讯

1、首先,你要找到英语发音与汉语拼音之间的关系。2、达到“会读就会拼

2023-06-20

Vision Pro入门版本:苹果基于iPhone的VR头显专利出炉

不久前,苹果公布了VisionPro头显,但比起它强大的功能,更令人印象深

2023-06-20

“白色黄金”锂的绿色化难题 新消息

如果仅增加锂产量,不解决其开发加工中的资源、生态、环境和社会问题,

2023-06-20

别克SUV ELECTRA E4上市 售价18.99万-25.99万元 消息

6月19日,上汽通用汽车别克品牌宣布,高档纯电轿跑SUV别克ELECTRAE4上

2023-06-20

大脚lol盒子官方下载 lol大脚最新版本|全球观点

1、现在好像都不能换皮肤了。相信通过lol大脚最新版本这篇文章能帮到你

2023-06-20

看余杭618狂欢大派“兑”,超多福利来咯!限时折扣、5折兑换!

看余杭APP“积分商城618”双重福利不要错过!【福利1:全场5折起兑】【

2023-06-20

房子产权到了70年后怎么办 每日热闻

房子产权到了70年后,房屋所有权人可以缴纳一定的费用,房屋就会自动续

2023-06-20

航班取消如何赔偿乘客

一、航班取消如何赔偿乘客航班取消的补偿有:由于承运人自身原因,造成

2023-06-20

今日热门!小鹏,站在悬崖边上?

小鹏,正站在深渊边上。截至2023年6月19日收盘,理想、蔚来总市值分别

2023-06-20

世界最资讯丨伊力特(600197)6月19日主力资金净卖出1962.65万元

截至2023年6月19日收盘,伊力特(600197)报收于28 36元,下跌2 98%,换

2023-06-20

实时焦点:湖南软件和信息技术服务业营收突破2000亿元

新湖南,主流新媒体,移动新门户。-分享自@新湖南

2023-06-20

6月19日基金净值:华商新兴活力混合最新净值2.713,涨2.8% 热点

6月19日,华商新兴活力混合最新单位净值为2 713元,累计净值为2 713元

2023-06-20

烤箱烤红薯能直接烤吗怎么烤

关于烤箱烤红薯能直接烤吗怎么烤的内容,包含用烤箱烤红薯怎么烤烤箱烤

2023-06-20

令我感动的一件事开头结尾 即时看

1、一、好的开头感动有许多种,对一件事的感动,对一句话的感动对一个

2023-06-20

岳阳首批政务服务效能监督员“上岗”

湖南日报·新湖南客户端6月19日讯(记者徐典波通讯员魏志华黄艳张苡苡

2023-06-19

1n立方米n是什么意思(n立方米是什么单位) 世界热门

n立方米n是什么意思,n立方米是什么单位这个问题很多朋友还不知道,来

2023-06-19

焦点速看:抖音怎么卖东西 抖音怎么卖自己的产品

演示机型:iPhone12,适用系统:iOS14 3,软件版本:抖音14 9 0。打开

2023-06-19

中楚物业被行政处罚,因违反生活垃圾管理条例

6月19日,中楚物业股份有限公司(以下简称“中楚物业”)被北京市丰台

2023-06-19

海南:开展基础教育质量提升三年攻坚行动|天天快资讯

中国教育报-中国教育新闻网讯(特约通讯员金浩田)从2012年到2022年,

2023-06-19