打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用ffmpeg解码音频文件到PCM格式
转自:http://www.xuebuyuan.com/1402006.html
使用ffmpeg解码音频文件到PCM格式
2013年05月17日 ? 综合 ? 共 3829字 ? 字号    ? 评论关闭
最近忙于使用ffmpeg播放音乐文件的项目,现将开发经验总结如下:
一、解码音乐文件的大致流程如下:
1,打开音乐文件,调用av_open_input_file()
2,查找audio stream,调用av_find_stream_info()
3,查找对应的decoder,调用avcodec_find_decoder()
4,打开decoder,调用avcodec_open()
5,读取一桢数据包,调用av_read_frame()
6,解码数据包,调用avcodec_decode_audio3()
7,将解码后的数据返回
这样,得到解码后的PCM数据之后,我们可以播放、也可以encode成其他格式。
二、相关代码
1,打开文件
// return 0: OK// return -1: arguments are wrongint internal_open(const char* file){ int i = 0; int res = 0; LOGD("enter internal_open(), file name:%s", file); if (file == 0 || strlen(file) == 0) { LOGE("%s, argument file is wrong!", __FUNCTION__); return -1; } // try open file if ((res = av_open_input_file(&m_format_ctx, file, NULL, 0, NULL)) != 0) { LOGE("%s, av_open_input_file() return failed!", __FUNCTION__); return res; } // find streams information if ((res = av_find_stream_info(m_format_ctx) < 0)) { LOGE("%s, av_find_stream_info() could not find codec parameters!", __FUNCTION__); return res; } av_dump_format(m_format_ctx, 0, file, 0); for(i = 0; i < m_format_ctx->nb_streams; i++) { // get audio stream id if(m_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { m_audio_stream = i; break; } } if(m_audio_stream == -1) { LOGE("%s, find audioStream failed!", __FUNCTION__); return -4; } // get audio stream codec m_codec_ctx = m_format_ctx->streams[m_audio_stream]->codec; // find the mpeg audio decoder m_codec = avcodec_find_decoder(m_codec_ctx->codec_id); if (!m_codec) { LOGE("%s, codec not found!", __FUNCTION__); return -5; } // open it if (avcodec_open(m_codec_ctx, m_codec) < 0) { LOGE("%s, could not open codec!", __FUNCTION__); return -7; } LOGD("exit internal_open()"); return 0;}2,解码数据
int internal_getaudio(unsigned char buff[], long num_samples){ //AVPacket avpkt; long copied_len = 0; int frame_size = 0; int decoded_len = 0; int real_copied = 0; int decoded_audio_len = 0; unsigned char* valid_data_pointer = 0; LOGD("enter internal_getaudio()"); // copy the backup (has not copied in last time) data at first! if (m_audio_buff_backup_len > 0) { LOGI("%s, has last not copied data in backup buff, length:%d", __FUNCTION__, m_audio_buff_backup_len); if (m_audio_buff_backup_len >= num_samples) { memcpy(buff, m_audio_buff_backup, num_samples); copied_len += num_samples; LOGI("%s, only copy data from backup buff, return 0", __FUNCTION__); } else { memcpy(buff, m_audio_buff_backup, m_audio_buff_backup_len); copied_len += m_audio_buff_backup_len; LOGI("%s, copy %d length data from backup buff", __FUNCTION__, m_audio_buff_backup_len); } } // decode new data while (copied_len < num_samples && av_read_frame(m_format_ctx, &m_avpkt) >= 0) { LOGI("%s, av_read_frame() return successful!", __FUNCTION__); if (m_avpkt.stream_index == m_audio_stream) { while (m_avpkt.size > 0) { LOGI("%s, current packet size:%d", __FUNCTION__, m_avpkt.size); frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; memset(m_audio_buff, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE); decoded_len = avcodec_decode_audio3(m_codec_ctx, (short *)m_audio_buff, &frame_size, &m_avpkt); LOGI("%s, current decoded size:%d", __FUNCTION__, decoded_len); if (decoded_len > 0) { m_avpkt.size -= decoded_len; m_avpkt.data += decoded_len; // copy audio data to output buff if ((num_samples-copied_len) > decoded_audio_len) { memcpy(buff+copied_len, m_audio_buff, frame_size); copied_len += frame_size; LOGI("%s, copy1, %d bytes has copied to output buff, total:%d!", __FUNCTION__, frame_size, copied_len); } else { real_copied = (num_samples-copied_len); memcpy(buff+copied_len, m_audio_buff, real_copied); copied_len += real_copied; LOGI("%s, copy2, %d bytes has copied to output buff, total:%d!", __FUNCTION__, real_copied, copied_len); m_audio_buff_backup_len = frame_size - real_copied; memcpy(m_audio_buff_backup, m_audio_buff+real_copied, m_audio_buff_backup_len); LOGI("%s, copy2, %d bytes has copied to backup buff!", __FUNCTION__, m_audio_buff_backup_len); break; } } else { LOGE("%s, decoded size is error, returned!", __FUNCTION__); break; } } } } LOGD("exit internal_getaudio(), decoded length: %d", copied_len); return copied_len;}3,关闭和释放资源
int internal_close(){ if (m_format_ctx) { av_close_input_file(m_format_ctx); m_format_ctx = 0; } return 0;}int internal_release(){ if (m_avpkt.data) { av_free_packet(&m_avpkt); } if (!m_codec_ctx) { avcodec_close(m_codec_ctx); m_codec_ctx = 0; } return 0;}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
FFmpeg转码框架解析
ffmpeg+sdl2.0做一个简单的音频播放器
ios一步一步编译ffmpeg,x264实现h264编码
FFmpeg学习教程
Decode mp3 audio using ffmpeg libraries | Muroa
ffmpeg中av_seek_frame使用样例(代码实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服