介绍

  • 简单的多屏播放器
  • 最多同时播放16个视频
  • 支持本地文件和rtsp、rtmp等流媒体播放
  • VS2015工程,依赖Qt+VLC
  • 练手作品

截图


下载

程序:download.csdn.net/detail/u014755412/9908787

源码:github.com/FutaAlice/QtPlayer


代码分析

IMediaPlayer是为规定接口的基类
提供了播放和控制的几个常用函数
其中打开媒体部分拆分为了OpenURL和OpenFile,并在cpp中实现
若为Windows环境,则对QFileDialog获取的路径进行替换

  1. /*******************************************************************
  2. IMediaPlayer.h(接口类)
  3. 构造时传入QWidget*
  4. 调用OpenFile或OpenURL或Open打开文件并渲染窗体
  5. *******************************************************************/
  6. #ifndef IMEDIAPLAYER_H
  7. #define IMEDIAPLAYER_H
  8. class QWidget;
  9. class IMediaPlayer
  10. {
  11. public:
  12. IMediaPlayer(QWidget* pWidget);
  13. virtual ~IMediaPlayer();
  14. virtual bool OpenFile();
  15. virtual bool OpenURL(const char* url);
  16. virtual bool Open(const char* url) = 0;
  17. virtual bool Play() = 0;
  18. virtual void Pause() = 0;
  19. virtual void Stop() = 0;
  20. virtual void ChangeVolume(int vol) = 0;
  21. protected:
  22. QWidget* m_pWidget;
  23. };
  24. #endif // IMEDIAPLAYER_H
  1. /*******************************************************************
  2. IMediaPlayer.cpp(接口类)
  3. *******************************************************************/
  4. #include "IMediaPlayer.h"
  5. #include <QtWidgets/QWidget>
  6. #include <QtWidgets/qfiledialog.h>
  7. // Windows环境下进行字符替换
  8. static void StrReplace(QString& str)
  9. {
  10. #if defined(Q_OS_MAC) // Mac
  11. #elif defined(Q_OS_UNIX) // Linux
  12. #elif defined(Q_OS_WIN) // Windows
  13. str = str.replace(QRegExp("/"), "\\");
  14. #endif
  15. }
  16. IMediaPlayer::IMediaPlayer(QWidget* pWidget)
  17. : m_pWidget(pWidget)
  18. {
  19. }
  20. IMediaPlayer::~IMediaPlayer()
  21. {
  22. }
  23. bool IMediaPlayer::OpenFile()
  24. {
  25. QString fileOpen = QFileDialog::getOpenFileName(NULL, "Load a file", "~");
  26. if (!fileOpen.isEmpty())
  27. {
  28. StrReplace(fileOpen);
  29. return Open(fileOpen.toUtf8().constData());
  30. }
  31. else
  32. return false;
  33. }
  34. bool IMediaPlayer::OpenURL(const char * url)
  35. {
  36. return Open(url);
  37. }

