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