精选文章 ffmpeg:提取视频中的音频

ffmpeg:提取视频中的音频

作者:HFUTWXY 时间: 2019-11-07 10:16:39
HFUTWXY 2019-11-07 10:16:39

接上篇视频转图片,大致流程都是一样的。

这里仅列出不同的地方

1.获取音频流

    int audio_stream_index = -1;
	for (int i = 0; i < av_format_context->nb_streams; ++i) {
		if (av_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
		{
			audio_stream_index = i;
		}
	}

2.准备音频输出流,这里要注意不同格式的视频封装的音频是有区别,wmv视频的是wma

    const char *audio_path = "C:/Users/Public/Videos/Sample Videos/images/temp.aac";
	audio_format_context = avformat_alloc_context();
	AVOutputFormat *audio_out_format = av_guess_format(nullptr, audio_path, nullptr);
	if (!audio_out_format)
	{
		return -1;
	}
	audio_format_context->oformat = audio_out_format;
	//新建输出流
	AVStream *audio_stream = avformat_new_stream(audio_format_context, nullptr);
	if (!audio_stream)
	{
		return -1;
	}

3.拷贝参数信息,并打印音频流信息

    AVStream *in_audio_stream = av_format_context->streams[audio_stream_index];
	if (avcodec_parameters_copy(audio_stream->codecpar, in_audio_stream->codecpar) < 0)
	{
		printf("copy paramter failed \n");
	}
	audio_stream->codecpar->codec_tag = 0;
	if (avio_open(&audio_format_context->pb, audio_path, AVIO_FLAG_WRITE) < 0)
	{
		printf("open audio file failed \n");
		return -1;
	}
	av_dump_format(audio_format_context, 0, audio_path, 1);

4.下面开始写文件

4.1写文件头

    // 写头部信息
	if (avformat_write_header(audio_format_context, nullptr) < 0) {
		printf("写入头部信息失败!\n");
		return -1;
	}

4.2while循环写每一帧的音频数据

AVPacket *packet = av_packet_alloc();
	AVFrame *av_frame_in = av_frame_alloc();
	int decode_result = 0;

	int frame_count = 0;
	while (av_read_frame(av_format_context, packet) >= 0)
	{
		if (packet->stream_index == audio_stream_index)
		{
			packet->pts = av_rescale_q_rnd(packet->pts, in_audio_stream->time_base, audio_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
			packet->dts = av_rescale_q_rnd(packet->dts, in_audio_stream->time_base, audio_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
			packet->duration = av_rescale_q(packet->duration, in_audio_stream->time_base, audio_stream->time_base);
			packet->pos = -1;
			packet->stream_index = 0;
			//将包写到输出媒体文件
			av_interleaved_write_frame(audio_format_context, packet);
		}

		av_packet_unref(packet);
	}

4.3写尾部信息

//写尾部信息
av_write_trailer(audio_format_context);

4.5关闭文件

avio_close(audio_format_context->pb);

 

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:干货:论文读不懂怎么办?

下一篇:【phantomjs】爬虫安装使用

CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。