之后新建一个派生自IMediaPlayer的类:VlcMediaPlayer,
并使用libvlc实现其基类中的纯虚函数实现视频的播放

  1. /*******************************************************************
  2. VlcMediaPlayer.h
  3. 使用libvlc实现的IMediaPlayer
  4. 构造时传入QWidget*
  5. 调用OpenFile或OpenURL或Open打开文件并渲染窗体
  6. 例如:
  7. QWidget* pWidget = new QOpenGLWidget();
  8. pWidget->show();
  9. auto player = new VlcMediaPlayer(pWidget);
  10. player->Open("test.hevc");
  11. *******************************************************************/
  12. #ifndef VLCMEDIAPLAYER_H
  13. #define VLCMEDIAPLAYER_H
  14. #include "IMediaPlayer.h"
  15. struct libvlc_media_player_t;
  16. struct libvlc_instance_t;
  17. class VlcMediaPlayer :
  18. public IMediaPlayer
  19. {
  20. public:
  21. VlcMediaPlayer(QWidget* pWidget);
  22. ~VlcMediaPlayer();
  23. // 禁用拷贝构造和赋值
  24. VlcMediaPlayer(const VlcMediaPlayer&) = delete;
  25. VlcMediaPlayer& operator=(VlcMediaPlayer&) = delete;
  26. // Control
  27. virtual bool Open(const char* url);
  28. virtual bool Play();
  29. virtual void Pause();
  30. virtual void Stop();
  31. virtual void ChangeVolume(int vol) ;
  32. private:
  33. // 播放器对象
  34. libvlc_media_player_t *m_pVlcPlayer;
  35. private:
  36. // libvlc实例,所有窗体的渲染共用一个
  37. static libvlc_instance_t *s_pVlcInstance;
  38. static unsigned int s_ref;
  39. };
  40. #endif // VLCMEDIAPLAYER_H
  1. /*******************************************************************
  2. VlcMediaPlayer.cpp
  3. libvlc播放视频的实现
  4. *******************************************************************/
  5. #include "VlcMediaPlayer.h"
  6. #include <assert.h>
  7. #include <QtWidgets/QWidget>
  8. # ifdef __cplusplus
  9. extern "C" {
  10. # endif
  11. #include <vlc/vlc.h>
  12. # ifdef __cplusplus
  13. }
  14. # endif
  15. #if defined(Q_OS_MAC) // Mac
  16. // TODO
  17. #elif defined(Q_OS_UNIX) // Linux
  18. #pragma comment(lib, "libvlc.a")
  19. #elif defined(Q_OS_WIN) // Windows
  20. #pragma comment(lib, "libvlc.lib")
  21. #endif
  22. unsigned int VlcMediaPlayer::s_ref = 0;
  23. libvlc_instance_t *VlcMediaPlayer::s_pVlcInstance = NULL;
  24. VlcMediaPlayer::VlcMediaPlayer(QWidget* pWidget)
  25. : IMediaPlayer(pWidget)
  26. , m_pVlcPlayer(NULL)
  27. {
  28. /* Initialize libVLC */
  29. if (0 == s_ref++)
  30. {
  31. s_pVlcInstance = libvlc_new(0, NULL);
  32. if (NULL == s_pVlcInstance)
  33. {
  34. assert(false);
  35. }
  36. }
  37. }
  38. VlcMediaPlayer::~VlcMediaPlayer()
  39. {
  40. if (0 == --s_ref)
  41. {
  42. libvlc_release(s_pVlcInstance);
  43. }
  44. }
  45. bool VlcMediaPlayer::Open(const char *url)
  46. {
  47. /* Stop if something is playing */
  48. Stop();
  49. auto funcOpen = libvlc_media_new_path;
  50. if (QString(url).startsWith("rtsp://") ||
  51. QString(url).startsWith("rtmp://") ||
  52. QString(url).startsWith("rtp://") ||
  53. QString(url).startsWith("tcp://") ||
  54. QString(url).startsWith("udp://") ||
  55. QString(url).startsWith("ftp://") ||
  56. QString(url).startsWith("http://") ||
  57. QString(url).startsWith("https://"))
  58. {
  59. funcOpen = libvlc_media_new_location;
  60. }
  61. /* Create a new Media */
  62. libvlc_media_t *vlcMedia = funcOpen(s_pVlcInstance, url);
  63. /* Fail to open url*/
  64. if (!vlcMedia)
  65. {
  66. return false;
  67. }
  68. if (QString(url).endsWith(".hevc"))
  69. libvlc_media_add_option(vlcMedia, ":demux=hevc");
  70. else if (QString(url).endsWith("rtsp"))
  71. libvlc_media_add_option(vlcMedia, ":rtsp-tcp");
  72. /* Create a new libvlc player */
  73. m_pVlcPlayer = libvlc_media_player_new_from_media(vlcMedia);
  74. /* Release the media */
  75. libvlc_media_release(vlcMedia);
  76. return Play();
  77. }
  78. bool VlcMediaPlayer::Play()
  79. {
  80. /* Integrate the video in the interface */
  81. #if defined(Q_OS_MAC)
  82. libvlc_media_player_set_nsobject(m_pVlcPlayer, (void*)m_pWidget->winId());
  83. #elif defined(Q_OS_UNIX)
  84. libvlc_media_player_set_xwindow(m_pVlcPlayer, m_pWidget->winId());
  85. #elif defined(Q_OS_WIN)
  86. libvlc_media_player_set_hwnd(m_pVlcPlayer, (void*)m_pWidget->winId());
  87. #endif
  88. /* And start playback */
  89. int vlc_ret = libvlc_media_player_play(m_pVlcPlayer);
  90. if (0 == vlc_ret)
  91. return true;
  92. else
  93. return false;
  94. }
  95. void VlcMediaPlayer::Pause()
  96. {
  97. if (m_pVlcPlayer && libvlc_media_player_is_playing(m_pVlcPlayer))
  98. {
  99. libvlc_media_player_pause(m_pVlcPlayer);
  100. }
  101. }
  102. void VlcMediaPlayer::Stop()
  103. {
  104. if (m_pVlcPlayer)
  105. {
  106. /* stop the media player */
  107. libvlc_media_player_stop(m_pVlcPlayer);
  108. /* release the media player */
  109. libvlc_media_player_release(m_pVlcPlayer);
  110. /* Reset application values */
  111. m_pVlcPlayer = NULL;
  112. }
  113. }
  114. void VlcMediaPlayer::ChangeVolume(int vol)
  115. {
  116. if (m_pVlcPlayer)
  117. {
  118. libvlc_audio_set_volume(m_pVlcPlayer, vol);
  119. }
  120. }

