SimplePlayerWindow.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include "SimplePlayerWindow.h"
  2. #include <QFileDialog>
  3. #include <QMessageBox>
  4. #include <QDebug>
  5. #include <QFileInfo>
  6. SimplePlayerWindow::SimplePlayerWindow(QWidget *parent)
  7. : QMainWindow(parent)
  8. , m_playerAdapter(PlayerAdapterFactory::create(this))
  9. , m_videoRenderer(nullptr)
  10. {
  11. setupUI();
  12. connectSignals();
  13. updateUI();
  14. // 设置视频渲染器
  15. if (m_videoRenderer && m_playerAdapter) {
  16. m_playerAdapter->setVideoRenderer(m_videoRenderer);
  17. }
  18. setWindowTitle("Simple Media Player");
  19. resize(800, 600);
  20. }
  21. SimplePlayerWindow::~SimplePlayerWindow()
  22. {
  23. if (m_playerAdapter) {
  24. m_playerAdapter->stop();
  25. }
  26. }
  27. void SimplePlayerWindow::openFile()
  28. {
  29. QString filename = QFileDialog::getOpenFileName(
  30. this,
  31. "Open Media File",
  32. "",
  33. "Media Files (*.mp4 *.avi *.mkv *.mov *.wmv *.flv *.webm *.mp3 *.wav *.aac *.flac *.ogg);;All Files (*.*)"
  34. );
  35. if (!filename.isEmpty()) {
  36. av::ErrorCode result = m_playerAdapter->openFile(filename);
  37. if (result != av::ErrorCode::OK) {
  38. QMessageBox::critical(this, "Error", "Failed to open file: " + filename);
  39. } else {
  40. m_fileLabel->setText("File: " + QFileInfo(filename).fileName());
  41. }
  42. }
  43. }
  44. void SimplePlayerWindow::playPause()
  45. {
  46. PlayerState state = m_playerAdapter->getState();
  47. if (state == PlayerState::Playing) {
  48. m_playerAdapter->pause();
  49. } else if (state == PlayerState::Paused || state == PlayerState::Stopped) {
  50. m_playerAdapter->play();
  51. }
  52. }
  53. void SimplePlayerWindow::stop()
  54. {
  55. m_playerAdapter->stop();
  56. }
  57. void SimplePlayerWindow::seek()
  58. {
  59. if (m_seeking) {
  60. qint64 duration = m_playerAdapter->getDuration();
  61. qint64 position = (duration * m_positionSlider->value()) / 1000;
  62. m_playerAdapter->seek(position);
  63. }
  64. }
  65. void SimplePlayerWindow::setVolume()
  66. {
  67. double volume = m_volumeSlider->value() / 100.0;
  68. m_playerAdapter->setVolume(volume);
  69. m_volumeLabel->setText(QString("Volume: %1%").arg(m_volumeSlider->value()));
  70. }
  71. void SimplePlayerWindow::toggleMute()
  72. {
  73. bool muted = m_playerAdapter->isMuted();
  74. m_playerAdapter->setMuted(!muted);
  75. }
  76. void SimplePlayerWindow::setPlaybackSpeed()
  77. {
  78. double speed = m_speedSlider->value() / 100.0;
  79. m_playerAdapter->setPlaybackSpeed(speed);
  80. m_speedLabel->setText(QString("Speed: %1x").arg(speed, 0, 'f', 2));
  81. }
  82. void SimplePlayerWindow::onStateChanged(PlayerState state)
  83. {
  84. QString stateText;
  85. switch (state) {
  86. case PlayerState::Idle:
  87. stateText = "Idle";
  88. break;
  89. // case PlayerState::Loading:
  90. // stateText = "Loading";
  91. // break;
  92. case PlayerState::Playing:
  93. stateText = "Playing";
  94. break;
  95. case PlayerState::Paused:
  96. stateText = "Paused";
  97. break;
  98. case PlayerState::Stopped:
  99. stateText = "Stopped";
  100. break;
  101. case PlayerState::Error:
  102. stateText = "Error";
  103. break;
  104. }
  105. m_stateLabel->setText("State: " + stateText);
  106. updateUI();
  107. }
  108. void SimplePlayerWindow::onMediaInfoChanged(const MediaInfo& info)
  109. {
  110. QString infoText = QString("Duration: %1 | Video: %2x%3 | Audio: %4 Hz")
  111. .arg(formatTime(info.duration))
  112. .arg(info.width)
  113. .arg(info.height)
  114. .arg(info.audioSampleRate);
  115. m_infoLabel->setText(infoText);
  116. }
  117. void SimplePlayerWindow::onPositionChanged(qint64 position)
  118. {
  119. if (!m_seeking) {
  120. qint64 duration = m_playerAdapter->getDuration();
  121. if (duration > 0) {
  122. int sliderValue = (position * 1000) / duration;
  123. m_positionSlider->setValue(sliderValue);
  124. }
  125. QString timeText = QString("%1 / %2")
  126. .arg(formatTime(position))
  127. .arg(formatTime(duration));
  128. m_timeLabel->setText(timeText);
  129. }
  130. }
  131. void SimplePlayerWindow::onVolumeChanged(double volume)
  132. {
  133. int volumePercent = static_cast<int>(volume * 100);
  134. m_volumeSlider->setValue(volumePercent);
  135. m_volumeLabel->setText(QString("Volume: %1%").arg(volumePercent));
  136. }
  137. void SimplePlayerWindow::onMutedChanged(bool muted)
  138. {
  139. m_muteButton->setText(muted ? "Unmute" : "Mute");
  140. }
  141. void SimplePlayerWindow::onPlaybackSpeedChanged(double speed)
  142. {
  143. int speedPercent = static_cast<int>(speed * 100);
  144. m_speedSlider->setValue(speedPercent);
  145. m_speedLabel->setText(QString("Speed: %1x").arg(speed, 0, 'f', 2));
  146. }
  147. void SimplePlayerWindow::onErrorOccurred(const QString& error)
  148. {
  149. QMessageBox::critical(this, "Player Error", error);
  150. qDebug() << "Player error:" << error;
  151. }
  152. void SimplePlayerWindow::onStatsUpdated(const PlaybackStats& stats)
  153. {
  154. QString statsText = QString("Packets: %1 | Video Frames: %2 | Audio Frames: %3")
  155. .arg(stats.queuedPackets)
  156. .arg(stats.queuedVideoFrames)
  157. .arg(stats.queuedAudioFrames);
  158. m_statsLabel->setText(statsText);
  159. }
  160. void SimplePlayerWindow::setupUI()
  161. {
  162. auto* centralWidget = new QWidget(this);
  163. setCentralWidget(centralWidget);
  164. auto* mainLayout = new QVBoxLayout(centralWidget);
  165. // 文件信息
  166. m_fileLabel = new QLabel("No file loaded");
  167. m_stateLabel = new QLabel("State: Idle");
  168. m_infoLabel = new QLabel("Media info will appear here");
  169. mainLayout->addWidget(m_fileLabel);
  170. mainLayout->addWidget(m_stateLabel);
  171. mainLayout->addWidget(m_infoLabel);
  172. // 视频渲染器
  173. m_videoRenderer = new VideoRenderer(this);
  174. m_videoRenderer->setMinimumSize(640, 480);
  175. m_videoRenderer->setStyleSheet("border: 1px solid gray;");
  176. mainLayout->addWidget(m_videoRenderer);
  177. // 控制按钮
  178. auto* buttonLayout = new QHBoxLayout();
  179. m_openButton = new QPushButton("Open File");
  180. m_playPauseButton = new QPushButton("Play");
  181. m_stopButton = new QPushButton("Stop");
  182. buttonLayout->addWidget(m_openButton);
  183. buttonLayout->addWidget(m_playPauseButton);
  184. buttonLayout->addWidget(m_stopButton);
  185. buttonLayout->addStretch();
  186. mainLayout->addLayout(buttonLayout);
  187. // 进度控制
  188. auto* progressLayout = new QHBoxLayout();
  189. m_timeLabel = new QLabel("00:00 / 00:00");
  190. m_positionSlider = new QSlider(Qt::Horizontal);
  191. m_positionSlider->setRange(0, 1000);
  192. progressLayout->addWidget(m_timeLabel);
  193. progressLayout->addWidget(m_positionSlider);
  194. mainLayout->addLayout(progressLayout);
  195. // 音量控制
  196. auto* volumeLayout = new QHBoxLayout();
  197. m_volumeLabel = new QLabel("Volume: 100%");
  198. m_volumeSlider = new QSlider(Qt::Horizontal);
  199. m_volumeSlider->setRange(0, 100);
  200. m_volumeSlider->setValue(100);
  201. m_muteButton = new QPushButton("Mute");
  202. volumeLayout->addWidget(m_volumeLabel);
  203. volumeLayout->addWidget(m_volumeSlider);
  204. volumeLayout->addWidget(m_muteButton);
  205. mainLayout->addLayout(volumeLayout);
  206. // 播放速度控制
  207. auto* speedLayout = new QHBoxLayout();
  208. m_speedLabel = new QLabel("Speed: 1.00x");
  209. m_speedSlider = new QSlider(Qt::Horizontal);
  210. m_speedSlider->setRange(25, 400); // 0.25x to 4.0x
  211. m_speedSlider->setValue(100);
  212. speedLayout->addWidget(m_speedLabel);
  213. speedLayout->addWidget(m_speedSlider);
  214. mainLayout->addLayout(speedLayout);
  215. // 统计信息
  216. m_statsLabel = new QLabel("Statistics will appear here");
  217. mainLayout->addWidget(m_statsLabel);
  218. mainLayout->addStretch();
  219. }
  220. void SimplePlayerWindow::connectSignals()
  221. {
  222. // UI信号
  223. connect(m_openButton, &QPushButton::clicked, this, &SimplePlayerWindow::openFile);
  224. connect(m_playPauseButton, &QPushButton::clicked, this, &SimplePlayerWindow::playPause);
  225. connect(m_stopButton, &QPushButton::clicked, this, &SimplePlayerWindow::stop);
  226. connect(m_positionSlider, &QSlider::sliderPressed, [this]() { m_seeking = true; });
  227. connect(m_positionSlider, &QSlider::sliderReleased, [this]() {
  228. seek();
  229. m_seeking = false;
  230. });
  231. connect(m_volumeSlider, &QSlider::valueChanged, this, &SimplePlayerWindow::setVolume);
  232. connect(m_muteButton, &QPushButton::clicked, this, &SimplePlayerWindow::toggleMute);
  233. connect(m_speedSlider, &QSlider::valueChanged, this, &SimplePlayerWindow::setPlaybackSpeed);
  234. // 播放器信号
  235. connect(m_playerAdapter.get(),
  236. &PlayerAdapter::stateChanged,
  237. this,
  238. &SimplePlayerWindow::onStateChanged);
  239. connect(m_playerAdapter.get(),
  240. &PlayerAdapter::mediaInfoChanged,
  241. this,
  242. &SimplePlayerWindow::onMediaInfoChanged);
  243. connect(m_playerAdapter.get(),
  244. &PlayerAdapter::positionChanged,
  245. this,
  246. &SimplePlayerWindow::onPositionChanged);
  247. connect(m_playerAdapter.get(),
  248. &PlayerAdapter::volumeChanged,
  249. this,
  250. &SimplePlayerWindow::onVolumeChanged);
  251. connect(m_playerAdapter.get(),
  252. &PlayerAdapter::mutedChanged,
  253. this,
  254. &SimplePlayerWindow::onMutedChanged);
  255. connect(m_playerAdapter.get(),
  256. &PlayerAdapter::playbackSpeedChanged,
  257. this,
  258. &SimplePlayerWindow::onPlaybackSpeedChanged);
  259. connect(m_playerAdapter.get(),
  260. &PlayerAdapter::errorOccurred,
  261. this,
  262. &SimplePlayerWindow::onErrorOccurred);
  263. connect(m_playerAdapter.get(),
  264. &PlayerAdapter::statsUpdated,
  265. this,
  266. &SimplePlayerWindow::onStatsUpdated);
  267. }
  268. void SimplePlayerWindow::updateUI()
  269. {
  270. PlayerState state = m_playerAdapter->getState();
  271. // 更新播放/暂停按钮
  272. if (state == PlayerState::Playing) {
  273. m_playPauseButton->setText("Pause");
  274. } else {
  275. m_playPauseButton->setText("Play");
  276. }
  277. // 更新按钮可用状态
  278. bool hasMedia = (state != PlayerState::Idle);
  279. m_playPauseButton->setEnabled(hasMedia);
  280. m_stopButton->setEnabled(hasMedia);
  281. m_positionSlider->setEnabled(hasMedia);
  282. }
  283. QString SimplePlayerWindow::formatTime(qint64 microseconds)
  284. {
  285. qint64 seconds = microseconds / 1000000;
  286. qint64 minutes = seconds / 60;
  287. seconds %= 60;
  288. return QString("%1:%2").arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
  289. }