ffmpeg-3.1.5视频+音频解码代码
2016-11-06 21:55
375 查看
之前文章中的代码只能解码视频数据,本文在之前的基础上加入了解码音频数据部分。
与之前只能解码视频的代码相比,本文代码增加了audioCodecCtx和audioCodec的处理部分、循环解码音频流的部分、和音频输出文件的设置部分。
解码后的音频为PCM格式,可以使用“audacity”软件进行分析。需要注意的是,在使用“audacity”软件分析PCM码流时,要通过“文件->导入->裸数据”的方法导入.pcm文件,而不要使用“文件->打开”的方式打开该文件。
上代码。
与之前只能解码视频的代码相比,本文代码增加了audioCodecCtx和audioCodec的处理部分、循环解码音频流的部分、和音频输出文件的设置部分。
解码后的音频为PCM格式,可以使用“audacity”软件进行分析。需要注意的是,在使用“audacity”软件分析PCM码流时,要通过“文件->导入->裸数据”的方法导入.pcm文件,而不要使用“文件->打开”的方式打开该文件。
上代码。
#include <stdio.h> extern "C" { #include "include\libavcodec\avcodec.h" #include "include\libavformat\avformat.h" #include "include\libavutil\imgutils.h" }; #define __STDC_CONSTANT_MACROS int _tmain(int argc, _TCHAR* argv[]) { //printf("%s", avcodec_configuration()); AVFormatContext *formatctx; AVCodec *videoCodec; AVCodec *audioCodec; AVCodecContext *videoCodecctx = NULL; AVCodecContext *audioCodecctx = NULL; AVFrame *frame; AVFrame *frameYUV; AVPacket avpkt; AVPacket *pavpkt = &avpkt; //init av_register_all(); avformat_network_init(); formatctx = avformat_alloc_context(); //输入文件路径 char *fileName = "Titanic.ts"; if (avformat_open_input(&formatctx,fileName,NULL,NULL)!=0) { printf("could not open input stream.\n"); return -1; } if (avformat_find_stream_info(formatctx, NULL) < 0) { printf("could not find stream information.\n"); return -1; } //output file FILE *outputfile_video = nullptr; FILE *outputfile_audio = nullptr; char *outputfilename_video = "output_video.yuv"; char *outputfilename_audio = "output_audio.pcm"; fopen_s(&outputfile_video, outputfilename_video, "wb"); fopen_s(&outputfile_audio, outputfilename_audio, "wb"); //==============video================ //find videoindex int videoindex = av_find_best_stream(formatctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (videoindex < 0) { printf("could not find a video stream.\n"); return -1; } //find the video decoder videoCodecctx = avcodec_alloc_context3(NULL); if (videoCodecctx == NULL) { printf("could not allocate video AVCodecContext.\n"); return -1; } avcodec_parameters_to_context(videoCodecctx, formatctx->streams[videoindex]->codecpar); videoCodec = avcodec_find_decoder(videoCodecctx->codec_id); if (videoCodec == NULL) { printf("vidoe codec not found.\n"); return -1; } //open the video decoder if (avcodec_open2(videoCodecctx, videoCodec, NULL) < 0) { printf("could not open video codec.\n"); return -1; } //===================================== //================audio=================== //find audioindex int audioindex = av_find_best_stream(formatctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); if (audioindex < 0) { printf("could not find a audio stream.\n"); return -1; } //find the audio decoder audioCodecctx = avcodec_alloc_context3(NULL); if (audioCodecctx == NULL) { printf("could not allocate audio AVCodecContext.\n"); return -1; } avcodec_parameters_to_context(audioCodecctx, formatctx->streams[audioindex]->codecpar); audioCodec = avcodec_find_decoder(audioCodecctx->codec_id); if (audioCodec == NULL) { printf("audio codec not found.\n"); return -1; } //open the audio decoder if (avcodec_open2(audioCodecctx, audioCodec, NULL) < 0) { printf("could not open audio codec.\n"); return -1; } //======================================== //output information printf("---------------- File Information --------------\n"); av_dump_format(formatctx, videoindex, fileName, 0); printf("------------------------------------------------\n"); //pre decode av_init_packet(&avpkt); frame = av_frame_alloc(); frameYUV = av_frame_alloc(); int video_dst_bufsize = av_image_alloc((uint8_t**)frameYUV->data, frameYUV->linesize, videoCodecctx->width, videoCodecctx->height, videoCodecctx->pix_fmt, 1); printf("decode video file %s to %s and %s\n", fileName, outputfilename_video, outputfilename_audio); //decode int frame_count = 0; while (av_read_frame(formatctx,pavpkt)>=0) { if (pavpkt->stream_index == videoindex) { if (avcodec_send_packet(videoCodecctx, pavpkt) != 0){ printf("input AVPacket to video decoder failed!\n"); return -1; } while (0 == avcodec_receive_frame(videoCodecctx, frame)){ av_image_copy((uint8_t **)frameYUV->data,frameYUV->linesize,(const uint8_t **)frame->data,frame->linesize,videoCodecctx->pix_fmt,videoCodecctx->width,videoCodecctx->height); fwrite(frameYUV->data[0], 1, video_dst_bufsize, outputfile_video); printf("decoded frame index: %d\n", frame_count); frame_count++; } } else if (pavpkt->stream_index == audioindex) { if (avcodec_send_packet(audioCodecctx, pavpkt) != 0){ printf("input AVPacket to audio decoder failed!\n"); return -1; } while (0 == avcodec_receive_frame(audioCodecctx, frame)){ size_t unpadded_linesize = frame->nb_samples*av_get_bytes_per_sample((AVSampleFormat)frame->format); fwrite(frame->extended_data[0], 1, unpadded_linesize, outputfile_audio); printf("decoded audio.\n"); } } av_packet_unref(pavpkt); } fclose(outputfile_video); fclose(outputfile_audio); av_frame_free(&frame); av_frame_free(&frameYUV); avcodec_close(videoCodecctx); avcodec_close(audioCodecctx); avformat_close_input(&formatctx); return 0; }
相关文章推荐
- ffmpeg-3.1.5视频解码代码
- FFmpeg 视频、音频编解码的例子
- 一段ffmpeg视频解码为YUV420P的示例代码
- ffmpeg / avconv是通用的视频/音频编解码命令行工具
- 分享代码,用QtMultimedia类播放ffmpeg解码的音频
- FFmpeg开源代码中的视频/音频编解码
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- 利用ffmpeg来进行视频解码的完整示例代码(H.264)
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- iPhone调用ffmpeg2.0.2解码h264视频的示例代码
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- libav/FFMPEG 视频音频编解码库使用
- 利用ffmpeg来进行视频解码的完整示例代码(H.264)
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(2)
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- 音视频编解码问题:javaCV如何快速进行音频预处理和解复用编解码(基于javaCV-FFMPEG)
- FFmpeg支持的音频和视频编解码格式
- ffmpeg代码笔记2:如何判断MP4文件里面的流是音频还是视频流