界面部分,
响应界面按钮点击的消息和调整窗体大小的消息,
并且调用VlcMediaPlayer添加播放视频的小窗口

  1. /*******************************************************************
  2. QtPlayer.h
  3. *******************************************************************/
  4. #pragma once
  5. #include <QtWidgets/QWidget>
  6. #include "ui_QtPlayer.h"
  7. struct libvlc_media_player_t;
  8. class QtPlayer : public QWidget
  9. {
  10. Q_OBJECT
  11. public:
  12. QtPlayer(QWidget *parent = Q_NULLPTR);
  13. void resizeEvent(QResizeEvent* e);
  14. private slots:
  15. void openFile();
  16. void openURL();
  17. private:
  18. Ui::QtPlayerClass ui;
  19. QWidget* m_pSubWidgets[16];
  20. };
  1. /*******************************************************************
  2. QtPlayer.cpp
  3. *******************************************************************/
  4. #include "QtPlayer.h"
  5. #include "VlcMediaPlayer.h"
  6. QtPlayer::QtPlayer(QWidget *parent)
  7. : QWidget(parent)
  8. {
  9. ui.setupUi(this);
  10. memset(m_pSubWidgets, NULL, sizeof(m_pSubWidgets));
  11. }
  12. void QtPlayer::openFile()
  13. {
  14. int w = width() / 4, h = (height() - 24) / 4;
  15. for (int i = 0; i < 16; ++i)
  16. {
  17. if (m_pSubWidgets[i] == NULL)
  18. {
  19. m_pSubWidgets[i] = new QWidget(this);
  20. auto player = new VlcMediaPlayer(m_pSubWidgets[i]);
  21. // 打开成功
  22. if (player->OpenFile())
  23. {
  24. resizeEvent(NULL);
  25. m_pSubWidgets[i]->show();
  26. }
  27. else
  28. {
  29. delete player;
  30. delete m_pSubWidgets[i];
  31. m_pSubWidgets[i] = NULL;
  32. }
  33. break;
  34. }
  35. }
  36. }
  37. void QtPlayer::resizeEvent(QResizeEvent *e)
  38. {
  39. int w = width() / 4, h = (height() - 24) / 4;
  40. for (int i = 0; i < 16; ++i)
  41. {
  42. if (NULL == m_pSubWidgets[i])
  43. continue;
  44. m_pSubWidgets[i]->resize(QSize(w, h));
  45. m_pSubWidgets[i]->move(QPoint((i % 4) * w, (i / 4) * h));
  46. }
  47. QPoint pos = ui.btnOpenFile->pos();
  48. pos.setY(height() - 24);
  49. ui.btnOpenFile->move(pos);
  50. pos = ui.btnOpenURL->pos();
  51. pos.setY(height() - 24);
  52. ui.btnOpenURL->move(pos);
  53. pos = ui.lineEdit->pos();
  54. pos.setY(height() - 24);
  55. ui.lineEdit->move(pos);
  56. }
  57. void QtPlayer::openURL()
  58. {
  59. int w = width() / 4, h = height() / 4;
  60. for (int i = 0; i < 16; ++i)
  61. {
  62. if (m_pSubWidgets[i] == NULL)
  63. {
  64. m_pSubWidgets[i] = new QWidget(this);
  65. auto player = new VlcMediaPlayer(m_pSubWidgets[i]);
  66. // 打开成功
  67. if (player->OpenURL(ui.lineEdit->text().toUtf8().constData()))
  68. {
  69. resizeEvent(NULL);
  70. m_pSubWidgets[i]->show();
  71. }
  72. else
  73. {
  74. delete player;
  75. delete m_pSubWidgets[i];
  76. m_pSubWidgets[i] = NULL;
  77. }
  78. break;
  79. }
  80. }
  81. }

