接上篇视频转图片,大致流程都是一样的。
这里仅列出不同的地方
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);