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スレッドを起動すればいいです.以下のとおりです
mplaerを制御するなら、QProcessのwrite方法を使って、mplayerにコマンドを書き込むだけでいいです.
mplayerから発信されたメッセージを読み取るには、QProcessのreadLineメソッドを使って、次のようにします.
三、MPlayerコマンド大全
1.mplayercal.h
一、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;
}