代码和上篇几乎一模一样,只需将输出文件的后缀改为mp3即可。

目录

程序源码

看到几篇不错的博文


程序源码

/****本程序实现了音频PCM采样数据编码为压缩码流(MP3,WMA,AAC等)。**/#include <stdio.h>#define __STDC_CONSTANT_MACROSextern "C"
{
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
#include "libavdevice/avdevice.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/imgutils.h"
}int flush_encoder(AVFormatContext *fmt_ctx, unsigned int stream_index)
{int ret;int got_frame;AVPacket enc_pkt;if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &AV_CODEC_CAP_DELAY))return 0;while (1){enc_pkt.data = NULL;enc_pkt.size = 0;av_init_packet(&enc_pkt);ret = avcodec_encode_audio2(fmt_ctx->streams[stream_index]->codec, &enc_pkt,NULL, &got_frame);av_frame_free(NULL);if (ret < 0)break;if (!got_frame){ret = 0;break;}printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n", enc_pkt.size);/* mux encoded frame */ret = av_write_frame(fmt_ctx, &enc_pkt);if (ret < 0)break;}return ret;
}int main(int argc, char *argv[])
{AVFormatContext *pFormatCtx = NULL;AVCodecContext *pCodecCtx = NULL;AVCodec *pCodec = NULL;AVFrame *pFrame = NULL;AVPacket pkt;int i = 0;const char *inFilename = "s16le.pcm";const char *outFilename = "output.mp3";avdevice_register_all();avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, outFilename);if (avio_open(&pFormatCtx->pb, outFilename, AVIO_FLAG_READ_WRITE) < 0){printf("can't open output file\n");return -1;}AVStream *stream = avformat_new_stream(pFormatCtx, NULL);if (!stream){printf("can't allocate new stream\n");return -1;}//设置参数pCodecCtx = stream->codec;pCodecCtx->codec_id = pFormatCtx->oformat->audio_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;pCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;pCodecCtx->sample_rate = 44100;pCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);pCodecCtx->bit_rate = 128000;
//  pCodecCtx->frame_size = 1024;//查找编码器pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
//  pCodec = avcodec_find_encoder_by_name("libfdk_aac");if (!pCodec){printf("can't find encoder\n");return -1;}//打开编码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){printf("can't open encoder\n");return -1;}pFrame = av_frame_alloc();if (!pFrame){printf("can't alloc frame\n");return -1;}pFrame->nb_samples = pCodecCtx->frame_size;pFrame->format = pCodecCtx->sample_fmt;pFrame->channels = 2;//PCM重采样SwrContext *swrCtx = swr_alloc();swr_alloc_set_opts(swrCtx, av_get_default_channel_layout(pCodecCtx->channels), pCodecCtx->sample_fmt,pCodecCtx->sample_rate, av_get_default_channel_layout(pFrame->channels), AV_SAMPLE_FMT_S16, //PCM源文件的采样格式44100, 0, NULL);swr_init(swrCtx);/* 分配空间 */uint8_t **convert_data = (uint8_t**) calloc(pCodecCtx->channels, sizeof(*convert_data));av_samples_alloc(convert_data, NULL, pCodecCtx->channels, pCodecCtx->frame_size, pCodecCtx->sample_fmt, 0);int size = av_samples_get_buffer_size(NULL, pCodecCtx->channels, pCodecCtx->frame_size, pCodecCtx->sample_fmt, 1);uint8_t *frameBuf = (uint8_t*) av_malloc(size);avcodec_fill_audio_frame(pFrame, pCodecCtx->channels, pCodecCtx->sample_fmt, (const uint8_t*) frameBuf, size, 1);//写帧头avformat_write_header(pFormatCtx, NULL);FILE *inFile = fopen(inFilename, "rb");av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;for (i = 0;; i++){//输入一帧数据的长度int length = pFrame->nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * pFrame->channels;printf("length = %d\n", length);//读PCM:特意注意读取的长度,否则可能出现转码之后声音变快或者变慢if (fread(frameBuf, 1, length, inFile) <= 0){printf("failed to read raw data\n");return -1;}else if (feof(inFile)){break;}swr_convert(swrCtx, convert_data, pCodecCtx->frame_size, (const uint8_t**) pFrame->data, pFrame->nb_samples);//输出一帧数据的长度length = pCodecCtx->frame_size * av_get_bytes_per_sample(pCodecCtx->sample_fmt);//双通道赋值(输出的AAC为双通道)memcpy(pFrame->data[0], convert_data[0], length);memcpy(pFrame->data[1], convert_data[1], length);pFrame->pts = i * 100;if (avcodec_send_frame(pCodecCtx, pFrame) < 0){printf("can't send frame for encoding\n");break;}if (avcodec_receive_packet(pCodecCtx, &pkt) >= 0){pkt.stream_index = stream->index;printf("write %4d frame, size = %d, length = %d\n", i, size, length);av_write_frame(pFormatCtx, &pkt);}av_packet_unref(&pkt);}//flush encoderif (flush_encoder(pFormatCtx, 0) < 0){printf("flushing encoder failed\n");return -1;}//write trailerav_write_trailer(pFormatCtx);avcodec_close(stream->codec);av_free(pFrame);av_free(frameBuf);avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);fclose(inFile);return 0;
}

