因为论文的方向分了(是的,是分的,不是自己选的,个中原因一言难尽。研究生毕设,刚开始,12月份答辩,之前做的全是内容开发,虽然很绝望但是还是要一点点做,论文方向是HEVC的编码优化,目前没啥思路,看了一些文章,开题半年了各种事,总之是自己懒吧,吐槽一下,时间不够是一定的,但再拼一把估计能混过去哈哈,想想但是考研复习时第二遍高数在考前三天复习的,也是拖延症巅峰了。不说废话了,开始。PS:下个月中期,人啊,真的不能太拖延症,以后工作千万不能这么搞)

这期姑且算作第二期吧,第一期其实是雷前辈教学生们配置ffmpeg以及ffmpeg命令行的用法等等。过后补
直接上ffmpeg播放视频的代码

/*** 最简单的基于FFmpeg的解码器* Simplest FFmpeg Decoder** 雷霄骅 Lei Xiaohua* leixiaohua1020@126.com* 中国传媒大学/数字电视技术* Communication University of China / Digital TV Technology* http://blog.csdn.net/leixiaohua1020** 本程序实现了视频文件的解码(支持HEVC,H.264,MPEG2等)。* 是最简单的FFmpeg视频解码方面的教程。* 通过学习本例子可以了解FFmpeg的解码流程。* This software is a simplest video decoder based on FFmpeg.* Suitable for beginner of FFmpeg.**/#include <stdio.h>
#include <iostream>
#define __STDC_CONSTANT_MACROS       //FFmpeg自己规定必须加的一句extern "C"//ffmpeg用C语言写,但是本程序是在C++中运行,因此需要用到extern
{
#include "libavcodec/avcodec.h"      //编解码库
#include "libavformat/avformat.h"    //封装格式处理
#include "libswscale/swscale.h"      //YUV解码后会有黑边区域,用sws.scale函数裁剪。视频像素数据格式转换
/*
#include "libavfilter/avfilter.h"    //滤镜特效处理
#include "libavdevice/avdevice.h"    //各种设备的输入输出
#include "libavutil/avutil.h"        //工具库(大部分库都需要这个库的支持)
#include "libpostproc/postprocess.h" //后加工
#include "libswresample/swresample.h"//音频采样数据格式转换
*/
};int main(int argc, char* argv[])
{AVFormatContext    *pFormatCtx;          //封装格式信息int               i, videoindex;        //AVCodecContext  *pCodecCtx;           //编码格式信息AVCodec           *pCodec;              //编码信息AVFrame *pFrame,*pFrameYUV;           //图像数据uint8_t *out_buffer;                  //AVPacket *packet;                     //码流数据int y_size;                           //Y(亮度)数据的尺寸int ret, got_picture;                 //struct SwsContext *img_convert_ctx;   //裁剪的信息//输入文件路径char filepath[]="Titanic.ts";int frame_cnt;                        //做循环解码帧用的计数,初始为零,等到达到总帧数停止//注册所有组件av_register_all();//初始化网络avformat_network_init();//初始化格式上下文,创建了一个供储存的封装格式信息的空间pFormatCtx = avformat_alloc_context();//判断输入文件是否有效.avformat_open_input():打开输入视频文件if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){printf("Couldn't open input stream.\n");return -1;}// avformat_find_stream_info():获取视频文件信息if(avformat_find_stream_info(pFormatCtx,NULL)<0){printf("Couldn't find stream information.\n");return -1;}//获取视频的stream的序号videoindex=-1;for(i=0; i<pFormatCtx->nb_streams; i++)                                    //nb_streams可以专门用来储存流的信息if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){videoindex=i;                                                      //视频流序号break;}if(videoindex==-1){printf("Didn't find a video stream.\n");return -1;}pCodecCtx=pFormatCtx->streams[videoindex]->codec;//avcodec_find_decoder():查找与视频编码格式对应的解码器。pCodec=avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec==NULL){printf("Codec not found.\n");return -1;}//avcodec_open2():打开解码器。 在这里打开之后才能采集后面所需的信息if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){printf("Could not open codec.\n");return -1;}/** 在此处添加输出视频信息的代码* 取自于pFormatCtx,使用fprintf()*//*std::cout << pFormatCtx->duration << std::endl;system("pause");*///文件输出FILE *fp = fopen("info.txt", "wb+");//输出封装格式fprintf(fp, "封装格式:%s\n", pFormatCtx->iformat->name);//输出比特率fprintf(fp, "比特率:%d\n", pFormatCtx->bit_rate);//时长,单位是msfprintf(fp,"时长:%dms\n", pFormatCtx->duration);//输出编码方式fprintf(fp, "编码方式:%d\n", pCodec->id);//输出长名称,即格式的长名称fprintf(fp,"长名称:%s\n", pFormatCtx->iformat->long_name);//输出视频的宽和高fprintf(fp,"宽:%d,高:%d\n", pFormatCtx->streams[videoindex]->codec->width, pFormatCtx->streams[videoindex]->codec->height);//单位是msprintf("时长:%dms\n", pFormatCtx->duration);//输出封装格式printf("封装格式:%s", pFormatCtx->iformat->name);//输出长名称,即格式的长名称printf("长名称:%s", pFormatCtx->iformat->long_name);//输出视频的宽和高printf("宽:%d,高:%d", pFormatCtx->streams[videoindex]->codec->width, pFormatCtx->streams[videoindex]->codec->height);//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>pFrame=av_frame_alloc();                                                                                    //取图像数据赋给内存pFrameYUV=av_frame_alloc();                                                                                    //取YUV图像数据赋给内存out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));  //avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);packet=(AVPacket *)av_malloc(sizeof(AVPacket));//Output Info-----------------------------printf("--------------- File Information ----------------\n");av_dump_format(pFormatCtx,0,filepath,0);                           //打印基本信息printf("-------------------------------------------------\n");img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); //创建文件两种格式的文件,为了储存做准备FILE *fp_264 = fopen("test264.h264", "wb+");FILE *fp_yuv = fopen("test_yuv.yuv", "wb+");//解码数据在最后做了一个循环,frame_cnt=0;while(av_read_frame(pFormatCtx, packet)>=0){    //取帧if(packet->stream_index==videoindex){      //判断是否是视频帧/** 在此处添加输出H264码流的代码* 取自于packet,使用fwrite()*/fwrite(packet->data,1,packet->size,fp_264);//解码前视频帧参数:帧大小,码流,即在AVPacket里fprintf(fp, "第%d帧packet大小:%d\n", frame_cnt, packet->size);//解码后视频帧参数:帧类型,图像,即在AVFrame里fprintf(fp, "第%d帧frame类型:%d\n", frame_cnt, pFrame->pict_type);//avcodec_decode_video2():解码一帧压缩数据。ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);if(ret < 0){printf("Decode Error.\n");return -1;}//裁剪黑边,YUV格式的帧会有黑边,实际的linesize比width要宽(考虑写入的时候不写完全)if(got_picture){sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);printf("Decoded frame index: %d\n",frame_cnt);/** 在此处添加输出YUV的代码* 取自于pFrameYUV,使用fwrite()*/fwrite(pFrameYUV->data[0], 1, pCodecCtx->width*pCodecCtx->height, fp_yuv);     //data有三组数据,依次是YUV。写入Y数据fwrite(pFrameYUV->data[1], 1, pCodecCtx->width*pCodecCtx->height/4, fp_yuv);   //写入U数据fwrite(pFrameYUV->data[2], 1, pCodecCtx->width*pCodecCtx->height/4, fp_yuv);   //写入Y数据frame_cnt++;}}av_free_packet(packet);}fclose(fp_264);fclose(fp_yuv);fclose(fp);//释放之前占据的内存sws_freeContext(img_convert_ctx);av_frame_free(&pFrameYUV);av_frame_free(&pFrame);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);//system("pause");return 0;
}

