• Qt+FFmpeg+opengl从零制作视频播放器-2.环境搭建


    1.环境介绍

    Qt5.9.0+VS2017+ffmpeg4.4.3,这里版本均使用64位版本。

    Qt的版本大于我这个版本都行。

    opengl3.3,Qt已经封装好了QOpenGLWidget,直接使用Qt的就行。

    Qt版本下载:Index of /archive/qt

    2.ffmpeg下载

    Releases · BtbN/FFmpeg-Builds · GitHub

    解压后,里面的文件如下图所示,包含静态库、动态库、头文件。

    3.VS安装QT插件

    打开VS,选择工具->扩展和更新。

    选择联机->搜索Qt Visual Studio Tools,点击下载, 自动安装插件。

    安装完成之后,重启VS,在工具栏就会看见Qt VS Tools字样

     点击 Qt VS Tools->Qt Options->add,添加自己的Qt版本。

    4.配置ffmpeg

     选择Qt Widgets Application,新建VideoPlayer工程。

     新建3rd目录。

    将目录 2ffmpeg下载的文件解压出来,将所有文件拷贝到3rd目录下。

    右键打开配置环境

    常规->输出目录->修改生成程序目录

    调试->工作目录->修改  

    C/C++->附加包含目录->修改  

    链接器->附加库目录->修改 

    5.运行程序

    1. #include
    2. #include
    3. #include "MainWindow.h"
    4. #pragma execution_character_set("utf-8")
    5. extern "C"
    6. {
    7. #include "libavformat/avformat.h"
    8. #include "libavutil/dict.h"
    9. };
    10. int main(int argc, char *argv[])
    11. {
    12. QApplication a(argc, argv);
    13. //MainWindow w;
    14. //w.show();
    15. setlocale(LC_ALL,"zh_CN.UTF-8");
    16. AVFormatContext *pFormatCtx = NULL;
    17. AVCodecContext *pCodecCtx = NULL;
    18. AVCodec *pCodec;
    19. AVDictionaryEntry *dict = NULL;
    20. int iHour, iMinute, iSecond, iTotalSeconds;//HH:MM:SS
    21. int videoIndex, audioIndex;
    22. char fileName[] = "F:/1920x1080.mp4";
    23. if (avformat_open_input(&pFormatCtx, fileName, NULL, NULL) != 0)//打开输入视频文件
    24. {
    25. printf("Couldn't open input stream.\n");
    26. return -1;
    27. }
    28. if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
    29. {
    30. printf("Couldn't find stream information.\n");
    31. return -1;
    32. }
    33. videoIndex = -1;
    34. for (int i = 0; i < pFormatCtx->nb_streams; i++)
    35. {
    36. if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)//查找音频
    37. {
    38. videoIndex = i;
    39. break;
    40. }
    41. }
    42. if (videoIndex == -1)
    43. {
    44. printf("Couldn't find a video stream.\n");
    45. return -1;
    46. }
    47. pCodecCtx = avcodec_alloc_context3(NULL);
    48. if (pCodecCtx == NULL)
    49. {
    50. printf("Could not allocate AVCodecContext\n");
    51. return -1;
    52. }
    53. avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoIndex]->codecpar);
    54. pCodec = avcodec_find_decoder(pCodecCtx->codec_id); //指向AVCodec的指针.查找解码器
    55. if (pCodec == NULL)
    56. {
    57. printf("Codec not found.\n");
    58. return -1;
    59. }
    60. //打开解码器
    61. if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
    62. {
    63. printf("Could not open codec.\n");
    64. return -1;
    65. }
    66. audioIndex = -1;
    67. for (int i = 0; i < pFormatCtx->nb_streams; i++)
    68. {
    69. if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
    70. {
    71. audioIndex = i;
    72. break;
    73. }
    74. }
    75. if (audioIndex == -1)
    76. {
    77. printf("Couldn't find a audio stream.\n");
    78. return -1;
    79. }
    80. //打印结构体信息
    81. puts("AVFormatContext信息:");
    82. puts("---------------------------------------------");
    83. iTotalSeconds = (int)pFormatCtx->duration/ 1000000;
    84. iHour = iTotalSeconds / 3600;//小时
    85. iMinute = iTotalSeconds % 3600 / 60;//分钟
    86. iSecond = iTotalSeconds % 60;//秒
    87. printf("持续时间:%02d:%02d:%02d\n", iHour, iMinute, iSecond);
    88. printf("平均混合码率:%d kb/s\n", pFormatCtx->bit_rate / 1000);
    89. printf("视音频个数:%d\n", pFormatCtx->nb_streams);
    90. puts("---------------------------------------------");
    91. puts("AVInputFormat信息:");
    92. puts("---------------------------------------------");
    93. printf("封装格式名称:%s\n", pFormatCtx->iformat->name);
    94. printf("封装格式长名称:%s\n", pFormatCtx->iformat->long_name);
    95. printf("封装格式扩展名:%s\n", pFormatCtx->iformat->extensions);
    96. printf("封装格式ID:%d\n", pFormatCtx->iformat->raw_codec_id);
    97. puts("---------------------------------------------");
    98. puts("AVStream信息:");
    99. puts("---------------------------------------------");
    100. printf("视频流标识符:%d\n", pFormatCtx->streams[videoIndex]->index);
    101. printf("音频流标识符:%d\n", pFormatCtx->streams[audioIndex]->index);
    102. printf("视频流长度:%d微秒\n", pFormatCtx->streams[videoIndex]->duration);
    103. printf("音频流长度:%d微秒\n", pFormatCtx->streams[audioIndex]->duration);
    104. puts("---------------------------------------------");
    105. puts("AVCodecContext信息:");
    106. puts("---------------------------------------------");
    107. printf("视频码率:%d kb/s\n", pCodecCtx->bit_rate / 1000);
    108. printf("视频大小:%d * %d\n", pCodecCtx->width, pCodecCtx->height);
    109. puts("---------------------------------------------");
    110. puts("AVCodec信息:");
    111. puts("---------------------------------------------");
    112. printf("视频编码格式:%s\n", pCodec->name);
    113. printf("视频编码详细格式:%s\n", pCodec->long_name);
    114. puts("---------------------------------------------");
    115. printf("视频时长:%d微秒\n", pFormatCtx->streams[videoIndex]->duration);
    116. printf("音频时长:%d微秒\n", pFormatCtx->streams[audioIndex]->duration);
    117. printf("音频采样率:%d\n", pFormatCtx->streams[audioIndex]->codecpar->sample_rate);
    118. printf("音频信道数目:%d\n", pFormatCtx->streams[audioIndex]->codecpar->channels);
    119. puts("AVFormatContext元数据:");
    120. puts("---------------------------------------------");
    121. while (dict = av_dict_get(pFormatCtx->metadata, "", dict, AV_DICT_IGNORE_SUFFIX))
    122. {
    123. printf("[%s] = %s\n", dict->key, dict->value);
    124. }
    125. puts("---------------------------------------------");
    126. puts("AVStream视频元数据:");
    127. puts("---------------------------------------------");
    128. dict = NULL;
    129. while (dict = av_dict_get(pFormatCtx->streams[videoIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX))
    130. {
    131. printf("[%s] = %s\n", dict->key, dict->value);
    132. }
    133. puts("---------------------------------------------");
    134. puts("AVStream音频元数据:");
    135. puts("---------------------------------------------");
    136. dict = NULL;
    137. while (dict = av_dict_get(pFormatCtx->streams[audioIndex]->metadata, "", dict, AV_DICT_IGNORE_SUFFIX))
    138. {
    139. printf("[%s] = %s\n", dict->key, dict->value);
    140. }
    141. puts("---------------------------------------------");
    142. av_dump_format(pFormatCtx, -1, fileName, 0);
    143. printf("\n\n编译信息:\n%s\n\n", avcodec_configuration());
    144. avcodec_free_context(&pCodecCtx);
    145. //avcodec_close(pCodecCtx);
    146. avformat_close_input(&pFormatCtx);
    147. system("pause");
    148. return a.exec();
    149. }

    运行结果 

    6.ffmpeg库下载

    https://download.csdn.net/download/wzz953200463/88883243

  • 相关阅读:
    读书笔记-你不知道的js(中卷)
    被领导拒绝涨薪申请,跳槽后怒涨9.5K,这是我的心路历程
    Java获取随机数
    Day 47、48 操作系统的运行机制与体系结构
    JVM 内存管理 你知道多少
    idea 集成git后一些场景的使用方法
    nodejs+vue+elementui寻医问药网站
    登录成功后跳转到之前打开的页面
    python控制负数以16进制整型格式输出
    云原生应用安全
  • 原文地址:https://blog.csdn.net/wzz953200463/article/details/136331554