看到几篇不错的博文

音频重采样

音频编码为AAC/MP3

常见音频编码格式

FFmpeg —— 15.示例程序(九):音频编码器(PCM编码为MP3)相关推荐

  1. 程序人生 - 音频格式 PCM、WAV、MP3 区别

    PCM PCM(Pulse Code Modulation----脉码调制录音).所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录.PCM信号是由[1].[0]等符号构成的数字信号,而 ...

  2. FFmpeg —— 12.示例程序(六):视频编码器(YUV编码为H264)

    流程 下面附一张使用FFmpeg编码视频的流程图.使用该流程,不仅可以编码H.264的视频,而且可以编码MPEG4/MPEG2/VP8等等各种FFmpeg支持的视频.图中蓝色背景的函数是实际输出数据的 ...

  3. FFmpeg示例程序合集-批量编译脚本

    此前做了一系列有关FFmpeg的示例程序,组成了< 最简单的FFmpeg示例程序合集>,其中包含了如下项目: simplest ffmpeg player:                 ...

  4. FFmpeg示例程序合集-Git批量获取脚本

    此前做了一系列有关FFmpeg的示例程序,组成了< FFmpeg示例程序合集>,其中包含了如下项目: simplest ffmpeg player:                  最简 ...

  5. android音频编辑之音频转换PCM与WAV

    前言 本篇开始讲解在Android平台上进行的音频编辑开发,首先需要对音频相关概念有基础的认识.所以本篇要讲解以下内容: 常用音频格式简介 WAV和PCM的区别和联系 WAV文件头信息 采样率简介 声 ...

  6. 原 android音频编辑之音频转换PCM与WAV

    http://blog.csdn.net/hesong1120/article/details/79043482 本文出自: hesong的专栏 前言 本篇开始讲解在Android平台上进行的音频编辑 ...

  7. FFMPEG实现PCM编码(采用封装格式实现)

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 原文:https://blog.csdn.net/hiwubihe/article/details/81260882 [音频编解码系列文章] 音 ...

  8. 音频编码器为packed(非planar)格式时的说明

    本人之前写过一些用ffmpeg录制系统声音,麦克风声音的博客:比如ffmpeg录制系统声音 ,由于采取的是ffmpeg自带的aac音频编码器,故最终的音频编码的格式一直是AV_SAMPLE_FMT_F ...

  9. 音频文件PCM、WAV、MP3的区别以及文件合并

     一.数字音频三要素 1.采样率 采样率即采样频率,指的一秒内的采样次数,它反映了采样点之间的间隔大小.常说的 44.1KHz 采样率,也即 1 秒采集了 44100 个样本.间隔越小,丢失的信息越少 ...

  10. 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

    本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样数据编码为AAC的压缩编码数据.编码器代码十分简单,但是每一行代码都很重要.通过看本编码器的源代码,可以了解FFMPEG音 ...

最新文章

  1. rhel-server-7.5-x86_64-dvd.iso镜像下载及rar压缩包的解压
  2. 怎样导出或导入Cookie
  3. python在线编辑器最新_Editor.md 二次开发-markdown在线编辑器
  4. 看一遍就理解,图解单链表反转
  5. [转载]MIT牛人解说数学体系
  6. 二叉树小球下落问题c语言,#C++初学记录(树和二叉树)
  7. vim配置之spacevim
  8. 今天将多线程的知识有回顾了下,总结了几点:
  9. 【FZU2178】礼物分配
  10. H5 71-网易注册界面4
  11. 某大型银行深化系统技术方案之十五:服务层之服务调用
  12. 实现中文下的UITableView Index
  13. AWS AI网络研讨会 webinar - Case 分享
  14. 计算机自带游戏怎么调,电脑游戏声音小怎么调,教您电脑游戏声音小怎么调
  15. 向工程腐化开炮:Java代码治理
  16. java中BigDecimal求余
  17. Android手机哪个悬浮好用,别羡慕苹果了,安卓悬浮神器比 iPhone 好用太多!
  18. BCD编码和ASCII码
  19. signature=c4f11bb5142d9f6ce0876b3cc0d888af,1【这人生我去了吧】_百度贴吧
  20. java毕业生设计医保局综合办公系统计算机源码+系统+mysql+调试部署+lw

热门文章

  1. nodejs 系统 临时文件夹
  2. 网络工程师常用的软件工具整理,最新软件安装包分享
  3. html如何设置本地链接,本地连接受限制或无连接【方法|图文教程】-太平洋IT百科...
  4. Linux命令之cat和tac篇
  5. [OpenGL] 太阳镜头光晕效果
  6. AI 让已故歌手重聚,再发4首原创新歌
  7. CentOS 安装 无线USB网卡 RTL8192EU
  8. 程序员必备网络基础知识清单,简单易懂
  9. 诡辩六论——微信陌陌如何话题不断的聊天
  10. CMakeLists.txt文本编辑工具