Qt5下QProcess + MPlayer实现QT音乐播放类

Qt5下QProcess + MPlayer实现QT音乐播放类


一、使用QProcess来调用MPlayer原因

起初由于使用的Qt5,Qt5多媒体播放使用的QMediaPlayer,而QMediaPlayer使用gstreamer后端来播放媒体,gstreamer又不能移植到arm(貌似可以,只是很麻烦)。于是换成Qt4,准备使用phonon + mplayer的方案。可是在后来编译好qt4和phonon以及phonon_backend(libphonon_mplayer.so)之后,在程序中并不能调出mplyer来,不知道是什么原因,估计是phonon_backend编译方法不对吧。于是最后决定,还是换回Qt5,使用QProcess直接调MPlayer的方式来实现。

二、QProcess调用MPlayer方法

我们只需要new一个QProcess,然后通过QProcess的start方法启动mplayer线程即可。如下:

	_process = new QProcess();
    QStringList args;
    args << "-slave"; //使用slave模式
    args << "-quiet"; //不要输出冗余信息
    _process->start("mplayer", args); //启动该进程,并传入参数args

这样,便可以启动mplayer。

如果我们要控制mplaer呢,使用QProcess的write方法,往mplayer写入命令即可,比如如下:

process->write("pause\n");

这样便可以对mplayer播放进行控制(播放/暂停)。

如果要读取mplayer发出来的消息呢,使用QProcess的readLine方法,方式如下:

_process->readLine(data,200);

这样便可以读取一行mplayer发送出来的信息,然后我们只需要解析这个data即可。

三、MPlayer命令大全

loadfile name		//加载媒体文件name
volume 100 1		//设置音量,中间位音量的大小0-100
mute 1/0			//静音开关
pause				//播放/暂停
get_time_length		//获取播放文件的长度,以秒为单位
seek value			//定位,valu为秒数
get_percent_pos		//获取播放的百分比
get_time_pos		//获取当前播放的位置,以秒为单位
get_file_name		//获取当前播放的媒体文件名
get_meta_album		//获取专辑
get_meta_artist		//获取艺术家
get_meta_comment	//获取评论
get_meta_genre		//获取流派
get_meta_title		//获取标题
get_meta_year		//获取年份

四、附录–音乐播放类源码

1.mplayercall.h
#ifndef MPLAYERCALL_H
#define MPLAYERCALL_H

#include 
#include 

class MPlayerCall : public QObject
{
    Q_OBJECT

public:
    enum MplayerAns //mplayer回复命令
    {
        ANS_TIME_POSITION,    	//current time
        ANS_PERCENT_POSITION,	//percent
        ANS_LENGTH,        	 //all time
        ANS_EXIT,
    };
    typedef struct//mplayer回复消息结构
    {
        MplayerAns ans;//命令
        int value;	//值
    } MplayerReturn;

    static MPlayerCall& construction(void)
    {
        static MPlayerCall obj;
        return obj;
    }
    MPlayerCall();
    virtual ~MPlayerCall();
    void setMusic(const QString name);//设置待播放音乐但不播放
    void setMusicPlay(const QString name);//设置音乐并播放
    void pause(void);//暂停
    void play(void);//播放
    void setVolume(unsigned char volume);//设置音量
    void getTimePos(void);//获取当前播放的时间
    void getTimeLen(void);//获取音乐文件总长
    void seek(int percent);//定位
    virtual void timerEvent( QTimerEvent *event);//定时器事件

private:
    void _mplayerWriteCmd(QString cmd);
    void _mplayerReadMessages(void);
    QProcess *_process;
    bool _isPlaying;
    unsigned char _volume;
    int _timer1SID;
    int _timer100MsID;

public slots:

signals:
    void mplayerReturnValue(MplayerReturn);//mplayer回复消息信号
};

#endif // MPLAYERCALL_H

#define mplayerCall MPlayerCall::construction()

2.mplayercall.cpp
#include "mplayercall.h"
#include "QDebug"
#include 
#include 

#define TIMER_1SECOND    1000
#define TIMER_100MSECOND 100

static bool seeked = false;

/**************************************************************************
 * init the mplayer
 * ***********************************************************************/
MPlayerCall::MPlayerCall()
{
    _isPlaying = false;
    _volume = 80;

    _process = new QProcess();
    _process->setProcessChannelMode(QProcess::ForwardedErrorChannel);

    QStringList args;
    args << "-slave"; //使用slave模式
    args << "-quiet"; //不要输出冗余信息
    _process->start("mplayer", args); //启动该进程,并传入参数args

    _timer1SID = this->startTimer(TIMER_1SECOND);
    _timer100MsID = this->startTimer(TIMER_100MSECOND);
}

/************************************************************************
 * start play a music
 * *********************************************************************/
void MPlayerCall::play(void)
{
    if(!_isPlaying)
    {
        _process->write("pause\n");
        _isPlaying  = true;
    }
}

/**************************************************************************
 * stop play
 * ***********************************************************************/
void MPlayerCall::pause(void)
{
    if(_isPlaying)
    {
        _process->write("pause\n");
        _isPlaying = false;
    }
}

/**************************************************************************
 * set a music but not play
 * ************************************************************************/
void MPlayerCall::setMusic(const QString name)
{
    if(_process != NULL)
    {
        _process->kill();
    }
    _process = new QProcess();

    QStringList args;
    args << "-slave"; //使用slave模式
    args << "-quiet"; //不要输出冗余信息
    args << name; //播放file_name文件
    _process->start("mplayer", args); //启动该进程,并传入参数args
    setVolume(_volume);
    pause();
    getTimeLen();
}

/**************************************************************************
 * set a music and play
 * ***********************************************************************/
void MPlayerCall::setMusicPlay(const QString name)
{
    if(_process != NULL)
    {
        _process->kill();
    }
    _process = new QProcess();

    QStringList args;
    args << "-slave"; //使用slave模式
    args << "-quiet"; //不要输出冗余信息
    args << name; //播放file_name文件
    _process->start("mplayer", args); //启动该进程,并传入参数args
    setVolume(_volume);
    _isPlaying = true;
    getTimeLen();
}

/*************************************************************************
 * set the volume
 * ************************************************************************/
void MPlayerCall::setVolume(unsigned char volume)
{
    if(_process == NULL)
    {
        return;
    }
    _volume = volume;
    _mplayerWriteCmd("volume " + QString::number(volume) + " 2\n");
}

/************************************************************************
 * send a command to get the time position
 ***********************************************************************/
void MPlayerCall::getTimePos(void)
{
    _mplayerWriteCmd("get_time_pos\n");
}

/*************************************************************************
 * send a command to get the media file time length
 * *********************************************************************/
void MPlayerCall::getTimeLen(void)
{
    _mplayerWriteCmd("get_time_length\n");
}

/**************************************************************************
 * set the played percent
 *************************************************************************/
void MPlayerCall::seek(int percent)
{
    _mplayerWriteCmd("seek " + QString::number(percent) + " 1\n");
    seeked = true;
    getTimePos();
}

/***********************************************************************
 * write command to mplayer
 * *******************************************************************/
void MPlayerCall::_mplayerWriteCmd(QString cmd)
{
    if(_process == NULL)
    {
        return;
    }
    _process->write(cmd.toUtf8());
}

/*************************************************************************
 * read the messages form mplayer
 * **********************************************************************/
void MPlayerCall::_mplayerReadMessages(void)
{
    while(_process->canReadLine())
    {
        char data[200];

        memset(data, 0, 200);
        _process->readLine(data,200);
        if((data[0] == 'E') && (data[1] == 'x') && (data[2] == 'i') && (data[3] == 't'))//exit
        {
            if(_isPlaying)
            {
                MplayerReturn mpRet;
                mpRet.ans = ANS_EXIT;
                emit mplayerReturnValue(mpRet);
            }
        }
        else if((data[0] == 'A') && (data[1] == 'N') && (data[2] == 'S'))
        {
            MplayerReturn mpRet;
            QString ans = NULL;
            QString value = NULL;

            int i = 4;
            while(data[i] != '=')
            {
                ans += data[i];
                i++;
            }
            i++;
            while((data[i] != '\n') && (data[i] != '.'))
            {
                value += data[i];
                i++;
            }
            mpRet.value = value.toInt();
            if(ans == "LENGTH")
            {
                mpRet.ans = ANS_LENGTH;
                emit mplayerReturnValue(mpRet);
            }
            else if(ans == "TIME_POSITION")
            {
                if(!seeked)
                {
                    mpRet.ans = ANS_TIME_POSITION;
                    emit mplayerReturnValue(mpRet);
                }
                else
                {
                    seeked = false;
                }
            }
            else if(ans == "PERCENT_POSITION")
            {
                mpRet.ans = ANS_PERCENT_POSITION;
                emit mplayerReturnValue(mpRet);
            }
        }
    }
}

/************************************************************************
 * timer event
 * *********************************************************************/
void MPlayerCall::timerEvent(QTimerEvent * event)
{
    if(event->timerId() == _timer100MsID)
    {
        _mplayerReadMessages();
    }
    else if(event->timerId() == _timer1SID)
    {
        if(_isPlaying)
        {
            getTimePos();
        }
    }
}

/*************************************************************************
 * delete private
 * **********************************************************************/
MPlayerCall::~MPlayerCall()
{
    _process->kill();
    delete _process;
}

你可能感兴趣的:(Qt)