ffmpeg 音频转码代码
时间: 2024-03-02 08:46:51 浏览: 82
当然可以!下面是一个简单的示例代码,用于将音频文件从一种格式转码为另一种格式,使用了FFmpeg库:
```c++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
int main(int argc, char *argv[]) {
// 注册所有的编解码器和文件格式
av_register_all();
// 打开输入文件
AVFormatContext *inputContext = NULL;
if (avformat_open_input(&inputContext, argv[1], NULL, NULL) != 0) {
fprintf(stderr, "无法打开输入文件\n");
return -1;
}
// 获取输入文件的流信息
if (avformat_find_stream_info(inputContext, NULL) < 0) {
fprintf(stderr, "无法获取输入文件的流信息\n");
return -1;
}
// 找到音频流
int audioStreamIndex = -1;
for (int i = 0; i < inputContext->nb_streams; i++) {
if (inputContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStreamIndex = i;
break;
}
}
if (audioStreamIndex == -1) {
fprintf(stderr, "找不到音频流\n");
return -1;
}
// 获取输入音频解码器
AVCodecParameters *inputCodecParams = inputContext->streams[audioStreamIndex]->codecpar;
AVCodec *inputCodec = avcodec_find_decoder(inputCodecParams->codec_id);
if (inputCodec == NULL) {
fprintf(stderr, "找不到输入音频解码器\n");
return -1;
}
// 打开输入音频解码器
AVCodecContext *inputCodecContext = avcodec_alloc_context3(inputCodec);
if (avcodec_parameters_to_context(inputCodecContext, inputCodecParams) < 0) {
fprintf(stderr, "无法打开输入音频解码器\n");
return -1;
}
if (avcodec_open2(inputCodecContext, inputCodec, NULL) < 0) {
fprintf(stderr, "无法打开输入音频解码器\n");
return -1;
}
// 创建输出音频编码器
AVCodec *outputCodec = avcodec_find_encoder(AV_CODEC_ID_MP3);
if (outputCodec == NULL) {
fprintf(stderr, "找不到输出音频编码器\n");
return -1;
}
// 创建输出音频编码器上下文
AVCodecContext *outputCodecContext = avcodec_alloc_context3(outputCodec);
if (outputCodecContext == NULL) {
fprintf(stderr, "无法创建输出音频编码器上下文\n");
return -1;
}
// 设置输出音频编码器参数
outputCodecContext->sample_fmt = outputCodec->sample_fmts[0];
outputCodecContext->bit_rate = 128000;
outputCodecContext->sample_rate = inputCodecContext->sample_rate;
outputCodecContext->channels = inputCodecContext->channels;
// 打开输出音频编码器
if (avcodec_open2(outputCodecContext, outputCodec, NULL) < 0) {
fprintf(stderr, "无法打开输出音频编码器\n");
return -1;
}
// 创建输出文件
AVFormatContext *outputContext = NULL;
if (avformat_alloc_output_context2(&outputContext, NULL, NULL, argv[2]) < 0) {
fprintf(stderr, "无法创建输出文件\n");
return -1;
}
// 添加音频流到输出文件
AVStream *outputStream = avformat_new_stream(outputContext, outputCodec);
if (outputStream == NULL) {
fprintf(stderr, "无法添加音频流到输出文件\n");
return -1;
}
// 复制输入流的参数到输出流
if (avcodec_parameters_copy(outputStream->codecpar, inputCodecParams) < 0) {
fprintf(stderr, "无法复制输入流的参数到输出流\n");
return -1;
}
// 写入输出文件的头部
if (avformat_write_header(outputContext, NULL) < 0) {
fprintf(stderr, "无法写入输出文件的头部\n");
return -1;
}
// 初始化音频帧
AVFrame *frame = av_frame_alloc();
if (frame == NULL) {
fprintf(stderr, "无法初始化音频帧\n");
return -1;
}
// 初始化输出音频帧
AVFrame *outputFrame = av_frame_alloc();
if (outputFrame == NULL) {
fprintf(stderr, "无法初始化输出音频帧\n");
return -1;
}
outputFrame->nb_samples = outputCodecContext->frame_size;
outputFrame->format = outputCodecContext->sample_fmt;
outputFrame->channel_layout = outputCodecContext->channel_layout;
if (av_frame_get_buffer(outputFrame, 0) < 0) {
fprintf(stderr, "无法为输出音频帧分配缓冲区\n");
return -1;
}
// 初始化音频包
AVPacket packet;
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
// 读取输入文件的音频帧并转码
while (av_read_frame(inputContext, &packet) >= 0) {
if (packet.stream_index == audioStreamIndex) {
// 解码音频帧
if (avcodec_send_packet(inputCodecContext, &packet) < 0) {
fprintf(stderr, "无法解码音频帧\n");
return -1;
}
while (avcodec_receive_frame(inputCodecContext, frame) >= 0) {
// 转码音频帧
if (avcodec_send_frame(outputCodecContext, frame) < 0) {
fprintf(stderr, "无法转码音频帧\n");
return -1;
}
while (avcodec_receive_packet(outputCodecContext, &packet) >= 0) {
// 写入输出文件
packet.stream_index = outputStream->index;
av_packet_rescale_ts(&packet, inputCodecContext->time_base, outputStream->time_base);
if (av_interleaved_write_frame(outputContext, &packet) < 0) {
fprintf(stderr, "无法写入输出文件\n");
return -1;
}
av_packet_unref(&packet);
}
}
}
av_packet_unref(&packet);
}
// 写入输出文件的尾部
if (av_write_trailer(outputContext) < 0) {
fprintf(stderr, "无法写入输出文件的尾部\n");
return -1;
}
// 清理资源
av_frame_free(&frame);
av_frame_free(&outputFrame);
avcodec_free_context(&inputCodecContext);
avcodec_free_context(&outputCodecContext);
avformat_close_input(&inputContext);
avformat_free_context(outputContext);
return 0;
}
```
这段代码使用了FFmpeg库来进行音频转码。它打开输入文件,找到音频流,创建输入音频解码器和输出音频编码器,然后逐帧读取输入文件的音频帧并进行解码和转码,最后将转码后的音频帧写入输出文件。
请注意,这只是一个简单的示例代码,实际使用时可能需要根据具体需求进行修改和扩展。另外,为了编译这段代码,你需要安装FFmpeg库并将其链接到你的项目中。
阅读全文