在Ubuntu中安装Mplayer:Qt——Ubuntu的安装Mplayer,及与Centos安装的区别;Mplayer的Demo试验【莫再踩坑了】
安装Mplayer成功之后,确定一下:是否在这个目录下/usr/bin存在mplayer目录:
确定存在之后,可以运行这个Demo:
链接:MplayerDemo成功项目 【相对下面那文章里的示例来说,代码有改动:改了一些Bug(虽然还有好几个BUG存在)】
Tips:CSDN下载分享,无需积分,免费——是从这篇文章《Linux 基于QT的mplayer视频播放器(实现进度条的拖动、播放列表等)》中下载的Demo成功示例
环境:
Linux操作系统:Ubuntu 14.0 LTS;
Qt编译器:“ Qt 5.8.0 gcc 64bit”;
Mplayer:Mplayer 1.3.0;
mainwindow.ui:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//#pragma execution_character_set("utf-8")
#include <QMainWindow>
#include <QPixmap>
#include <QSize>
#include <QProcess>
#include <QDir>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QListWidget>
#include <QStringList>
#include <QListWidgetItem>
#include <QByteArray>
#include <QMessageBox>
#include <QApplication>
#include <QDesktopWidget>
#include <QMouseEvent>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QPixmap pixmap;
QProcess *process;//使用进程进行操作
QString arg;//用来存放要使用的mplayer播放器路径
public:
QString fileName;
private slots:
void openFileSlot();//打开文件
void deleteFileSlot();//删除文件
void play(QString fileName);//播放
void on_listWidget_itemDoubleClicked(QListWidgetItem *item);//项目双击播放
void dataReceive();//接收视频信息(当前时间,总时间,进度),并显示
void zantingOrstartSlot();//暂停或开始
void on_horizontalSlider_sliderMoved(int position);//移动进度条控制播放位置
void backSlot();//后退
void forwardSlot();//快进
void lastSlot();//上一个
void nextSlot();//下一个
void reduceSlot();//减速
void accelerateSlot();//加速
void stopSlot();//停止
void voiceSlot();//声音静音
void on_voiceslider_sliderMoved(int position);//声音滑条
void mousePressEvent(QMouseEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QDateTime>
#include <QDebug>
using namespace std;
static double speed=1;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
this->process = new QProcess;
this->process->setProcessChannelMode(QProcess::MergedChannels);
// arg = "F:/mypler-vedio/MPlayer/mplayer.exe";//在Windows系统中安装Mplayer之后
arg = "/usr/bin/mplayer";//在Linux系统中安装Mplayer之后,将作用于play()函数的start()
ui->setupUi(this);
QPixmap pixmap;
pixmap.load(":/images/voice.png");//set the icon of function
ui->voiceButton->setFixedSize(48, 48);
ui->voiceButton->setIcon(pixmap);
ui->voiceButton->setIconSize(QSize(48, 48));
ui->voiceButton->setToolTip("音量");
ui->voiceButton->show();
ui->voiceslider->setSliderPosition(20);
ui->voiceslider->setValue(20);
QPixmap pixmap1;
pixmap1.load(":/images/last.png");
ui->lastButton->setFixedSize(48, 48);
ui->lastButton->setIcon(pixmap1);
ui->lastButton->setIconSize(QSize(48, 48));
ui->lastButton->setToolTip("上一个");
ui->lastButton->show();
QPixmap pixmap2;
pixmap2.load(":/images/next.png");
ui->nextButton->setFixedSize(48, 48);
ui->nextButton->setIcon(pixmap2);
ui->nextButton->setIconSize(QSize(48, 48));
ui->nextButton->setToolTip("下一个");
ui->nextButton->show();
QPixmap pixmap3;
pixmap3.load(":/images/start.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap3);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("开始播放");
ui->startButton->show();
QPixmap pixmap5;
pixmap5.load(":/images/manfang.png");
ui->manButton->setFixedSize(48, 48);
ui->manButton->setIcon(pixmap5);
ui->manButton->setIconSize(QSize(48, 48));
ui->manButton->setToolTip("减速播放");
ui->manButton->show();
QPixmap pixmap6;
pixmap6.load(":/images/kuaifang.png");
ui->kuaiButton->setFixedSize(48, 48);
ui->kuaiButton->setIcon(pixmap6);
ui->kuaiButton->setIconSize(QSize(48, 48));
ui->kuaiButton->setToolTip("加速播放");
ui->kuaiButton->show();
QPixmap pixmap7;
pixmap7.load(":/images/back.png");
ui->backButton->setFixedSize(48, 48);
ui->backButton->setIcon(pixmap7);
ui->backButton->setIconSize(QSize(48, 48));
ui->backButton->setToolTip("后退");
ui->backButton->show();
QPixmap pixmap8;
pixmap8.load(":/images/fast.png");
ui->fastButton->setFixedSize(48, 48);
ui->fastButton->setIcon(pixmap8);
ui->fastButton->setIconSize(QSize(48, 48));
ui->fastButton->setToolTip("快进");
ui->fastButton->show();
QPixmap pixmap9;
pixmap9.load(":/images/tingzhi.png");
ui->tingzhiButton->setFixedSize(48, 48);
ui->tingzhiButton->setIcon(pixmap9);
ui->tingzhiButton->setIconSize(QSize(48, 48));
ui->tingzhiButton->setToolTip("停止");
ui->tingzhiButton->show();
ui->centralWidget->setAutoFillBackground(true);//设置中心部件背景颜色
QPalette p = ui->centralWidget ->palette();
p.setColor(QPalette::Window,QColor(136, 136, 136));
ui->centralWidget->setPalette(p);
QFile dataFile("x.txt");
if (dataFile.open(QFile::ReadOnly|QIODevice::Text))
{
QTextStream data(&dataFile);
QStringList fonts;
QString line;
while (!data.atEnd())//逐行读取文本,并去除每行的回车
{
line = data.readLine();
line.remove('\n');
fonts<<line;
}
ui->listWidget->addItems(fonts);//把各行添加到listwidget
}
QObject::connect(ui->addfileButton,SIGNAL(clicked()),this,SLOT(openFileSlot()));//添加文件
QObject::connect(ui->deleteButton,SIGNAL(clicked()),this,SLOT(deleteFileSlot()));//删除文件
QObject::connect(ui->startButton,SIGNAL(clicked()),this,SLOT(zantingOrstartSlot()));//开始暂停
QObject::connect(ui->backButton,SIGNAL(clicked()),this,SLOT(backSlot()));//后退
QObject::connect(ui->fastButton,SIGNAL(clicked()),this,SLOT(forwardSlot()));//快进
QObject::connect(ui->lastButton,SIGNAL(clicked()),this,SLOT(lastSlot()));//上一个
QObject::connect(ui->nextButton,SIGNAL(clicked()),this,SLOT(nextSlot()));//下一个
QObject::connect(ui->manButton,SIGNAL(clicked()),this,SLOT(reduceSlot()));//减速
QObject::connect(ui->kuaiButton,SIGNAL(clicked()),this,SLOT(accelerateSlot()));//加速
QObject::connect(ui->tingzhiButton,SIGNAL(clicked()),this,SLOT(stopSlot()));//停止
QObject::connect(ui->voiceButton,SIGNAL(clicked()),this,SLOT(voiceSlot()));//声音静音
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::zantingOrstartSlot()//暂停或者开始
{
this->process->write("pause\n");
if(ui->startButton->toolTip() == "开始播放")
{
if(ui->listWidget->count() == 0)
{
QMessageBox::information(this,"open false","please add file first");
}
else
{
qDebug() << "connecting... ";
QObject::connect(this->process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataReceive()));
this->process->write("get_time_length\n");//打印出当前文件的长度用秒表示。总时长
this->process->write("get_time_pos\n");//打印出在文件的当前位置用秒表示,采用浮点数。时间位置,视频进度
this->process->write("get_percent_pos\n");//打印出文件中的当前位置为整数百分比[0-100]。视频进度百分比
qDebug() << "after connecting... ";
QPixmap pixmap4;
pixmap4.load(":/images/stop.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap4);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("暂停播放");
ui->startButton->show();
if(ui->listWidget->currentItem() == NULL)
{
ui->listWidget->setCurrentRow(0);
qDebug() << "Null --------- setCurrentRow(0)";
}
play(ui->listWidget->currentItem()->text());
}
}
else
{
qDebug() << "disconnecting... ";
QObject::disconnect(this->process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataReceive()));
qDebug() << "after disconnecting... ";
QPixmap pixmap3;
pixmap3.load(":/images/start.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap3);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("开始播放");
ui->startButton->show();
}
}
void MainWindow::openFileSlot()//打开文件添加列表
{
int k=0;
QStringList filenames = QFileDialog::getOpenFileNames(this,"选择文件","/",tr("视频文件(*mp3 *mp4 *wma *3gp *rmvb *mkv *ts *wmv *h264)"));
//筛选重复项
if(ui->listWidget->count() != -1)
{
//2020.11.11我认为QStringList的iterator QList::end()迭代器的最后一项,指的是结束符、空值,
//因为只选择了一个文件时,begin第一项与end最后一项不相等,从而进入For循环
for (QStringList::Iterator j=filenames.begin();j!=filenames.end();++j)
{
for(int i=0;i<ui->listWidget->count();++i)
{
if(*j == ui->listWidget->item(i)->text())//关键循环,判断某个文件路径与原有的多个视频路径是否存在相同
{
k=1;
continue;
}
}
if(k!=1)//只要K为1,某个文件路径就不需要放入listWidget播放列表,而是换下个for筛选下一个文件路径与多个已有视频路径是否存在相同
{
ui->listWidget->addItem(*j);
}
else
{
k=0;
}
}
}
else
{
if(filenames.count()!=0)
{
ui->listWidget->addItems(filenames);
}
}
//将listWidget中的项内容写入到txt文本中
QStringList lines;
QString line;
int row=0;
QFile file("x.txt");//打开该文件进入编辑模式
if(file.open(QIODevice::WriteOnly))//如果被打开
{
file.resize("x.txt",0);//清空内容
while(row<(ui->listWidget->count()))//从wistlidget里一行一行的读取文本并存入lines里边
{
line=ui->listWidget->item(row)->text();
row++;
lines<<line;
}
QTextStream stream( &file );//开始写入文本
for ( QStringList::Iterator it=lines.begin();it!=lines.end();++it )
stream<<*it<<"\r\n";//注意是"\r\n"!!!!!!如果是单个"\n" 保存文本的时候它不保留换行符!!!!
}
file.close();
}
void MainWindow::deleteFileSlot()//删除,2020.11.11不支持多条删除,只能选中一条删除
{
if(ui->listWidget->currentRow() == -1)
{
QMessageBox::information(this,"Error delete","Not select a flie or thie list is null");
}
else
{
ui->listWidget->takeItem(ui->listWidget->currentRow());//2020.11.11直接删除该item
//将listWidget中的项内容写入到txt文本中
QStringList lines;
QString line;
int row=0;
QFile file("x.txt");//打开该文件进入编辑模式
if(file.open(QIODevice::WriteOnly))//如果被打开
{
file.resize("x.txt",0);//清空内容
while(row<(ui->listWidget->count()))//从wistlidget里一行一行的读取文本并存入lines里边
{
line=ui->listWidget->item(row)->text();
row++;
lines<<line;
qDebug() << " lines == " << lines;
}
QTextStream stream( &file );//开始写入文本
for ( QStringList::Iterator it=lines.begin();it!=lines.end();++it )
stream<<*it<<"\r\n";//注意是"\r\n"!!!!!!如果是单个"\n" 保存文本的时候它不保留换行符!!!!
}
file.close();
}
}
void MainWindow::dataReceive()//接收信息
{
this->process->write("get_time_length\n");
this->process->write("get_time_pos\n");
this->process->write("get_percent_pos\n");
while(this->process->canReadLine())
{
QByteArray b(this->process->readLine());
b.replace(QByteArray("\n"), QByteArray(""));
QString s(b);
if (b.startsWith("ANS_LENGTH")) //输出视频总时间
{
int totalTimeNum = s.mid(11).toFloat();
int sec = 0, min = 0, hour = 0;
if(totalTimeNum < 60)
{
sec = totalTimeNum;
min = 0;
hour= 0;
}
else if(totalTimeNum >= 60 && totalTimeNum <3600)
{
sec = totalTimeNum%60;
min = totalTimeNum/60;
hour= 0;
}
else if(totalTimeNum > 3600)
{
sec = totalTimeNum%60;
min = totalTimeNum/60%60;
hour= totalTimeNum/3600;
}
QString totalTime = QString("%1:%2:%3").arg(hour).arg(min).arg(sec); //标准格式输出时间
ui->totletimeLable->setText(totalTime);
ui->horizontalSlider->setRange(0,totalTimeNum);
}
else if (b.startsWith("ANS_TIME_POSITION")) //输出视频当前时间
{
int currentTimeNum = s.mid(18).toFloat();
int sec = 0, min = 0, hour = 0;
if(currentTimeNum < 60)
{
sec = currentTimeNum;
min = 0;
hour= 0;
}
else if(currentTimeNum >= 60 && currentTimeNum <3600)
{
sec = currentTimeNum%60;
min = currentTimeNum/60;
hour= 0;
}
else if(currentTimeNum > 3600)
{
sec = currentTimeNum%60;
min = currentTimeNum/60%60;
hour= currentTimeNum/3600;
}
QString currentTime = QString("%1:%2:%3").arg(hour).arg(min).arg(sec);
ui->currenttimeLable->setText(currentTime);
ui->horizontalSlider->setValue(currentTimeNum);
}
else if(b.startsWith("ANS_PERCENT_POSITION"))
{
QString currentPercent = s.mid(21);
ui->precentLable->setText(currentPercent+"%");//视频播放进度百分比
}
}
}
void MainWindow::play(QString fileName)//播放
{
QStringList arg1;
this->process->kill();
this->process=new QProcess;
arg1 << fileName;
arg1 << "-slave";//默认情况下,mplayer接受键盘的命令,而"-slave"使其不再接受键盘事件,而是作为后台程序运行,
//接受以“\n”结束的命令控制,这样我们可以在进程中给他发送命令,而不需要操作键盘了.
arg1 << "-quiet"; //尽可能的不打印播放信息
// arg1 << "-fs";
arg1 << "-zoom";//视频居中,四周黑条,全屏播放(好像是默认值
arg1 << "-x";
arg1 << "720";//指定视频x方向是720大小,y方向是576大小
arg1 << "-y";
arg1 << "576";
arg1 << "-wid" << QString::number((unsigned int)(ui->widget->winId()));
// "-wid <窗口标识>" 是指让MPlayer依附于那个窗口,
//ui->widget->winId() 这个指令就是用来获取widget的标识码 ,
//这样视频播放的时候,就在这个部件里播放,相当于给他固定起来。
connect(this->process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataReceive()));
this->process->start(arg,arg1); //开始播放进程
this->setWindowTitle(fileName);//设置当前播放的视频的标题名称
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap4;
pixmap4.load(":/images/stop.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap4);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("暂停播放");
ui->startButton->show();
}
void MainWindow::on_listWidget_itemDoubleClicked(QListWidgetItem *item)//项目双击播放
{
play(item->text());
}
/**
定位视频的某些地方。
0 是一个相对定位+/- <value>(默认值)。
1 是定位<value>%在视频里。
2 是寻求一个绝对位置的<value>秒。
*/
void MainWindow::on_horizontalSlider_sliderMoved(int position)//进度条移动
{
this->process->write(QString("seek "+QString::number(position)+" 2\n").toUtf8());
}
void MainWindow::backSlot()//后退
{
this->process->write("seek -5 0\n");
}
void MainWindow::forwardSlot()//快进
{
this->process->write("seek +1 0\n");
}
void MainWindow::lastSlot()//上一个
{
if(ui->listWidget->currentRow() == 0)//当光标在第一个文件时,点击上一个光标移动到最下面的文件,不播放
{
ui->listWidget->setCurrentRow(ui->listWidget->count()-1);
}
else
{
ui->listWidget->setCurrentRow(ui->listWidget->currentRow()-1);
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap4;
pixmap4.load(":/images/stop.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap4);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("暂停播放");
ui->startButton->show();
}
play(ui->listWidget->currentItem()->text());
}
void MainWindow::nextSlot()//下一个
{
if(ui->listWidget->currentRow() == ui->listWidget->count()-1)
{
ui->listWidget->setCurrentRow(0);//当光标在最后一个文件时,点击下一个,光标移动到第一个,不播放
}
else
{
ui->listWidget->setCurrentRow(ui->listWidget->currentRow()+1);
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap4;
pixmap4.load(":/images/stop.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap4);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("暂停播放");
ui->startButton->show();
}
play(ui->listWidget->currentItem()->text());
}
void MainWindow::reduceSlot()//减速
{
speed=speed/2;
this->process->write(QString("speed_set " + QString::number(speed)+" 2\n").toUtf8());
}
void MainWindow::accelerateSlot()//加速
{
speed=speed*2;
this->process->write(QString("speed_set " + QString::number(speed) +" 2\n").toUtf8());
}
void MainWindow::stopSlot()//停止
{
this->process->write("quit\n");
ui->horizontalSlider->setSliderPosition(0);
ui->totletimeLable->clear();
ui->currenttimeLable->clear();
ui->precentLable->clear();
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap3;
pixmap3.load(":/images/start.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap3);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("开始播放");
ui->startButton->show();
}
void MainWindow::voiceSlot()//声音静音(待实现)
{
if(ui->voiceButton->toolTip() == "音量")
{
this->process->write("mute 1\n"); //开启静音
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap1;
pixmap1.load(":/images/novoice.png");
ui->voiceButton->setFixedSize(48, 48);
ui->voiceButton->setIcon(pixmap1);
ui->voiceButton->setIconSize(QSize(48, 48));
ui->voiceButton->setToolTip("静音");
ui->voiceButton->show();
}
else
{
this->process->write("mute 0\n"); //关闭静音
QPixmap pixmap;
pixmap.load(":/images/voice.png");
ui->voiceButton->setFixedSize(48, 48);
ui->voiceButton->setIcon(pixmap);
ui->voiceButton->setIconSize(QSize(48, 48));
ui->voiceButton->setToolTip("音量");
ui->voiceButton->show();
}
}
void MainWindow::on_voiceslider_sliderMoved(int position)//声音滑条
{
this->process->write(QString("volume " + QString::number(position) +" 2\n").toUtf8());
if(position == 0)
{
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap1;
pixmap1.load(":/images/novoice.png");
ui->voiceButton->setFixedSize(48, 48);
ui->voiceButton->setIcon(pixmap1);
ui->voiceButton->setIconSize(QSize(48, 48));
ui->voiceButton->setToolTip("静音");
ui->voiceButton->show();
}
else
{
QPixmap pixmap;
pixmap.load(":/images/voice.png");
ui->voiceButton->setFixedSize(48, 48);
ui->voiceButton->setIcon(pixmap);
ui->voiceButton->setIconSize(QSize(48, 48));
ui->voiceButton->setToolTip("音量");
ui->voiceButton->show();
}
}
void MainWindow::mousePressEvent(QMouseEvent *event)//鼠标单击实现视频播放暂停
{
this->process->write("pause\n");
int x=event->x();
int y=event->y();
if((x>0&&x<720)&&(y>0&&y<576))
{
if((event->button() == Qt::LeftButton)&&(ui->startButton->toolTip() == "开始播放"))
{
qDebug() << "mouse connecting... ";
QObject::connect(this->process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataReceive()));
this->process->write("get_time_length\n");
this->process->write("get_time_pos\n");
this->process->write("get_percent_pos\n");
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap7;
pixmap7.load(":/images/stop.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap7);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("暂停播放");
ui->startButton->show();
this->statusBar()->showMessage("开始",3*1000);//显示此时的状态,显示3秒
}
//不能用此语句,要用else
// if((event->button() == Qt::LeftButton)&&(ui->startButton->toolTip() == "暂停播放"))
else
{
QObject::disconnect(this->process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataReceive()));
QPixmap pixmap;
pixmap.load(":/images/voice.png");
QPixmap pixmap3;
pixmap3.load(":/images/start.png");
ui->startButton->setFixedSize(48, 48);
ui->startButton->setIcon(pixmap3);
ui->startButton->setIconSize(QSize(48, 48));
ui->startButton->setToolTip("开始播放");
ui->startButton->show();
this->statusBar()->showMessage("暂停",3*1000);//显示此时的状态,显示3秒
}
}
}
效果: