Qt 5下QProcess+MPlayer QT音楽再生クラスを実現します.

42562 ワード

Qt 5下QProcess+MPlayer QT音楽再生クラスを実現します.
一、QProcessを使ってMPlayerを呼び出した理由
最初はQt 5を使って、Qt 5マルチメディアで使用されたQMediaPlayerを再生しましたが、QMediaPlayerはgstreamバックエンドを使ってメディアを再生しました.gstreamはarmに移植できませんでした.Qt 4に変えて、phonon+mplayerを使う案を準備します.しかし、後にQt 4とphononとphonon_をコンパイルしました.backend(libphonomplayer.so)の後、プログラムの中でmplyerを呼び出すことができません.何の原因か分かりません.backendコンパイルの方法が間違っていますよね.そこで最終的には、Qt 5に戻るか、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
"
);
このように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.mplayercal.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.mplayercal.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
"
); _isPlaying = true; } } /************************************************************************** * stop play * ***********************************************************************/ void MPlayerCall::pause(void) { if(_isPlaying) { _process->write("pause
"
); _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
"
); } /************************************************************************ * send a command to get the time position ***********************************************************************/ void MPlayerCall::getTimePos(void) { _mplayerWriteCmd("get_time_pos
"
); } /************************************************************************* * send a command to get the media file time length * *********************************************************************/ void MPlayerCall::getTimeLen(void) { _mplayerWriteCmd("get_time_length
"
); } /************************************************************************** * set the played percent *************************************************************************/ void MPlayerCall::seek(int percent) { _mplayerWriteCmd("seek " + QString::number(percent) + " 1
"
); 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] != '
'
) && (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; }