写了一个音乐播放器,想要实现音乐搜索功能。思路是本地写个简单的服务器,然后将音乐传输到客户端,每传一些然后就播放一点于是去查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()<<"----------------------";
}