ffmpeg播放音视频文件(ffmpeg-3.2.4-win32-dev版本)

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "swscale.lib")
#pragma comment(lib, "swresample.lib")

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
}

#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio

int main()
{
//1.注册组件
av_register_all();
//封装格式上下文
AVFormatContext *pFormatCtx = avformat_alloc_context();
//2.打开输入音频文件
const char *input_file_name = "d:\\ts.ts";
if (avformat_open_input(&pFormatCtx, input_file_name, NULL, NULL) != 0) {
printf("%s", "打开输入音频文件失败");
return -1;
}
//3.获取音频信息
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
printf("%s", "获取音频信息失败");
return -1;
}

int i, videoStream, audioStream, nRet;
// Find the first video stream
videoStream = -1;
audioStream = -1;
for (i = 0; i < pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
}
else if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = i;
}
}

if (videoStream == -1)
{
return -1;
}

AVCodecContext *pVideoCodecCtx = pFormatCtx->streams[videoStream]->codec;
AVCodec *pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);

AVCodecContext *pAudioCodecCtx = pFormatCtx->streams[audioStream]->codec;
AVCodec *pAudioCodec = avcodec_find_decoder(pAudioCodecCtx->codec_id);


//通知解码器,我们能处理截断的bit流
if (pVideoCodec->capabilities&CODEC_CAP_TRUNCATED)
{
pVideoCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
}

//打开视频解码器
if (avcodec_open2(pVideoCodecCtx, pVideoCodec, NULL) < 0)
{
printf("%s", "编码器无法打开");
return -1;
}

//通知解码器,我们能处理截断的bit流
if (pAudioCodec->capabilities&CODEC_CAP_TRUNCATED)
{
pAudioCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
}

//打开音频解码器
if (avcodec_open2(pAudioCodecCtx, pAudioCodec, NULL) < 0)
{
return -1;
}

//音频频参数
uint8_t *pktdata;
int pktsize;
int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
uint8_t * audio_out_buf = (uint8_t *)malloc(out_size);
//frame->16bit 44100 PCM 统一音频采样格式与采样率
SwrContext *swrCtxAudio = swr_alloc();
//重采样设置选项-----------------------------------------------------------start
//输入的采样格式
enum AVSampleFormat in_sample_fmt = pAudioCodecCtx->sample_fmt;
//输出的采样格式 16bit PCM
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
//输入的采样率
int in_sample_rate = pAudioCodecCtx->sample_rate;
//输出的采样率
int out_sample_rate = 44100;
//输入的声道布局
uint64_t in_ch_layout = pAudioCodecCtx->channel_layout;
//输出的声道布局
uint64_t out_ch_layout = AV_CH_LAYOUT_MONO;
//重采样设置选项
swr_alloc_set_opts(swrCtxAudio, out_ch_layout, out_sample_fmt, out_sample_rate, in_ch_layout, in_sample_fmt, in_sample_rate, 0, NULL);
swr_init(swrCtxAudio);
//获取输出的声道个数
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);
FILE *fp_pcm = fopen("d:\\out.pcm", "wb");
//视频参数
int y_size;
FILE *fp_yuv = fopen("d:\\out.yuv", "wb+");
struct SwsContext *swrCtxVideo;
AVFrame *pFrameYUV;
pFrameYUV = av_frame_alloc();
uint8_t * video_out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pVideoCodecCtx->width, pVideoCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, video_out_buffer, AV_PIX_FMT_YUV420P, pVideoCodecCtx->width, pVideoCodecCtx->height);
swrCtxVideo = sws_getContext(pVideoCodecCtx->width, pVideoCodecCtx->height, pVideoCodecCtx->pix_fmt,
pVideoCodecCtx->width, pVideoCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

//开始解码
int nGopPicture = 1;
AVFrame *pFrame = av_frame_alloc();
AVPacket pktData;
av_init_packet(&pktData);
while (av_read_frame(pFormatCtx, &pktData) >= 0)
{
if (pktData.stream_index == videoStream)
{
nRet = avcodec_decode_video2(pVideoCodecCtx, pFrame, &nGopPicture, &pktData);
if (nRet < 0){
printf("Decode Error.\n");
return -1;
}
if (nGopPicture){
sws_scale(swrCtxVideo, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pVideoCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
y_size = pVideoCodecCtx->width * pVideoCodecCtx->height;
fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv); //Y
fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv); //U
fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv); //V
}
}
else if (pktData.stream_index == audioStream)
{
//解码AVPacket->AVFrame
nRet = avcodec_decode_audio4(pAudioCodecCtx, pFrame, &nGopPicture, &pktData);
if (nRet < 0) {
printf("Decode Error.\n");
return -1;
}

//非0,正在解码
if (nGopPicture) {
swr_convert(swrCtxAudio, &audio_out_buf, AVCODEC_MAX_AUDIO_FRAME_SIZE, (const uint8_t **)pFrame->data, pFrame->nb_samples);
//获取sample的size
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel_nb, pFrame->nb_samples,
out_sample_fmt, 1);
//写入文件进行测试
fwrite(audio_out_buf, 1, out_buffer_size, fp_pcm);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&pktData);
}


fclose(fp_yuv);
fclose(fp_pcm);
av_frame_free(&pFrame);
av_free(audio_out_buf);
av_free(video_out_buffer);
swr_free(&swrCtxAudio);
avcodec_close(pAudioCodecCtx);
avcodec_close(pVideoCodecCtx);
avformat_close_input(&pFormatCtx);
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值