方法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)