ffmpeg 通过avcodec 把pcm转mp3
时间: 2023-07-25 14:43:50 浏览: 140
使用FFmpeg的AVCodec API 将PCM音频转换为MP3格式可以分为以下几个步骤:
1. 初始化FFmpeg库和AVCodec上下文。
2. 创建输入和输出AVFrame。
3. 将PCM音频数据填充到输入AVFrame中。
4. 使用AVCodec API进行编码。
5. 将编码后的MP3音频数据从输出AVFrame中获取。
6. 将MP3音频数据写入文件。
以下是一个示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
int main(int argc, char *argv[]) {
const char *input_file = "input.pcm";
const char *output_file = "output.mp3";
// 初始化FFmpeg库
av_register_all();
// 获取MP3编码器
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
if (!codec) {
fprintf(stderr, "Failed to find MP3 encoder\n");
return 1;
}
// 创建编码上下文
AVCodecContext *ctx = avcodec_alloc_context3(codec);
if (!ctx) {
fprintf(stderr, "Failed to allocate codec context\n");
return 1;
}
// 配置编码器参数
ctx->channels = 1;
ctx->sample_rate = 44100;
ctx->bit_rate = 128000;
ctx->sample_fmt = AV_SAMPLE_FMT_S16;
ctx->codec_id = AV_CODEC_ID_MP3;
if (avcodec_open2(ctx, codec, NULL) < 0) {
fprintf(stderr, "Failed to open codec\n");
return 1;
}
// 创建输入AVFrame
AVFrame *frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Failed to allocate frame\n");
return 1;
}
frame->nb_samples = ctx->frame_size;
frame->format = ctx->sample_fmt;
av_frame_get_buffer(frame, 0);
// 打开输入文件
FILE *input_f = fopen(input_file, "rb");
if (!input_f) {
fprintf(stderr, "Failed to open input file\n");
return 1;
}
// 打开输出文件
FILE *output_f = fopen(output_file, "wb");
if (!output_f) {
fprintf(stderr, "Failed to open output file\n");
return 1;
}
// 创建编码器输出AVPacket
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int ret;
while (1) {
// 读取PCM数据到输入AVFrame中
if (fread(frame->data[0], 1, frame->linesize[0], input_f) <= 0) {
break;
}
// 编码输入AVFrame为输出AVPacket
ret = avcodec_send_frame(ctx, frame);
if (ret < 0) {
fprintf(stderr, "Error sending frame to codec: %s\n", av_err2str(ret));
return 1;
}
while (ret >= 0) {
ret = avcodec_receive_packet(ctx, &pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
fprintf(stderr, "Error receiving packet from codec: %s\n", av_err2str(ret));
return 1;
}
// 将编码后的音频数据写入输出文件
fwrite(pkt.data, 1, pkt.size, output_f);
av_packet_unref(&pkt);
}
}
// 刷新编码器缓冲区
ret = avcodec_send_frame(ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Error flushing frame to codec: %s\n", av_err2str(ret));
return 1;
}
while (ret >= 0) {
ret = avcodec_receive_packet(ctx, &pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
fprintf(stderr, "Error receiving packet from codec: %s\n", av_err2str(ret));
return 1;
}
// 将编码后的音频数据写入输出文件
fwrite(pkt.data, 1, pkt.size, output_f);
av_packet_unref(&pkt);
}
// 释放资源
fclose(input_f);
fclose(output_f);
av_frame_free(&frame);
avcodec_free_context(&ctx);
return 0;
}
```
你可以根据需要调整代码中的参数。
阅读全文