PlayWidget.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "PlayWidget.h"
  2. #include <QDebug>
  3. #include <QTimer>
  4. #include "playercontroller.h"
  5. #include "../AvRecorder/ui/opengl_video_widget.h"
  6. #include "audio_effect_gl.h"
  7. #include "qnamespace.h"
  8. PlayWidget::PlayWidget(QWidget* parent)
  9. : QWidget(parent)
  10. {
  11. setupUi();
  12. setupConnections();
  13. setPlayerController(new PlayerController);
  14. }
  15. PlayWidget::~PlayWidget()
  16. {
  17. if (m_playerController) {
  18. delete m_playerController;
  19. }
  20. }
  21. void PlayWidget::startToPlay(const QString& url)
  22. {
  23. if (m_playerController) {
  24. m_playerController->startToPlay(url);
  25. }
  26. }
  27. bool PlayWidget::isPlaying() const
  28. {
  29. if (m_playerController) {
  30. return m_playerController->isPlaying();
  31. }
  32. return false;
  33. }
  34. void PlayWidget::setupUi()
  35. {
  36. m_videoWidget = std::make_unique<OpenGLVideoWidget>(this);
  37. m_sliderProgress = new QSlider(Qt::Horizontal, this);
  38. m_labelTime = new QLabel("00:00/00:00", this);
  39. m_btnPlayPause = new QPushButton("播放", this);
  40. m_comboSpeed = new QComboBox(this);
  41. m_comboSpeed->addItems({"0.5x", "1.0x", "1.5x", "2.0x"});
  42. m_sliderVolume = new QSlider(Qt::Horizontal, this);
  43. m_sliderVolume->setRange(0, 100);
  44. m_labelVolume = new QLabel("音量", this);
  45. QHBoxLayout* controlLayout = new QHBoxLayout;
  46. controlLayout->addWidget(m_btnPlayPause);
  47. QLabel* speedLabel = new QLabel("倍速:", this);
  48. controlLayout->addWidget(speedLabel);
  49. controlLayout->addWidget(m_comboSpeed);
  50. controlLayout->addWidget(m_labelVolume);
  51. controlLayout->addWidget(m_sliderVolume);
  52. m_audioEffect = std::make_unique<AudioEffectGL>(this);
  53. QVBoxLayout* mainLayout = new QVBoxLayout(this);
  54. mainLayout->addWidget(m_videoWidget.get(), 100); // 增加拉伸因子,让视频区域占据更多空间
  55. QHBoxLayout* progressLayout = new QHBoxLayout;
  56. progressLayout->addWidget(m_sliderProgress, 8);
  57. progressLayout->addWidget(m_labelTime, 2);
  58. mainLayout->addLayout(progressLayout, 0); // 设置为0,不占用额外空间
  59. mainLayout->addLayout(controlLayout, 0); // 设置为0,不占用额外空间
  60. mainLayout->addWidget(m_audioEffect.get(), 0); // 设置为0,不占用额外空间
  61. setLayout(mainLayout);
  62. // 设置视频组件的最小尺寸策略,确保它能够正常显示
  63. m_videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  64. m_videoWidget->setMinimumSize(320, 240); // 设置最小尺寸
  65. // 隐藏除了m_videoWidget之外的所有UI组件
  66. m_sliderProgress->hide();
  67. m_labelTime->hide();
  68. m_btnPlayPause->hide();
  69. speedLabel->hide();
  70. m_comboSpeed->hide();
  71. m_sliderVolume->hide();
  72. m_labelVolume->hide();
  73. m_audioEffect->hide();
  74. }
  75. void PlayWidget::setupConnections()
  76. {
  77. connect(m_btnPlayPause, &QPushButton::clicked, this, &PlayWidget::onPlayPauseClicked);
  78. // connect(m_sliderProgress, &QSlider::sliderReleased, this, [this]() {
  79. // if (!m_playerController) return;
  80. // int value = m_sliderProgress->value();
  81. // int max = m_sliderProgress->maximum();
  82. // if (max > 0) {
  83. // double seek_time = value * m_totalTime / max;
  84. // m_playerController->videoSeek(seek_time);
  85. // }
  86. // });
  87. connect(m_comboSpeed, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlayWidget::onSpeedChanged);
  88. connect(m_sliderVolume, &QSlider::valueChanged, this, &PlayWidget::onVolumeChanged);
  89. }
  90. void PlayWidget::setPlayerController(PlayerController* controller)
  91. {
  92. m_playerController = controller;
  93. if (!m_playerController) return;
  94. // 视频帧信号
  95. connect(
  96. m_playerController,
  97. &PlayerController::frameReady,
  98. this,
  99. [this](AVFrame* frame) {
  100. AVFrame* copiedFrame = av_frame_clone(frame);
  101. // 添加空指针检查和frame有效性检查
  102. if (m_videoWidget && copiedFrame && copiedFrame->data[0] && copiedFrame->width > 0
  103. && copiedFrame->height > 0) {
  104. m_videoWidget->Render(copiedFrame);
  105. }
  106. },
  107. Qt::DirectConnection);
  108. // 音频可视化信号
  109. connect(m_playerController, &PlayerController::audioData, this, [this](const AudioData& data) {
  110. if (m_audioEffect)
  111. m_audioEffect->paint_data(data);
  112. });
  113. connect(m_playerController, &PlayerController::videoStopped, this, [this]() {
  114. if (m_videoWidget)
  115. m_videoWidget->showEndTip("播放结束啦~");
  116. });
  117. // VideoPlayThread* videoPlayThread = m_playerController->videoPlayThread();
  118. // 进度/时间信号
  119. // connect(m_playerController, &PlayerController::updatePlayTime, this, [this]() {
  120. // if (!m_playerController) return;
  121. // auto state = m_playerController->state();
  122. // if (!state) return;
  123. // double cur = state->audio_clock;
  124. // double total = 0;
  125. // if (state->ic) total = state->ic->duration / 1000000.0;
  126. // m_totalTime = total;
  127. // int max = 1000;
  128. // m_sliderProgress->setMaximum(max);
  129. // m_sliderProgress->setValue(total > 0 ? int(cur * max / total) : 0);
  130. // QTime curT(0,0); curT = curT.addSecs(int(cur));
  131. // QTime totT(0,0); totT = totT.addSecs(int(total));
  132. // m_labelTime->setText(curT.toString("mm:ss") + "/" + totT.toString("mm:ss"));
  133. // });
  134. // 音量信号
  135. connect(m_playerController, &PlayerController::updatePlayControlVolume, this, [this]() {
  136. if (!m_playerController) return;
  137. float vol = m_playerController->deviceVolume();
  138. m_sliderVolume->setValue(int(vol * 100));
  139. });
  140. // 播放/暂停状态信号
  141. connect(m_playerController, &PlayerController::updatePlayControlStatus, this, [this]() {
  142. if (!m_playerController) return;
  143. auto state = m_playerController->state();
  144. if (state && state->paused)
  145. m_btnPlayPause->setText("播放");
  146. else
  147. m_btnPlayPause->setText("暂停");
  148. });
  149. // controller->startToPlay("C:/Users/zhuizhu/Videos/1.mp4");
  150. }
  151. void PlayWidget::onPlayPauseClicked()
  152. {
  153. if (m_playerController) m_playerController->pausePlay();
  154. }
  155. void PlayWidget::onProgressChanged(int value)
  156. {
  157. // 进度条拖动时可选预览实现
  158. }
  159. void PlayWidget::onSpeedChanged(int index)
  160. {
  161. if (!m_playerController) return;
  162. double speed = 1.0;
  163. switch(index) {
  164. case 0: speed = 0.5; break;
  165. case 1: speed = 1.0; break;
  166. case 2: speed = 1.5; break;
  167. case 3: speed = 2.0; break;
  168. default: speed = 1.0; break;
  169. }
  170. m_playerController->setPlaySpeed(speed);
  171. }
  172. void PlayWidget::onVolumeChanged(int value)
  173. {
  174. if (!m_playerController) return;
  175. m_playerController->setDeviceVolume(value / 100.0f);
  176. }