目录
作用
可以播放视频和音频
linux下载
sudo apt install mplayer
arm下载
由于arm版本qt没有多媒体模块,只能使用第三方播放器(mplayer或者madplay),对于arm平台而言,它就相当于一个可执行文件,可以当做命令来使用,在linux下可以使用system函数来执行mplayer,将播放音乐的命令集成到程序中,在qt中把mplayer当做是一个进程QProoess,那么,可以使用它来播放音乐
- 下载mplayer源码,进行交叉编译配置生成一个程序,一般都有现成的
- 将程序放到板子上的/bin目录下加权限
- 添加环境
使用方法
键盘
- mplayer xxx,xxx是播放的视频,可以通过键盘来控制
命令
- mplayer -slave -quiet xxx,xxx是播放的视频
- -slave是表示用命令的方式
- -quiet是表示不输出多余的信息
- 进入之后可以输入命令词来进行控制视频
命令词有很多,举例几个
- pause是暂停/播放
- seek xx快进xx秒,如果是负数就是后退
- get_time_length返回播放文件的长度,多少秒
- get_file_name返回当前播放文件的名字
- get_meta_year返回当前播放文件的年份
在arm上qt实战
在linux上用交叉编译后将可执行文件放到开发板上,再安装第三方播放器,就可以运行了
配置ui界面
添加头文件,成员,函数
#include <QProcess>
#include <QListWidgetItem>
#include <QFileDialog>
#include <QDebug>
#include <QThread>
#include <QTime>
#include <QPoint>
private:
QProcess *m_process;//进程指针
int index;//歌曲索引
添加视频按钮点击事件
//弹出选择文件对话框,并返回选择文件的路径
QStringList lists = QFileDialog::getOpenFileNames(this,"add video","","video file (*.mp4 *.MP4 *.avi)");
//将添加的文件显示到列表上
for(int i=0; i<lists.size(); i++){
//新建一个选项
QListWidgetItem *item = new QListWidgetItem;
//选项设置图标
item->setIcon(QIcon(":/new/prefix1/pic/video.png"));
//将路径名字写入选项
item->setText(lists.at(i).toLocal8Bit());
//将选项加入到列表上
ui->listWidget->addItem(item);
}
列表选项双击事件
//获取列表的第几首歌曲
index = ui->listWidget->currentRow();
//并执行播放
on_btn_player_clicked();
播放按钮点击事件
//先停止当前视频
on_btn_stop_clicked();
//获取并打印显示视频的控件的全局坐标和长宽
int posX = ui->label_videoShow->mapToGlobal(QPoint(0, 0)).x();
int posY = ui->label_videoShow->mapToGlobal(QPoint(0, 0)).y();
int width = ui->label_videoShow->width();
int height = ui->label_videoShow->height();
qDebug()<<"geometry posX:"<<posX<<"\tgeometry posY:"<<posY;
qDebug()<<"width:"<<width<<"\theight:"<<height;
//组合视频播放字符串命令
QString cmd = QString::fromLocal8Bit("mplayer -slave -quiet -geometry %1:%2 -zoom -x %3 -y %4 %5 &")
.arg(posX)
.arg(posY)
.arg(width)
.arg(height)
.arg(ui->listWidget->item(index)->text());//视频名字
//通过进行来运行命令
m_process->start(cmd.toLocal8Bit().data());
//get_time_length返回播放文件的长度,以秒为单位 ANS_LENGTH=264.00
m_process->write("get_time_length\n");
//关联当进程运行命令的后返回结果时就会发出readyRead信号,会执行onRecvData槽函数
//等于执行ls命令获取目录,当ls命令产生任何输出时,就会发出readyRead信号
connect(m_process,&QProcess::readyRead,this,&MainWindow::onRecvData);
暂停继续按钮点击事件
//向进程写入命令
m_process->write("pause\n");
停止按钮点击事件
//判断进程是否在运行,在运行就杀死进程
if(m_process->state() == QProcess::Running){
m_process->kill();
}
//等待直到子进程完成其工作或遇到错误并退出
m_process->waitForFinished();
上一首按钮点击事件
//将索引加一
index = --index < 0 ? (ui->listWidget->count()-1) :index;
//并执行播放
on_btn_player_clicked();
下一首按钮点击事件
//ui->listWidget->count();返回列表有多少哥选项
//将索引加一
index = ++index % ui->listWidget->count();
//并执行播放
on_btn_player_clicked();
快进按钮点击事件
//向进程写入命令
m_process->write("seek +10\n");
快退按钮点击事件
//向进程写入命令
m_process->write("seek -10\n");
静音按钮点击事件
//向进程写入命令
m_process->write("mute\n");
音量滑动条拖动事件
//显示当前播放的音量数值
ui->label_volumeValue->setText(QString::fromLocal8Bit("当前音量:%1").arg(position));
运行命令返回结果的槽函数
//运行命令的后的槽函数
void MainWindow::onRecvData()
{
//获取并打印运行命令返回的数据
QString data = m_process->readAll();
qDebug()<<data;
//从 m_process 读取的数据中是否包含字符串 "ANS_LENGTH"。如果包含,说明数据中包含了文件的时间长度信息
//获取文件时间长度 ANS_LENGTH=264.00
if(data.contains("ANS_LENGTH")){
//返回来的时间长度是浮点型,必须转成浮点型,如果转成int 会转换失败
bool ok;
//首先移除 "ANS_LENGTH=" 字符串和换行符再转为浮点型
double timeLength = data.remove("ANS_LENGTH=").remove("\n").toDouble(&ok);
//判断有没有获取到数据
if(ok){
//创建一个时间对象,从0开始
QTime timeFormat(0,0,0);
//加入前面获取到的文件时间长度
timeFormat = timeFormat.addSecs(timeLength);
//显示时间长度
ui->label_timeLength->setText(timeFormat.toString());
//设置 时间长度滑动进度条的最大值为时间长度
ui->horizontalSlider_seek->setMaximum(timeLength);
}else{
qDebug()<<"string to double error";
}
}
}
c调用播放器
在启动mplaver播放器的时候,使用选项参数 -input file=/tmp/fifo 将有名管道文件 传递给mplaver播放器进程,此时该mplaver播放器进程执行的时候,会打开该有名管道文件,Mplaver从有名管道读到主进程发送的命令。然后在编程中 往有名管道文件中 输入相关slave命令,达到控制播放器的效果。但是,如果使用get_fle_name等命令想要获取 从mplaver播放器 返回的数据,则还需要创建一个无名管道文件,然后再创建一个子进程,把子进程的标准输出重定向无名管道的写端,Mplayer发出的内容发送到无名管道中,父进程通过读管道就可以读到Mplayer发出的信息。
代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int fifofd;
int init_open()
{
//创建管道文件 --mkfifo
int ret = mkfifo("/tmp/fifo",0777);
if(ret==-1)
{
perror("mkfifo error");
return -1;
}
//打开管道文件
fifofd = open("/tmp/fifo",O_RDWR);
if(fifofd==-1)
{
perror("open fifo error");
return -1;
}
}
int write_cmd(char *cmd)
{
//往管道写命令
write(fifofd,cmd,strlen(cmd));
}
int main(void)
{
//初始化管道
init_open();
//使用slave命令,将管道和播放器绑定在一起
system("mplayer -slave -quiet -input file=/tmp/fifo 1.mp3 &");
while(1)
{
write_cmd("seek +10\n");
sleep(3);
}
close(fifofd);
return 0;
}