寫了一個音樂播放器,想要實現音樂搜索功能。思路是本地寫個簡單的服務器,然後將音樂傳輸到客戶端,每傳一些然後就播放一點於是去查API
發現Phonon框架包括MediaObject,Sink,Path。大概就是mediaObject的數據傳到相應的硬件設備然後播放出來。而mediaObject的數據為mediaSource。因此去查mediaSource,發現其數據來源可以是本地mp3文件,或者url或者一個QIODevice。API中有個QBuffer的使用例子,它是一個QIODevice的子類,因此想的是先調用mediaObject.setCurrentSource(buf),將指向這個buf的指針傳進去,也就是將這塊buf和媒體對象關聯起來(此時buf中還沒數據)。那麼之後客戶端的socket沒接收到一些數據就將這些數據寫入到這個buf中,因此buf是動態變化的,那麼應該就能實現傳過來多少就播放多少。於是便開始寫代碼了。
OK,代碼寫完。。問題來了,當檢測到文件傳完後,調用mediaObject.play()發現並沒有啥反應,但是我把mediaObject.setCurrentSource放到buf已經接收完所有數據後卻能播放!我感覺就是,關聯的數據源為一個IO類型的數據流時,必須是其中已經存在完整的媒體數據後才行。也就是在接收數據前關聯,每當buf中數據有變動時,mediaObject並沒有去檢測它的改變,或者說檢測了但是因為數據不完整所以不能播放。
是我理解錯了還是?代碼哪有問題呢。。如果理解錯了應該怎麼去做,麻煩懂的前輩給個思路。。謝謝了。寫的比較亂,希望能看懂。。
具體代碼如下:
#include "tcpclient.h"
#include <QDir>
TcpClient::TcpClient(QObject *parent) :
QObject(parent)
{
file = new QFile("123.mp3");
data = new QByteArray();
buffer = new QBuffer(data);//buffer = new MyBuffer(data);
Phonon::createPath(&mediaObject,&audioOutput);
audioOutput.setVolume(1.0);
mediaObject.setCurrentSource(buffer);
//opened=file->open(QIODevice::ReadWrite);
QString ip("192.168.71.128");
quint16 port=5555;
tcpClient.connectToHost(ip,port);
connect(this,SIGNAL(finishedRecv()),this,SLOT(playMus()));
connect(&mediaObject,SIGNAL(stateChanged(Phonon::State,Phonon::State)),this,SLOT(printError(Phonon::State,Phonon::State)));
connect(&tcpClient,SIGNAL(connected()),this,SLOT(connectSuc()));
connect(&tcpClient,SIGNAL(readyRead()),this,SLOT(recvData()));
connect(&tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(displayError(QAbstractSocket::SocketError)));
}
void TcpClient::displayError(QAbstractSocket::SocketError)
{
qDebug()<<"error:"<<tcpClient.errorString();
tcpClient.close();
}
void TcpClient::recvData()
{
QByteArray btArray;
//qDebug()<<"recv data";
btArray=tcpClient.readAll();
if(btArray.contains("finish"))
{
qDebug()<<"finish";
btArray=btArray.left(btArray.size()-6);
data->append(btArray);
//file->write(btArray);
emit finishedRecv();
tcpClient.close();
}
data->append(btArray);
//file->write(btArray);
}
void TcpClient::connectSuc()
{
qDebug()<<"connect suc";
}
void TcpClient::playMus()
{
//file->close();
qDebug()<<"play now:";
mediaObject.setCurrentSource(buffer);
mediaObject.play();
}
void TcpClient::printError(Phonon::State newState,Phonon::State oldState)
{
qDebug()<<"----------------------";
qDebug()<<"oldstate:"<<oldState;
qDebug()<<"newState:"<<newState;
qDebug()<<"----------------------";
}
在Linux上配置Apache,把音樂文件放在web站點下傳地址了。。