编写一个基于ffmpeg的处理音频流的c++例子
时间: 2023-07-16 12:12:48 浏览: 250
好的,以下是一个基于FFmpeg的处理音频流的C语言示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <libavformat/avformat.h>
int main(int argc, char **argv)
{
av_register_all();
AVFormatContext *in_fmt_ctx = NULL, *out_fmt_ctx = NULL;
AVCodecContext *audio_codec_ctx = NULL;
int ret = 0;
if (argc < 3) {
fprintf(stderr, "Usage: %s input_file output_file\n", argv[0]);
return 1;
}
// 打开输入文件并获取输入格式上下文
if ((ret = avformat_open_input(&in_fmt_ctx, argv[1], NULL, NULL)) < 0) {
fprintf(stderr, "Could not open input file '%s': %d\n", argv[1], ret);
return 1;
}
// 获取输入流信息
if ((ret = avformat_find_stream_info(in_fmt_ctx, NULL)) < 0) {
fprintf(stderr, "Failed to retrieve input stream information: %d\n", ret);
return 1;
}
// 打印输入流信息
av_dump_format(in_fmt_ctx, 0, argv[1], 0);
// 查找音频流
int audio_stream_idx = av_find_best_stream(in_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if (audio_stream_idx < 0) {
fprintf(stderr, "Could not find audio stream in the input file\n");
return 1;
}
// 获取音频解码器
AVCodecParameters *audio_codec_params = in_fmt_ctx->streams[audio_stream_idx]->codecpar;
AVCodec *audio_codec = avcodec_find_decoder(audio_codec_params->codec_id);
if (!audio_codec) {
fprintf(stderr, "Failed to find audio codec\n");
return 1;
}
// 初始化音频解码器上下文
audio_codec_ctx = avcodec_alloc_context3(audio_codec);
if (!audio_codec_ctx) {
fprintf(stderr, "Failed to allocate audio codec context\n");
return 1;
}
if ((ret = avcodec_parameters_to_context(audio_codec_ctx, audio_codec_params)) < 0) {
fprintf(stderr, "Failed to copy audio codec parameters to context: %d\n", ret);
return 1;
}
if ((ret = avcodec_open2(audio_codec_ctx, audio_codec, NULL)) < 0) {
fprintf(stderr, "Failed to open audio codec: %d\n", ret);
return 1;
}
// 打开输出文件并获取输出格式上下文
if ((ret = avformat_alloc_output_context2(&out_fmt_ctx, NULL, NULL, argv[2])) < 0) {
fprintf(stderr, "Could not create output context: %d\n", ret);
return 1;
}
// 创建输出流
AVStream *out_audio_stream = avformat_new_stream(out_fmt_ctx, NULL);
if (!out_audio_stream) {
fprintf(stderr, "Failed to create output audio stream\n");
return 1;
}
// 复制输入流参数到输出流
if ((ret = avcodec_parameters_copy(out_audio_stream->codecpar, audio_codec_params)) < 0) {
fprintf(stderr, "Failed to copy audio codec parameters: %d\n", ret);
return 1;
}
// 写出格式头
if ((ret = avformat_write_header(out_fmt_ctx, NULL)) < 0) {
fprintf(stderr, "Failed to write output file header: %d\n", ret);
return 1;
}
// 初始化音频帧
AVFrame *audio_frame = av_frame_alloc();
if (!audio_frame) {
fprintf(stderr, "Failed to allocate audio frame\n");
return 1;
}
// 初始化音频数据包
AVPacket *packet = av_packet_alloc();
if (!packet) {
fprintf(stderr, "Failed to allocate packet\n");
return 1;
}
// 循环读取音频包并写入输出文件
while (av_read_frame(in_fmt_ctx, packet) >= 0) {
if (packet->stream_index == audio_stream_idx) {
// 解码音频包
ret = avcodec_send_packet(audio_codec_ctx, packet);
if (ret < 0) {
fprintf(stderr, "Error sending a packet to the decoder: %d\n", ret);
break;
}
while (ret >= 0) {
// 获取解码音频帧
ret = avcodec_receive_frame(audio_codec_ctx, audio_frame);
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
break;
} else if (ret < 0) {
fprintf(stderr, "Error while decoding audio frame: %d\n", ret);
break;
}
// 将解码音频帧写入输出文件
ret = av_write_frame(out_fmt_ctx, audio_frame->pts, audio_frame->buf, audio_frame->linesize[0], audio_frame->key_frame);
if (ret < 0) {
fprintf(stderr, "Error writing audio frame to output file: %d\n", ret);
break;
}
}
}
av_packet_unref(packet);
}
// 写出格式尾
av_write_trailer(out_fmt_ctx);
// 释放资源
av_frame_free(&audio_frame);
av_packet_free(&packet);
avformat_close_input(&in_fmt_ctx);
avcodec_free_context(&audio_codec_ctx);
avformat_free_context(out_fmt_ctx);
return 0;
}
```
此代码通过FFmpeg库提供的函数,可以从输入音频文件中读取音频流数据,然后使用音频解码器进行解码,并将解码后的音频流写入输出文件。这个示例是一个非常基础的处理音频流的程序,但是它可以供您参考,并且根据您的需求进行修改以满足您的特定需求。
阅读全文