avplayerwidget.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "avplayerwidget.h"
  2. #include "avopenglwidget.h"
  3. #include "av_player.h"
  4. #include "vframe.h"
  5. AVPlayerWidget::AVPlayerWidget(QWidget *parent)
  6. : QWidget{parent}
  7. , m_player(new AVPlayer)
  8. , m_openglWidget(new AVOpenGLWidget(this))
  9. , m_isPlaying(false)
  10. , m_isPaused(false)
  11. {
  12. setupUI();
  13. connectSignals();
  14. // 设置默认音量
  15. m_player->setVolume(50);
  16. m_volumeSlider->setValue(50);
  17. // 设置默认测试URL
  18. m_urlEdit->setText("rtmp://127.0.0.1:1935/stream/V1/stream");
  19. }
  20. AVPlayerWidget::~AVPlayerWidget()
  21. {
  22. if (m_player) {
  23. m_player->clearPlayer();
  24. }
  25. }
  26. void AVPlayerWidget::setupUI()
  27. {
  28. m_mainLayout = new QVBoxLayout(this);
  29. // 添加OpenGL视频渲染组件
  30. m_mainLayout->addWidget(m_openglWidget, 1);
  31. // 创建控制面板
  32. m_controlLayout = new QHBoxLayout();
  33. // URL输入框
  34. m_urlEdit = new QLineEdit(this);
  35. m_urlEdit->setPlaceholderText("输入视频文件路径或URL");
  36. m_controlLayout->addWidget(m_urlEdit, 2);
  37. // 测试播放按钮
  38. m_testPlayButton = new QPushButton("测试播放", this);
  39. m_controlLayout->addWidget(m_testPlayButton);
  40. // 播放控制按钮
  41. m_playButton = new QPushButton("播放", this);
  42. m_pauseButton = new QPushButton("暂停", this);
  43. m_stopButton = new QPushButton("停止", this);
  44. m_controlLayout->addWidget(m_playButton);
  45. m_controlLayout->addWidget(m_pauseButton);
  46. m_controlLayout->addWidget(m_stopButton);
  47. // 音量控制
  48. QLabel *volumeLabel = new QLabel("音量:", this);
  49. m_volumeSlider = new QSlider(Qt::Horizontal, this);
  50. m_volumeSlider->setRange(0, 100);
  51. m_volumeSlider->setValue(50);
  52. m_volumeSlider->setMaximumWidth(100);
  53. m_controlLayout->addWidget(volumeLabel);
  54. m_controlLayout->addWidget(m_volumeSlider);
  55. // 时间显示
  56. m_timeLabel = new QLabel("00:00 / 00:00", this);
  57. m_controlLayout->addWidget(m_timeLabel);
  58. m_mainLayout->addLayout(m_controlLayout);
  59. // 设置初始状态
  60. m_pauseButton->setEnabled(false);
  61. m_stopButton->setEnabled(false);
  62. }
  63. void AVPlayerWidget::connectSignals()
  64. {
  65. // 连接AVPlayer信号
  66. connect(m_player, &AVPlayer::frameChanged, this, &AVPlayerWidget::onFrameChanged, Qt::QueuedConnection);
  67. connect(m_player, &AVPlayer::AVDurationChanged, this, &AVPlayerWidget::durationChangedSlot);
  68. connect(m_player, &AVPlayer::AVPtsChanged, this, &AVPlayerWidget::ptsChangedSlot);
  69. connect(m_player, &AVPlayer::AVTerminate, this, &AVPlayerWidget::terminateSlot, Qt::QueuedConnection);
  70. // 连接UI控件信号
  71. connect(m_playButton, &QPushButton::clicked, this, &AVPlayerWidget::onPlayButtonClicked);
  72. connect(m_pauseButton, &QPushButton::clicked, this, &AVPlayerWidget::onPauseButtonClicked);
  73. connect(m_stopButton, &QPushButton::clicked, this, &AVPlayerWidget::onStopButtonClicked);
  74. connect(m_testPlayButton, &QPushButton::clicked, this, &AVPlayerWidget::onTestPlayButtonClicked);
  75. connect(m_volumeSlider, &QSlider::valueChanged, this, &AVPlayerWidget::onVolumeChanged);
  76. }
  77. void AVPlayerWidget::play(const QString &url)
  78. {
  79. if (!m_player->play(url)) {
  80. // 提示反馈?
  81. return;
  82. }
  83. m_isPlaying = true;
  84. m_isPaused = false;
  85. m_playButton->setEnabled(false);
  86. m_pauseButton->setEnabled(true);
  87. m_stopButton->setEnabled(true);
  88. emit playStateChanged(true);
  89. }
  90. void AVPlayerWidget::stop()
  91. {
  92. m_player->clearPlayer();
  93. m_isPlaying = false;
  94. m_isPaused = false;
  95. m_playButton->setEnabled(true);
  96. m_pauseButton->setEnabled(false);
  97. m_stopButton->setEnabled(false);
  98. m_openglWidget->clearFrame();
  99. emit playStateChanged(false);
  100. }
  101. void AVPlayerWidget::pause()
  102. {
  103. if (m_isPlaying && !m_isPaused) {
  104. m_player->pause(true);
  105. m_isPaused = true;
  106. m_playButton->setText("继续");
  107. m_playButton->setEnabled(true);
  108. m_pauseButton->setEnabled(false);
  109. }
  110. }
  111. void AVPlayerWidget::resume()
  112. {
  113. if (m_isPlaying && m_isPaused) {
  114. m_player->pause(false);
  115. m_isPaused = false;
  116. m_playButton->setText("播放");
  117. m_playButton->setEnabled(false);
  118. m_pauseButton->setEnabled(true);
  119. }
  120. }
  121. void AVPlayerWidget::onPlayButtonClicked()
  122. {
  123. if (m_isPaused) {
  124. resume();
  125. } else {
  126. QString url = m_urlEdit->text().trimmed();
  127. if (!url.isEmpty()) {
  128. play(url);
  129. }
  130. }
  131. }
  132. void AVPlayerWidget::onPauseButtonClicked()
  133. {
  134. pause();
  135. }
  136. void AVPlayerWidget::onStopButtonClicked()
  137. {
  138. stop();
  139. }
  140. void AVPlayerWidget::onTestPlayButtonClicked()
  141. {
  142. // 使用默认测试视频
  143. QString testUrl = "C:/Users/zhuizhu/Videos/2.mp4";
  144. m_urlEdit->setText(testUrl);
  145. play(testUrl);
  146. }
  147. void AVPlayerWidget::onVolumeChanged(int volume)
  148. {
  149. m_player->setVolume(volume);
  150. }
  151. void AVPlayerWidget::onFrameChanged(QSharedPointer<VideoFrame> frame)
  152. {
  153. m_openglWidget->onShowYUV(frame);
  154. // 注意:这里不要释放avFrame,因为Render方法会处理
  155. }
  156. void AVPlayerWidget::ptsChangedSlot(unsigned int pts)
  157. {
  158. // 更新时间显示
  159. int seconds = pts / 1000;
  160. int minutes = seconds / 60;
  161. seconds = seconds % 60;
  162. QString timeStr = QString("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
  163. // 这里可以更新时间标签的当前时间部分
  164. }
  165. void AVPlayerWidget::durationChangedSlot(unsigned int duration)
  166. {
  167. // 更新总时长显示
  168. int seconds = duration / 1000;
  169. int minutes = seconds / 60;
  170. seconds = seconds % 60;
  171. QString durationStr = QString("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
  172. m_timeLabel->setText(QString("00:00 / %1").arg(durationStr));
  173. }
  174. void AVPlayerWidget::terminateSlot()
  175. {
  176. stop();
  177. }
  178. // 兼容旧接口实现
  179. void AVPlayerWidget::stopPlay()
  180. {
  181. stop();
  182. }
  183. void AVPlayerWidget::setPlayRoomId(const QString &id)
  184. {
  185. // 以当前URL为基准,去掉最后一节后拼接房间ID,避免硬编码服务器地址
  186. QString base = m_urlEdit->text().trimmed();
  187. if (base.isEmpty()) {
  188. base = "rtmp://127.0.0.1:1935/stream/V1/stream";
  189. }
  190. int lastSlash = base.lastIndexOf('/');
  191. QString streamBase = lastSlash > 0 ? base.left(lastSlash) : base;
  192. QString url = streamBase + "/" + id;
  193. m_urlEdit->setText(url);
  194. }
  195. void AVPlayerWidget::startPlay()
  196. {
  197. const QString url = m_urlEdit->text().trimmed();
  198. if (!url.isEmpty()) {
  199. play(url);
  200. }
  201. }