简单的多屏播放器示例(vlc+qt)的更多相关文章

  1. 一款非常简单的android音乐播放器源码分享给大家

    一款非常简单的android音乐播放器源码分享给大家,该应用虽然很小,大家常用的播放器功能基本实现了,可能有点还不够完善,大家也可以自己完善一下,源码在源码天堂那里已经有了,大家可以到那里下载学习吧. ...

  2. 【源码分享】mui实现简单的手机音乐播放器

    mui实现简单的手机音乐播放器 最近先来无事,我用mui写了一个可以跨页面控制的音乐播放器.主要功能有上一曲,下一曲,播放,暂停,感兴趣的可以继续看下去. 说的总是不实在,直接上源码,有兴趣的可以读下 ...

  3. Go笔记之二:一个完整的播放器示例

    Go笔记之二:一个完整的播放器示例 该示例从命令行运行一个播放器示例,可进行添加.删除.浏览和模拟播放,其内容是对 Go 语言接口使用的良好展示 源码及可执行文件 参考书籍<Go语言编程> ...

  4. h5-自定义视屏播放器

    1.html代码 <h3 class="playerTitle">视屏播放器</h3> <div class="player"&g ...

  5. Java利用VLC开发简易视屏播放器

    1.环境配置 (1)下载VLC  VlC官网http://www.videolan.org/    各个版本的下载地址http://download.videolan.org/pub/videolan ...

  6. Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

    效果图如下: (PS本来是要给大家穿gif动态图的,无奈太大了,没法上传) 功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能 实现的思路: 在主布局中放置一个SurfaceView,在Su ...

  7. 超简单解决linux音乐播放器乱码问题

    问题 中文MP3的tag信息有些因为采用了GBK编码, 导致linux下的大多播放器(Rhythmbox, Audacious)无法正确识别而显示乱码. 如下图Audacious的乱码情况. 网上的常 ...

  8. android快捷简单的实现音乐播放器

    自己做了一个相对完整的音乐播放器,现在把播放模块提取出来,分享给大家.音乐播放器基本功能都实现了的,可能有些BUG,希望谅解. 播放器功能如下: 1.暂停,播放 2.拖动条实现,快进,快退 3.歌词同 ...

  9. 一个简单的ipfs音乐播放器的实现

    IPFS音乐播放器 IPFS相关 IPFS第一次亲密接触 什么是IPFS IPFS对比HTTP/FTP等协议的优势 IPFS应用场景 -移动数据 交易 路由 网络 定义数据 命名 使用数据 具体场景; ...

随机推荐

  1. webpack 学习过程

    什么是WebPack,为什么要使用它? 为什要使用WebPack 现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包.为了简化开发的复杂度,前端社区涌现 ...

  2. Linux中 tr 命令详解

    tr - translate or delete characters 主要用于转换和删除字符 带有最常用选项的t r命令格式为:tr -c -d -s [ "string1_to_tran ...

  3. Odoo的菜单项

    用户界面的入口是菜单项,菜单项形成一个层级结构,最顶级项为应用,其下一级为每个应用的主菜单.还可以添加更深的子菜单.可操作菜单与窗口操作关联,它告诉客户端在点击了菜单项后应执行什么操作. 菜单项存储在 ...

  4. 【2017-04-19】C#中String.Format格式使用

    例子: int a =9; string s= a.ToString("000"); Console.Write(s); 打印出来就是009 C#格式化数值结果表 字符 说明 示例 ...

  5. 使用select异步IO实现socketserver服务器 源码剖析

    #_*_coding:utf-8_*_ #这是一个echo server,客户端消息,服务端回复相同的消息 import select, socket, sys, queue # Create a T ...

  6. elk快速入门-filebeat

    filebeatFilebeat是一个日志文件托运工具,在你的服务器上安装客户端后,filebeat会监控日志目录或者指定的日志文件,追踪读取这些文件(追踪文件的变化,不停的读),并且转发这些信息到e ...

  7. 《编译原理》LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析

    <编译原理>LR 分析法与构造 LR(1) 分析表的步骤 - 例题解析 笔记 直接做题是有一些特定步骤,有技巧.但也必须先了解一些基本概念,本篇会通过例题形式解释概念,会容易理解和记忆,以 ...

  8. Python main()函数解析

    __main__ — Top-level script environment '__main__'是顶级代码执行的作用域的名字. 当一个模块从标准input, 一个脚本文件,或一个交互命令read读 ...

  9. jquery中.each()方法遍历循环如何终止方法

    使用return false 终止循环 function checkStar(obj){ var flag=false; //获取本节点星级 var star = obj.getAttribute(& ...

  10. python+request+HTMLTestRunner+unittest接口自动化测试框架

    转自https://my.oschina.net/u/3041656/blog/820023 正在调研使用python进行自动化测试,在网上发现一篇比较好的博文,作者使用的是python3,但目前自己 ...