按雷前辈在ppt里留的任务做了修改。欢迎来看的各位指正。

学雷前辈暑期小学期课简单视频播放器制作笔记(二)相关推荐

  1. CUGBACM22级暑假小学期训练-简单构造

    CUGBACM22级暑假小学期训练-简单构造 这Typora打到9000多字就开始卡了,难绷 A - Gardener and the Capybaras (hard version) 题意:给一个字 ...

  2. MediaPlayer+TextureView,完美切换全屏、小窗口的 Android 视频播放器

    NiceVieoPlayer 项目地址:xiaoyanger0825/NiceVieoPlayer  简介:MediaPlayer+TextureView,完美切换全屏.小窗口的 Android 视频 ...

  3. android 实现视频播放功能,android开发之简单视频播放器(VideoView)

    简单视频播放器的使用 一.简单使用videoView和MediaController实现播放控制 1.添加需要的权限 2.设置布局 android:id="@+id/main_video&q ...

  4. Opencv 简单视频播放器

    最近看了一下[1]_2011_OpenCV 2 Computer Vision Application Programming Cookbook.pdf,写了一个利用Opencv库实现的简单视频播放器 ...

  5. Android Studio——简单视频播放器

    1.界面分析 三个界面:主界面,视频列表界面,视频播放界面,如下图所示: 2.实现思路 (1)主界面设计 很简单,就一个背景和一个控件,然后为控件设置点击事件,然后跳转到视频列表界面 activity ...

  6. 微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义

    把录音的模块尝试过之后就想着微信小程序的视频播放会不会更有趣? 果然,微信小程序视频自带弹幕.是不是很爽,跟我一起来看看. 微信小程序开发之录音机 音频播放 动画 (真机可用) 先上gif: 再上几张 ...

  7. 轻松玩转Python:打开文件夹,搜索视频文件,实现简单视频播放器

    目录 1.功能描述: 2.具体实现: 3.代码实现: 4.执行效果: 1.功能描述: 这段代码实现了一个简单的视频播放器,可以打开指定的文件夹并搜索其中的视频文件,将搜索结果展示在列表框中,用户可以选 ...

  8. 2021-2022年小学期 程序设计开发实践 随堂笔记

    作者:筱柒_Littleseven 2022/08/08 Class1 对于数据结构的理解 首先对于程序编写和项目开发来说,主要的部分是对于数据的储存.处理分析的过程,而并非仅仅通过学习过的语法知识完 ...

  9. PyQt5 简单视频播放器

    文章目录 1.主要组件 2.功能代码 3.功能展示 4.如果播放不了 1.主要组件 QVideoWidget:这个类主要用作播放视频的控件 QMediaPlayer :实现媒体播放的类 2.功能代码 ...

