生成一个基于C语言的FFMPEG音频保存程序员
时间: 2024-06-08 18:12:13 浏览: 16
以下是一个基于C语言的FFmpeg音频保存程序示例,该程序可以从音频文件中提取数据并将其保存到另一个音频文件中:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <libavutil/frame.h>
#include <libavutil/mem.h>
#include <libavutil/samplefmt.h>
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/error.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
int main(int argc, char **argv)
{
AVCodec *codec;
AVCodecContext *codec_ctx = NULL;
AVFormatContext *input_fmt_ctx = NULL;
AVFormatContext *output_fmt_ctx = NULL;
AVPacket packet;
AVFrame *frame = NULL;
SwrContext *swr_ctx = NULL;
uint8_t **resampled_data = NULL;
int resampled_linesize;
int stream_index = -1;
int ret, i;
if (argc != 3) {
fprintf(stderr, "Usage: %s input_file output_file\n"
"Example program to save a media file in a custom container format.\n"
"The output format is guessed according to the file extension.\n",
argv[0]);
exit(1);
}
av_register_all();
avcodec_register_all();
/* open the input file */
if (avformat_open_input(&input_fmt_ctx, argv[1], NULL, NULL) < 0) {
fprintf(stderr, "Could not open input file '%s'", argv[1]);
exit(1);
}
/* retrieve stream information */
if (avformat_find_stream_info(input_fmt_ctx, NULL) < 0) {
fprintf(stderr, "Could not find stream information");
exit(1);
}
/* select the audio stream */
ret = av_find_best_stream(input_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
if (ret < 0) {
fprintf(stderr, "Could not find audio stream in the input file");
exit(1);
}
stream_index = ret;
/* allocate codec context */
codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx) {
fprintf(stderr, "Could not allocate codec context");
exit(1);
}
/* fill codec context based on input stream */
if (avcodec_parameters_to_context(codec_ctx, input_fmt_ctx->streams[stream_index]->codecpar) < 0) {
fprintf(stderr, "Could not fill codec context based on input stream");
exit(1);
}
/* open the codec */
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec");
exit(1);
}
/* allocate resampler context and set options */
swr_ctx = swr_alloc_set_opts(NULL,
codec_ctx->channel_layout, codec_ctx->sample_fmt, codec_ctx->sample_rate,
codec_ctx->channel_layout, AV_SAMPLE_FMT_S16, codec_ctx->sample_rate,
0, NULL);
if (!swr_ctx) {
fprintf(stderr, "Could not allocate resampler context");
exit(1);
}
/* initialize the resampler context */
if (swr_init(swr_ctx) < 0) {
fprintf(stderr, "Could not initialize resampler context");
exit(1);
}
/* allocate data pointers array for resampled data */
av_samples_alloc_array_and_samples(&resampled_data, &resampled_linesize, codec_ctx->channels,
10000, AV_SAMPLE_FMT_S16, 0);
/* open the output file */
if (avformat_alloc_output_context2(&output_fmt_ctx, NULL, NULL, argv[2]) < 0) {
fprintf(stderr, "Could not allocate output format context");
exit(1);
}
/* create new audio stream in output file */
AVStream *out_stream = avformat_new_stream(output_fmt_ctx, NULL);
if (!out_stream) {
fprintf(stderr, "Could not create new audio stream in output file");
exit(1);
}
/* copy codec parameters from input to output stream */
out_stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
out_stream->codecpar->codec_id = codec->id;
out_stream->codecpar->bit_rate = codec_ctx->bit_rate;
out_stream->codecpar->sample_rate = codec_ctx->sample_rate;
out_stream->codecpar->channels = codec_ctx->channels;
out_stream->codecpar->channel_layout = codec_ctx->channel_layout;
avcodec_parameters_to_context(out_stream->codec, out_stream->codecpar);
avio_open(&output_fmt_ctx->pb, argv[2], AVIO_FLAG_WRITE);
/* write header to output file */
avformat_write_header(output_fmt_ctx, NULL);
/* initialize packet */
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
/* read frames from input file, resample and write to output file */
while (av_read_frame(input_fmt_ctx, &packet) >= 0) {
if (packet.stream_index == stream_index) {
/* decode audio frame */
ret = avcodec_send_packet(codec_ctx, &packet);
if (ret < 0) {
fprintf(stderr, "Error decoding audio frame");
break;
}
while (ret >= 0) {
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate audio frame");
break;
}
/* get decoded audio frame */
ret = avcodec_receive_frame(codec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
av_frame_free(&frame);
break;
} else if (ret < 0) {
fprintf(stderr, "Error decoding audio frame");
av_frame_free(&frame);
break;
}
/* resample audio frame */
ret = swr_convert(swr_ctx, resampled_data, frame->nb_samples,
(const uint8_t **)frame->data, frame->nb_samples);
if (ret < 0) {
fprintf(stderr, "Error resampling audio frame");
av_frame_free(&frame);
break;
}
/* write resampled data to output file */
for (i = 0; i < frame->nb_samples; i++)
fwrite(resampled_data[0] + i * 2, 1, 2, output_fmt_ctx->pb);
av_frame_free(&frame);
}
}
/* free packet */
av_packet_unref(&packet);
}
/* flush resampler */
while (1) {
ret = swr_convert(swr_ctx, resampled_data, AUDIO_REFILL_THRESH,
NULL, 0);
if (ret < 0) {
fprintf(stderr, "Error flushing resampler");
break;
}
fwrite(resampled_data[0], 1, ret * 2, output_fmt_ctx->pb);
if (ret < AUDIO_REFILL_THRESH)
break;
}
/* write trailer to output file */
av_write_trailer(output_fmt_ctx);
/* close output file */
avio_closep(&output_fmt_ctx->pb);
/* free resources */
avformat_close_input(&input_fmt_ctx);
if (output_fmt_ctx && !(output_fmt_ctx->oformat->flags & AVFMT_NOFILE))
avio_closep(&output_fmt_ctx->pb);
avformat_free_context(output_fmt_ctx);
avcodec_free_context(&codec_ctx);
swr_free(&swr_ctx);
av_freep(&resampled_data[0]);
av_freep(&resampled_data);
return 0;
}
```
注意:此示例只是一个基本示例,没有对错误处理进行详细说明,实际使用时需要进行更完善的错误处理。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)