#include "PlayWidget.h" #include #include #include "playercontroller.h" #include "../AvRecorder/ui/opengl_video_widget.h" #include "audio_effect_gl.h" #include "qnamespace.h" PlayWidget::PlayWidget(QWidget* parent) : QWidget(parent) { setupUi(); setupConnections(); setPlayerController(new PlayerController); } PlayWidget::~PlayWidget() { if (m_playerController) { delete m_playerController; } } void PlayWidget::startToPlay(const QString& url) { if (m_playerController) { m_playerController->startToPlay(url); } } bool PlayWidget::isPlaying() const { if (m_playerController) { return m_playerController->isPlaying(); } return false; } void PlayWidget::setupUi() { m_videoWidget = std::make_unique(this); m_sliderProgress = new QSlider(Qt::Horizontal, this); m_labelTime = new QLabel("00:00/00:00", this); m_btnPlayPause = new QPushButton("播放", this); m_comboSpeed = new QComboBox(this); m_comboSpeed->addItems({"0.5x", "1.0x", "1.5x", "2.0x"}); m_sliderVolume = new QSlider(Qt::Horizontal, this); m_sliderVolume->setRange(0, 100); m_labelVolume = new QLabel("音量", this); QHBoxLayout* controlLayout = new QHBoxLayout; controlLayout->addWidget(m_btnPlayPause); QLabel* speedLabel = new QLabel("倍速:", this); controlLayout->addWidget(speedLabel); controlLayout->addWidget(m_comboSpeed); controlLayout->addWidget(m_labelVolume); controlLayout->addWidget(m_sliderVolume); m_audioEffect = std::make_unique(this); QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_videoWidget.get(), 100); // 增加拉伸因子,让视频区域占据更多空间 QHBoxLayout* progressLayout = new QHBoxLayout; progressLayout->addWidget(m_sliderProgress, 8); progressLayout->addWidget(m_labelTime, 2); mainLayout->addLayout(progressLayout, 0); // 设置为0,不占用额外空间 mainLayout->addLayout(controlLayout, 0); // 设置为0,不占用额外空间 mainLayout->addWidget(m_audioEffect.get(), 0); // 设置为0,不占用额外空间 setLayout(mainLayout); // 设置视频组件的最小尺寸策略,确保它能够正常显示 m_videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_videoWidget->setMinimumSize(320, 240); // 设置最小尺寸 // 隐藏除了m_videoWidget之外的所有UI组件 m_sliderProgress->hide(); m_labelTime->hide(); m_btnPlayPause->hide(); speedLabel->hide(); m_comboSpeed->hide(); m_sliderVolume->hide(); m_labelVolume->hide(); m_audioEffect->hide(); } void PlayWidget::setupConnections() { connect(m_btnPlayPause, &QPushButton::clicked, this, &PlayWidget::onPlayPauseClicked); // connect(m_sliderProgress, &QSlider::sliderReleased, this, [this]() { // if (!m_playerController) return; // int value = m_sliderProgress->value(); // int max = m_sliderProgress->maximum(); // if (max > 0) { // double seek_time = value * m_totalTime / max; // m_playerController->videoSeek(seek_time); // } // }); connect(m_comboSpeed, QOverload::of(&QComboBox::currentIndexChanged), this, &PlayWidget::onSpeedChanged); connect(m_sliderVolume, &QSlider::valueChanged, this, &PlayWidget::onVolumeChanged); } void PlayWidget::setPlayerController(PlayerController* controller) { m_playerController = controller; if (!m_playerController) return; // 视频帧信号 connect( m_playerController, &PlayerController::frameReady, this, [this](AVFrame* frame) { AVFrame* copiedFrame = av_frame_clone(frame); // 添加空指针检查和frame有效性检查 if (m_videoWidget && copiedFrame && copiedFrame->data[0] && copiedFrame->width > 0 && copiedFrame->height > 0) { m_videoWidget->Render(copiedFrame); } }, Qt::DirectConnection); // 音频可视化信号 connect(m_playerController, &PlayerController::audioData, this, [this](const AudioData& data) { if (m_audioEffect) m_audioEffect->paint_data(data); }); connect(m_playerController, &PlayerController::videoStopped, this, [this]() { if (m_videoWidget) m_videoWidget->showEndTip("播放结束啦~"); }); // VideoPlayThread* videoPlayThread = m_playerController->videoPlayThread(); // 进度/时间信号 // connect(m_playerController, &PlayerController::updatePlayTime, this, [this]() { // if (!m_playerController) return; // auto state = m_playerController->state(); // if (!state) return; // double cur = state->audio_clock; // double total = 0; // if (state->ic) total = state->ic->duration / 1000000.0; // m_totalTime = total; // int max = 1000; // m_sliderProgress->setMaximum(max); // m_sliderProgress->setValue(total > 0 ? int(cur * max / total) : 0); // QTime curT(0,0); curT = curT.addSecs(int(cur)); // QTime totT(0,0); totT = totT.addSecs(int(total)); // m_labelTime->setText(curT.toString("mm:ss") + "/" + totT.toString("mm:ss")); // }); // 音量信号 connect(m_playerController, &PlayerController::updatePlayControlVolume, this, [this]() { if (!m_playerController) return; float vol = m_playerController->deviceVolume(); m_sliderVolume->setValue(int(vol * 100)); }); // 播放/暂停状态信号 connect(m_playerController, &PlayerController::updatePlayControlStatus, this, [this]() { if (!m_playerController) return; auto state = m_playerController->state(); if (state && state->paused) m_btnPlayPause->setText("播放"); else m_btnPlayPause->setText("暂停"); }); // controller->startToPlay("C:/Users/zhuizhu/Videos/1.mp4"); } void PlayWidget::onPlayPauseClicked() { if (m_playerController) m_playerController->pausePlay(); } void PlayWidget::onProgressChanged(int value) { // 进度条拖动时可选预览实现 } void PlayWidget::onSpeedChanged(int index) { if (!m_playerController) return; double speed = 1.0; switch(index) { case 0: speed = 0.5; break; case 1: speed = 1.0; break; case 2: speed = 1.5; break; case 3: speed = 2.0; break; default: speed = 1.0; break; } m_playerController->setPlaySpeed(speed); } void PlayWidget::onVolumeChanged(int value) { if (!m_playerController) return; m_playerController->setDeviceVolume(value / 100.0f); }