方法1:命令转码
# 转码ffmpeg -ac 2 -ar 48000 -f s16le -i input.pcm -acodec libfdk_aac output.aac # 播放 ffplay output.aac
方法2:代码转码
main.c
#include "libavutil/log.h" #include "libavutil/avutil.h" #include "libavcodec/avcodec.h" #include "libavutil/parseutils.h"int encodeAudio(AVCodecContext *encoderCtx, AVFrame *frame, AVPacket *packet, FILE *dst) {int ret = avcodec_send_frame(encoderCtx, frame);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "avcodec_send_frame failed:%s\n", av_err2str(ret));return -1;}while (ret >= 0) {ret = avcodec_receive_packet(encoderCtx, packet);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return 0;} else if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "avcodec_receive_packet failed:%s\n", av_err2str(ret));return -1;}fwrite(packet->data, 1, packet->size, dst);av_packet_unref(packet);}return 0; }int main(int argc, char **argv) {av_log_set_level(AV_LOG_DEBUG);if (argc < 3) {av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile outputFile\n", argv[0]);return -1;}const char *inputFile = argv[1];const char *outputFile = argv[2];AVFrame *frame = av_frame_alloc();frame->sample_rate = 48000;frame->channels = 2;frame->channel_layout = AV_CH_LAYOUT_STEREO;frame->format = AV_SAMPLE_FMT_S16;frame->nb_samples = 1024;av_frame_get_buffer(frame, 0);AVCodec *encoder = avcodec_find_encoder_by_name("libfdk_aac");if (encoder == NULL) {av_log(NULL, AV_LOG_ERROR, "avcodec_find_encoder_by_name failed\n");av_frame_free(&frame);return -1;}AVCodecContext *encoderCtx = avcodec_alloc_context3(encoder);if (encoderCtx == NULL) {av_log(NULL, AV_LOG_ERROR, "avcodec_find_encoder_by_name failed\n");av_frame_free(&frame);return -1;}encoderCtx->sample_fmt = frame->format;encoderCtx->sample_rate = frame->sample_rate;encoderCtx->channels = frame->channels;encoderCtx->channel_layout = frame->channel_layout;int ret;ret = avcodec_open2(encoderCtx, encoder, NULL);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "avcodec_open2 failed\n");av_frame_free(&frame);avcodec_free_context(&encoderCtx);return -1;}FILE *inFp = fopen(inputFile, "rb");if (inFp == NULL) {av_log(NULL, AV_LOG_ERROR, "open input file failed\n");av_frame_free(&frame);avcodec_free_context(&encoderCtx);return -1;}FILE *ontFp = fopen(outputFile, "wb+");if (ontFp == NULL) {av_log(NULL, AV_LOG_ERROR, "open output file failed\n");av_frame_free(&frame);avcodec_free_context(&encoderCtx);fclose(inFp);return -1;}AVPacket *packet = av_packet_alloc();while (1) {size_t readSize = fread(frame->data[0], 1, frame->linesize[0], inFp);if (readSize == 0) {av_log(NULL, AV_LOG_INFO, "finish read input file\n");break;}encodeAudio(encoderCtx, frame, packet, ontFp);}encodeAudio(encoderCtx, NULL, packet, ontFp);av_frame_free(&frame);avcodec_free_context(&encoderCtx);fclose(inFp);fclose(ontFp);return 0; }
Makefile
TARGET=main SRC=main.c CC=gcc CFLAGS=-I /usr/local/ffmpeg/include LDFLAGS=-L /usr/local/ffmpeg/lib LDFLAGS+= -lavutil -lavformat -lavcodec -lswscale all:$(TARGET) $(TARGET):$(SRC)$(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) clean:rm -rf $(TARGET)