最新文章

  1. 接入路由器做NAT,做限速的一些想法
  2. c++ 纯虚函数和抽象类那些事(二)实现抽象类
  3. .frm_.myd_myi转换为.sql导入mysql数据库_把.frm,.myd,myi转换为.sql导入数据库
  4. python decorator_python 中的decorator
  5. java错位_java – 如何保护自己免受参数错位的影响
  6. Lisp的本质(The Nature of Lisp)
  7. mysql-5.7 group commit 详解
  8. 3D博物馆虚拟纪念馆数字博览厅的“另类”展现方式
  9. 腾讯qq的授权管理查看页面
  10. 按步搭建简单IoT微服务(2)
  11. 把一个人的特点写具体作文_五年级把一个人的特点写具体的作文10篇
  12. 无线通信中的TD系统(TD-LTE)
  13. 航空爱好者自问自答(2)
  14. iOS oc 手机摇一摇震动带音效功能
  15. java基础语法入门到类型转换问题,运算符,数据输入,数组,方法概述,Debug模式,以及10个小案例的详细介绍。
  16. Ubuntu虚拟机中编译运行cgminer挖矿软件
  17. 【动画】【特效】 17种常用动画特效
  18. 计算机专业及各种证书考试,各种计算机认证考试的比较
  19. 科脉如何修改服务器名字,科脉云商助手服务器设置
  20. 甲骨文所见商代官职表

热门文章

  1. c# .net接口协定Contract
  2. postgresql11.2修改分区表中复合索引字段长度遇到的BUG
  3. java JDBC连接MySQL数据库调用存储过程进行查询
  4. 云顶之弈机器人怎么拉人_LOL云顶之弈10.16b机器人怎么玩_云顶之弈10.16b机器人装备站位_3DM网游...
  5. element中组件el-autocomplete远程搜索之精确匹配和模糊匹配
  6. 前端外行的微信小程序瞎折腾之旅
  7. QQ登录, 腾讯开放平台和QQ互联的坑
  8. 双链表初始化、头插、尾插、头删、尾删、任意位置插入和删除、判空、销毁、打印、查找操作
  9. LeetCode解题(1)----------8 字符串转换整数[go]
  10. 古月居《ROS入门21讲》零基础学习笔记