VideoPlayerWidget.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /**
  2. * 叶海辉
  3. * QQ群121376426
  4. * http://blog.yundiantech.com/
  5. */
  6. #include "VideoPlayerWidget.h"
  7. #include "ui_VideoPlayerWidget.h"
  8. #include <QPainter>
  9. #include <QPaintEvent>
  10. #include <QFileDialog>
  11. #include <QDebug>
  12. #include <QDesktopWidget>
  13. #include <QFontDatabase>
  14. #include <QMouseEvent>
  15. #include <QMessageBox>
  16. Q_DECLARE_METATYPE(VideoPlayer::PlayerState)
  17. VideoPlayerWidget::VideoPlayerWidget(QWidget *parent) :
  18. DragAbleWidget(parent),
  19. ui(new Ui::VideoPlayerWidget)
  20. {
  21. ui->setupUi(this->getContainWidget());
  22. ///初始化播放器
  23. VideoPlayer::initPlayer();
  24. setWindowFlags(Qt::FramelessWindowHint);//|Qt::WindowStaysOnTopHint); //使窗口的标题栏隐藏
  25. setAttribute(Qt::WA_TranslucentBackground);
  26. //因为VideoPlayer::PlayerState是自定义的类型 要跨线程传递需要先注册一下
  27. qRegisterMetaType<VideoPlayer::PlayerState>();
  28. connect(this, &VideoPlayerWidget::sig_OpenVideoFileFailed, this, &VideoPlayerWidget::slotOpenVideoFileFailed);
  29. connect(this, &VideoPlayerWidget::sig_OpenSdlFailed, this, &VideoPlayerWidget::slotOpenSdlFailed);
  30. connect(this, &VideoPlayerWidget::sig_TotalTimeChanged, this, &VideoPlayerWidget::slotTotalTimeChanged);
  31. connect(this, &VideoPlayerWidget::sig_PlayerStateChanged, this, &VideoPlayerWidget::slotStateChanged);
  32. connect(this, &VideoPlayerWidget::sig_DisplayVideo, this, &VideoPlayerWidget::slotDisplayVideo);
  33. connect(ui->pushButton_open, &QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  34. connect(ui->toolButton_open, &QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  35. connect(ui->pushButton_play, &QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  36. connect(ui->pushButton_pause,&QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  37. connect(ui->pushButton_stop, &QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  38. connect(ui->pushButton_volume, &QPushButton::clicked, this, &VideoPlayerWidget::slotBtnClick);
  39. connect(ui->horizontalSlider, SIGNAL(sig_valueChanged(int)), this, SLOT(slotSliderMoved(int)));
  40. connect(ui->horizontalSlider_volume, SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int)));
  41. ui->widget_container->installEventFilter(this);
  42. mPlayer = this;
  43. mTimer = new QTimer; //定时器-获取当前视频时间
  44. connect(mTimer,SIGNAL(timeout()),this,SLOT(slotTimerTimeOut()));
  45. mTimer->setInterval(500);
  46. ui->stackedWidget->setCurrentWidget(ui->page_open);
  47. ui->pushButton_pause->hide();
  48. resize(1024,768);
  49. setTitle(QStringLiteral("我的播放器-V%1").arg(AppConfig::VERSION_NAME));
  50. mVolume = mPlayer->getVolume();
  51. }
  52. VideoPlayerWidget::~VideoPlayerWidget()
  53. {
  54. delete ui;
  55. }
  56. void VideoPlayerWidget::slotSliderMoved(int value)
  57. {
  58. if (QObject::sender() == ui->horizontalSlider)
  59. {
  60. mPlayer->seek((qint64)value * 1000000);
  61. }
  62. else if (QObject::sender() == ui->horizontalSlider_volume)
  63. {
  64. mPlayer->setVolume(value / 100.0);
  65. ui->label_volume->setText(QString("%1").arg(value));
  66. }
  67. }
  68. void VideoPlayerWidget::slotTimerTimeOut()
  69. {
  70. if (QObject::sender() == mTimer)
  71. {
  72. qint64 Sec = mPlayer->getCurrentTime();
  73. ui->horizontalSlider->setValue(Sec);
  74. // QString hStr = QString("00%1").arg(Sec/3600);
  75. QString mStr = QString("00%1").arg(Sec/60);
  76. QString sStr = QString("00%1").arg(Sec%60);
  77. QString str = QString("%1:%2").arg(mStr.right(2)).arg(sStr.right(2));
  78. ui->label_currenttime->setText(str);
  79. }
  80. }
  81. void VideoPlayerWidget::slotBtnClick(bool isChecked)
  82. {
  83. if (QObject::sender() == ui->pushButton_play)
  84. {
  85. mPlayer->play();
  86. }
  87. else if (QObject::sender() == ui->pushButton_pause)
  88. {
  89. mPlayer->pause();
  90. }
  91. else if (QObject::sender() == ui->pushButton_stop)
  92. {
  93. mPlayer->stop(true);
  94. }
  95. else if (QObject::sender() == ui->pushButton_open || QObject::sender() == ui->toolButton_open)
  96. {
  97. QString s = QFileDialog::getOpenFileName(
  98. this, QStringLiteral("选择要播放的文件"),
  99. "/",//初始目录
  100. QStringLiteral("视频文件 (*.flv *.rmvb *.avi *.MP4 *.mkv);; 所有文件 (*.*);; "));
  101. if (!s.isEmpty())
  102. {
  103. s.replace("/","\\");
  104. mPlayer->stop(true); //如果在播放则先停止
  105. mPlayer->startPlay(s.toStdString());
  106. }
  107. }
  108. else if (QObject::sender() == ui->pushButton_volume)
  109. {
  110. qDebug()<<isChecked;
  111. bool isMute = isChecked;
  112. mPlayer->setMute(isMute);
  113. if (isMute)
  114. {
  115. mVolume = mPlayer->getVolume();
  116. ui->horizontalSlider_volume->setValue(0);
  117. ui->horizontalSlider_volume->setEnabled(false);
  118. ui->label_volume->setText(QString("%1").arg(0));
  119. }
  120. else
  121. {
  122. int volume = mVolume * 100.0;
  123. ui->horizontalSlider_volume->setValue(volume);
  124. ui->horizontalSlider_volume->setEnabled(true);
  125. ui->label_volume->setText(QString("%1").arg(volume));
  126. }
  127. }
  128. }
  129. ///打开文件失败
  130. void VideoPlayerWidget::doOpenVideoFileFailed(const int &code)
  131. {
  132. emit sig_OpenVideoFileFailed(code);
  133. }
  134. ///打开SDL失败的时候回调此函数
  135. void VideoPlayerWidget::doOpenSdlFailed(const int &code)
  136. {
  137. emit sig_OpenSdlFailed(code);
  138. }
  139. ///获取到视频时长的时候调用此函数
  140. void VideoPlayerWidget::doTotalTimeChanged(const int64_t &uSec)
  141. {
  142. emit sig_TotalTimeChanged(uSec);
  143. }
  144. ///播放器状态改变的时候回调此函数
  145. void VideoPlayerWidget::doPlayerStateChanged(const VideoPlayer::PlayerState &state)
  146. {
  147. emit sig_PlayerStateChanged(state);
  148. }
  149. void VideoPlayerWidget::slotOpenVideoFileFailed(const int &code)
  150. {
  151. QMessageBox::critical(NULL, "tips", QString("open file failed %1").arg(code));
  152. }
  153. void VideoPlayerWidget::slotOpenSdlFailed(const int &code)
  154. {
  155. QMessageBox::critical(NULL, "tips", QString("open Sdl failed %1").arg(code));
  156. }
  157. void VideoPlayerWidget::slotTotalTimeChanged(const qint64 &uSec)
  158. {
  159. qint64 Sec = uSec/1000000;
  160. ui->horizontalSlider->setRange(0,Sec);
  161. // QString hStr = QString("00%1").arg(Sec/3600);
  162. QString mStr = QString("00%1").arg(Sec/60);
  163. QString sStr = QString("00%1").arg(Sec%60);
  164. QString str = QString("%1:%2").arg(mStr.right(2)).arg(sStr.right(2));
  165. ui->label_totaltime->setText(str);
  166. }
  167. void VideoPlayerWidget::slotStateChanged(VideoPlayer::PlayerState state)
  168. {
  169. if (state == VideoPlayer::Stop)
  170. {
  171. ui->stackedWidget->setCurrentWidget(ui->page_open);
  172. ui->pushButton_pause->hide();
  173. ui->widget_videoPlayer->clear();
  174. ui->horizontalSlider->setValue(0);
  175. ui->label_currenttime->setText("00:00");
  176. ui->label_totaltime->setText("00:00");
  177. mTimer->stop();
  178. }
  179. else if (state == VideoPlayer::Playing)
  180. {
  181. ui->stackedWidget->setCurrentWidget(ui->page_video);
  182. ui->pushButton_play->hide();
  183. ui->pushButton_pause->show();
  184. mTimer->start();
  185. }
  186. else if (state == VideoPlayer::Pause)
  187. {
  188. ui->pushButton_pause->hide();
  189. ui->pushButton_play->show();
  190. }
  191. }
  192. ///显示rgb数据,此函数不宜做耗时操作,否则会影响播放的流畅性,传入的brgb32Buffer,在函数返回后既失效。
  193. void VideoPlayerWidget::doDisplayVideo(const uint8_t *brgb32Buffer, const int &width, const int &height)
  194. {
  195. // qDebug()<<__FUNCTION__<<width<<height;
  196. //把这个RGB数据 用QImage加载
  197. QImage tmpImg((uchar *)brgb32Buffer, width, height, QImage::Format_RGB32);
  198. // QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示
  199. QImage image = tmpImg.convertToFormat(QImage::Format_RGB888,Qt::NoAlpha); //去掉透明的部分 有些奇葩的视频会透明
  200. emit sig_DisplayVideo(image);
  201. }
  202. void VideoPlayerWidget::slotDisplayVideo(const QImage &image)
  203. {
  204. // qDebug()<<__FUNCTION__<<image;
  205. ui->widget_videoPlayer->inputOneFrame(image);
  206. }
  207. //图片显示部件时间过滤器处理
  208. bool VideoPlayerWidget::eventFilter(QObject *target, QEvent *event)
  209. {
  210. if(target == ui->widget_container)
  211. {
  212. if(event->type() == QEvent::Resize)
  213. {
  214. QResizeEvent * e = (QResizeEvent*)event;
  215. int w = e->size().width();
  216. int h = e->size().height();
  217. ui->stackedWidget->move(0, 0);
  218. ui->stackedWidget->resize(w, h);
  219. int x = 0;
  220. int y = h - ui->widget_controller->height();
  221. ui->widget_controller->move(x, y);
  222. ui->widget_controller->resize(w, ui->widget_controller->height());
  223. }
  224. // else if(event->type() == QEvent::Enter)
  225. // {
  226. // qDebug("Enter...");
  227. // }
  228. // else if(event->type() == QEvent::Leave)
  229. // {
  230. // qDebug("Leave...");
  231. // }
  232. // qDebug("The imageWidget generate the event!");
  233. // if(event->type() == QEvent::MouseButtonPress)
  234. // {
  235. // QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
  236. // if(mouseEvent->buttons() & Qt::LeftButton)
  237. // {
  238. // qDebug("The Left Button Event!");
  239. // }
  240. // else if(mouseEvent->buttons() & Qt::RightButton)
  241. // {
  242. // qDebug("The Right Button Event!");
  243. // }
  244. // return true;
  245. // }
  246. }
  247. //其它部件产生的事件则交给基类处理
  248. return DragAbleWidget::eventFilter(target, event);
  249. }