花了一年多的时间,终于把这个超级播放器做成了自己想要的架构,用户的需求是一方面,自己架构方面的提升也是一方面,最主要是将界面和解码解耦了,这样才能动态的挂载不同的解码内核到不同的窗体,多对多关系,而且解耦和才能方便的实现共享解码,整个设计参照了Qt的设计思路,将各种功能做成不同的类组件,同时还有多层基类的设计,最大的提炼共性,本组件设计的视频解码线程基类、视频显示窗体基类、视频文件保存基类等,都是公用的,而且还提供给本地摄像头组件使用,因为共性一样。
国内站点:https://gitee.com/feiyangqingyun
国际站点:https://github.com/feiyangqingyun
体验地址:http://pan.baidu.com/s/1YOVD8nkoOSYwX9KgSauLeQ 提取码:kcgz 文件名:bin_video_demo/bin_linux_video。
void frmPlayerx::playStart(const QString &url) { on_btnStop_clicked(); VideoPara videoPara = ui->videoWidget->getVideoPara(); videoPara.videoCore = VideoCore_FFmpeg; videoPara.videoUrl = url; ui->videoWidget->setVideoPara(videoPara); if (!ui->videoWidget->init()) { return; } //关联采集线程信号槽 VideoThread *videoThread = ui->videoWidget->getVideoThread(); connect(videoThread, SIGNAL(receivePlayStart(int)), this, SLOT(receivePlayStart(int))); connect(videoThread, SIGNAL(receivePlayFinsh()), this, SLOT(receivePlayFinsh())); connect(videoThread, SIGNAL(receiveDuration(qint64)), this, SLOT(receiveDuration(qint64))); connect(videoThread, SIGNAL(receivePosition(qint64)), this, SLOT(receivePosition(qint64))); connect(videoThread, SIGNAL(receiveVolume(int)), this, SLOT(receiveVolume(int))); connect(videoThread, SIGNAL(receiveMuted(bool)), this, SLOT(receiveMuted(bool))); ui->videoWidget->play(); } void frmPlayerx::playNext() { //如果播放完毕则查看是否有下一曲,有则自动播放下一曲 //计算当前行及列表总数 int count = ui->listWidget->count(); int row = ui->listWidget->currentRow(); //如果是顺序播放则自动播放下一曲 //如果是单曲循环则重新播放当前曲目 //如果是列表循环,自动播放下一曲,如果是最后一曲播放完毕则播放第一曲 //如果是随机播放,自动取随机数播放曲目 if (playMode == "list") { if (row < count - 1) { ui->listWidget->setCurrentRow(row + 1); on_listWidget_doubleClicked(); } else { on_btnStop_clicked(); } } else if (playMode == "loop") { ui->listWidget->setCurrentRow(row); on_listWidget_doubleClicked(); } else if (playMode == "looplist") { if (row < count - 1) { ui->listWidget->setCurrentRow(row + 1); on_listWidget_doubleClicked(); } else { ui->listWidget->setCurrentRow(0); on_listWidget_doubleClicked(); } } else if (playMode == "random") { int index = rand() % count; ui->listWidget->setCurrentRow(index); on_listWidget_doubleClicked(); } } void frmPlayerx::playPause() { playStatus = "play"; ui->btnPlay->setToolTip("播放"); IconHelper::setIcon(ui->btnPlay, 0xf04b, 18); ui->btnPlay->setStyleSheet("#btnPlay{padding:0px 0px 0px 4px;}"); } void frmPlayerx::receivePlayStart(int time) { playStatus = "pause"; ui->btnPlay->setToolTip("暂停"); IconHelper::setIcon(ui->btnPlay, 0xf04c, 18); ui->btnPlay->setStyleSheet("#btnPlay{padding:0px 0px 0px 0px;}"); } void frmPlayerx::receivePlayFinsh() { ui->labDuration->setText("00:00"); ui->labPosition->setText("00:00"); ui->sliderPosition->setValue(0); ui->sliderVolume->setValue(100); ui->sliderPosition->setRange(0, 0); receiveMuted(false); playPause(); //自动切换到下一个视频并执行模拟双击事件 if (ui->listWidget->currentRow() < ui->listWidget->count() - 1) { QDateTime now = QDateTime::currentDateTime(); if (doubleClickTime.msecsTo(now) > 500) { playNext(); } } } void frmPlayerx::receiveDuration(qint64 duration) { //设置进度条最大进度以及总时长 ui->sliderPosition->setValue(0); ui->sliderPosition->setMaximum(duration); ui->labDuration->setText(QUIHelper::getTimeString(duration)); } void frmPlayerx::receivePosition(qint64 position) { //设置当前进度及已播放时长 ui->sliderPosition->setValue(position); ui->labPosition->setText(QUIHelper::getTimeString(position)); } void frmPlayerx::receiveVolume(int volume) { ui->sliderVolume->setValue(volume); }