FFmpeg4入门系列教程15:mp3音频解码为pcm

您所在的位置:网站首页 pcm转换成mp3的手机软件 FFmpeg4入门系列教程15:mp3音频解码为pcm

FFmpeg4入门系列教程15:mp3音频解码为pcm

2023-08-15 18:28| 来源: 网络整理| 查看: 265

本文首发于:FFmpeg4入门系列教程15:mp3音频解码为pcm - 食铁兽

索引地址:幽弥狂:FFmpeg4入门系列教程索引

上一篇:幽弥狂:FFmpeg4入门系列教程14:Linux下摄像头捕获并编码为h264

本系列的之前文章介绍了视频的编解码相关,接下来介绍音频的编解码,本文将mp3音频文件解码为pcm。

使用的mp3音频文件为从网易云音乐上下载的排骨教主的牵丝戏,文件大小为9.6MB。

先看一下文件信息:

$ffprobe test.mp3 Input #0, mp3, from 'test.mp3': Metadata: encoder : Lavf57.25.100 album : 排骨翻唱合集 artist : 排骨教主 title : 牵丝戏 comment : 163 key(Don't modify):L64FU3W4YxX3ZFTmbZ+8/VtyyFZpYaEZwBWeBYUoIhTD9n+9XApvnDI33SQMX5/hovsUgti9hVA1nVRCnV2p/JFk/KogWWpzJQE7UDv7jwhDvQEpzKhh5cV1ribc34A73au+8wyCBqJDRJP2g7PSBHwGuxUsoS2O64gLvAdVfhfjd9p5aDHjskwNs6ZjhoQ45q6BlPJRf+bTmH0STg/SHgWMyYdN6EeHUVkFQTY06 track : 12 Duration: 00:03:59.44, start: 0.025056, bitrate: 321 kb/s Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s Metadata: encoder : Lavc57.24 Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 640x640 [SAR 256:256 DAR 1:1], 90k tbr, 90k tbn, 90k tbc (attached pic) Metadata: comment : Cover (front)

注意音频流Stream #0:0这行信息,格式为mp3,采样率为44.1kHz,stereo立体声(即双声道),fltp表示数据格式为浮点型(float)。

解码流程图为:

可以看到和幽弥狂:FFmpeg4入门系列教程5:解码视频流过程的基本流程是一样的。

解码代码为:

#include #include "libavcodec/avcodec.h" #include "libavfilter/avfilter.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" #include "libavutil/ffversion.h" #include "libswresample/swresample.h" #include "libswscale/swscale.h" #include "libpostproc/postprocess.h" int main() { const char inFileName[] = "/home/jackey/Music/test.mp3"; const char outFileName[] = "test.pcm"; FILE *file=fopen(outFileName,"w+b"); if(!file){ printf("Cannot open output file.\n"); return -1; } AVFormatContext *fmtCtx =avformat_alloc_context(); AVCodecContext *codecCtx = NULL; AVPacket *pkt=av_packet_alloc(); AVFrame *frame = av_frame_alloc(); int aStreamIndex = -1; do{ if(avformat_open_input(&fmtCtx,inFileName,NULL,NULL)streams[i]->codecpar->codec_type==AVMEDIA_TYPE_AUDIO){ aStreamIndex=(int)i; break; } } if(aStreamIndex==-1){ printf("Cannot find audio stream.\n"); return -1; } AVCodecParameters *aCodecPara = fmtCtx->streams[aStreamIndex]->codecpar; AVCodec *codec = avcodec_find_decoder(aCodecPara->codec_id); if(!codec){ printf("Cannot find any codec for audio.\n"); return -1; } codecCtx = avcodec_alloc_context3(codec); if(avcodec_parameters_to_context(codecCtx,aCodecPara)pkt_timebase = fmtCtx->streams[aStreamIndex]->time_base; if(avcodec_open2(codecCtx,codec,NULL)=0){ if(pkt->stream_index==aStreamIndex){ if(avcodec_send_packet(codecCtx,pkt)>=0){ while(avcodec_receive_frame(codecCtx,frame)>=0){ /* Planar(平面),其数据格式排列方式为 (特别记住,该处是以点nb_samples采样点来交错,不是以字节交错): LLLLLLRRRRRRLLLLLLRRRRRRLLLLLLRRRRRRL...(每个LLLLLLRRRRRR为一个音频帧) 而不带P的数据格式(即交错排列)排列方式为: LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLRL...(每个LR为一个音频样本) */ if(av_sample_fmt_is_planar(codecCtx->sample_fmt)){ int numBytes =av_get_bytes_per_sample(codecCtx->sample_fmt); //pcm播放时是LRLRLR格式,所以要交错保存数据 for(int i=0;inb_samples;i++){ for(int ch=0;chchannels;ch++){ fwrite((char*)frame->data[ch]+numBytes*i,1,numBytes,file); } } } } } } av_packet_unref(pkt); } }while(0); av_frame_free(&frame); av_packet_free(&pkt); avcodec_close(codecCtx); avcodec_free_context(&codecCtx); avformat_free_context(fmtCtx); fclose(file); return 0; }

和解码视频的部分类似。解码结果为84.5MB。

我们使用ffplay播放一下看看效果:

ffplay -ar 44100 -ac 2 -f f32le -i test.pcm

ar为audio rate,ac为audio channel ,f32le为float 32位小端数据格式。

显示为:

没发现什么大问题。

完整代码在github中的15.ffmpeg_audio_decode_mp32pcm。

下一篇:幽弥狂:FFmpeg4入门系列教程16:音频重采样解码为pcm



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3