4
0
mirror of https://github.com/QuasarApp/SoundBand.git synced 2025-05-08 13:09:33 +00:00

added a create package method

This commit is contained in:
Andrei Yankovich 2017-11-20 00:37:12 +03:00
parent c732a3d8bc
commit 285f068358
9 changed files with 217 additions and 65 deletions

@ -70,7 +70,7 @@ void ETcpSocket::readReady_(){
{
array->remove(0,sizeof(qint32));
ReadyStack.push_back(array);
array=new QByteArray;
array=new QByteArray();
emit Message(this);
}else{
emit donwload(array->size(),size);
@ -93,8 +93,9 @@ QTcpSocket* ETcpSocket::getSource()const{
}
void ETcpSocket::nextItem(){
if(ReadyStack.size())
if( ReadyStack.size()){
ReadyStack.pop_front();
}
}
int ETcpSocket::sizeDescriptPackege(){

@ -4,6 +4,27 @@
#include <QTcpServer>
#include <QList>
#include <QDataStream>
/**
* @brief The ETcpSocket class
* example :
* ETcpSocket *tcp;
* try{
* tcp = new ETcpSocket(addres,port);
* }catch(addNodeExaption e){
* e.what();
* }
* QByteArray *array;
* while(array = tcp.getSource()){
* package pkg(*array);
* package ans = ansver(pkg);
* tcp.Write(ans);
* array->clear();
* delete array;
*
* }
*
*/
class ETcpSocket:public QObject
{
Q_OBJECT

@ -12,6 +12,7 @@
// network config
#define DEDAULT_PORT 1239
#define MAX_SYNC_TIME 10 * 1000 * 1000 // 10 sec on microsec
#define MAX_SYNC_TIME 20 * 1000 // 10 sec on microsec
#define SYNC_TIME 5 * 1000 // 5 sec on microsec
#endif // CONFIG_H

@ -6,11 +6,7 @@
namespace syncLib{
package::package(){
type = package::t_void;
source.clear();
playdata.run = 0;
playdata.seek = 0;
size = 0;
clear();
}
package::package(const QByteArray &array):
package::package(){
@ -24,42 +20,51 @@ Syncer package::getPlayData() const{
return playdata;
}
package::TypePackage package::getType() const{
TypePackage package::getType() const{
return type;
}
bool package::isValid() const{
switch (type) {
case package::t_void:
case TypePackage::t_void:
return false;
case package::t_close:
case TypePackage::t_close:
return true;
case package::t_sync:
case TypePackage::t_sync:
return playdata.run > 0 && playdata.seek > 0;
case package::t_song:
case TypePackage::t_song:
return source.size > 0;
case package::t_stop:
case TypePackage::t_song_h:
return header.size > 0;
case TypePackage::t_stop:
return true;
default:
return false;
}
}
void package::clear(){
type = TypePackage::t_void;
source.clear();
playdata.run = 0;
playdata.seek = 0;
}
QByteArray package::parseTo(){
QByteArray temp;
QDataStream stream(temp);
temp.clear();
if(isValid()){
switch (type) {
case package::t_void:
case TypePackage::t_void:
break;
case package::t_close:
case TypePackage::t_close:
stream << int();
stream << (unsigned char)(type);
stream.device()->seek(0);
stream << temp.size();
break;
case package::t_sync:
case TypePackage::t_sync:
stream << int();
stream << (unsigned char)(type);
stream << playdata.run;
@ -67,14 +72,21 @@ QByteArray package::parseTo(){
stream.device()->seek(0);
stream << temp.size();
break;
case package::t_song:
case TypePackage::t_song:
stream << int();
stream << (unsigned char)(type);
stream << source;
stream.device()->seek(0);
stream << temp.size();
break;
case package::t_stop:
case TypePackage::t_song_h:
stream << int();
stream << (unsigned char)(type);
stream << header;
stream.device()->seek(0);
stream << temp.size();
break;
case TypePackage::t_stop:
stream << int();
stream << (unsigned char)(type);
stream.device()->seek(0);
@ -88,21 +100,24 @@ QByteArray package::parseTo(){
}
bool package::parseFrom(const QByteArray &array){
type = t_void;
type = TypePackage::t_void;
QDataStream stream(array);
switch (type) {
case package::t_void:
case TypePackage::t_void:
return false;
case package::t_close:
case TypePackage::t_close:
return true;
case package::t_sync:
case TypePackage::t_sync:
stream >> playdata.run;
stream >> playdata.seek;
return isValid();
case package::t_song:
case TypePackage::t_song:
stream >> source;
return isValid();
case package::t_stop:
case TypePackage::t_song_h:
stream >> header;
return isValid();
case TypePackage::t_stop:
return true;
default:
return isValid();

@ -6,6 +6,23 @@
class Syncer;
namespace syncLib {
/**
* @brief The TypePackage enum
* t_void - this package empty and not valid.
* t_close - the information about close channel.
* t_sync - the infomation about sync playning media file on network.
* t_song - the package with this type is necessary for translite media data on network.
* t_stop - the package with type 'stop' necessary for stoping playning media files.
*/
enum TypePackage{
t_void = 0x0,
t_close = 0x1,
t_sync = 0x2,
t_song_h = 0x4,
t_song = 0x8,
t_stop = 0x10
};
/**
* @brief The package class. Package for translite media data on network
*
@ -23,25 +40,11 @@ class package
* 4 byte - size of data of package (it avelable if type is t_sync or t_song)
* data
*/
/**
* @brief The TypePackage enum
* t_void - this package empty and not valid.
* t_close - the information about close channel.
* t_sync - the infomation about sync playning media file on network.
* t_song - the package with this type is necessary for translite media data on network.
* t_stop - the package with type 'stop' necessary for stoping playning media files.
*/
enum TypePackage{
t_void = 0x0,
t_close = 0x1,
t_sync = 0x2,
t_song = 0x4,
t_stop = 0x8
};
private:
TypePackage type;
unsigned int size;
Song source;
SongHeader header;
Syncer playdata;
public:
package();
@ -59,8 +62,10 @@ public:
Syncer getPlayData() const;
TypePackage getType() const;
bool isValid() const;
void clear();
QByteArray parseTo();
bool parseFrom(const QByteArray& array);
friend class Sync;
};
class Node:public QTcpServer{

@ -4,7 +4,7 @@ namespace syncLib{
SongHeader::SongHeader()
{
this->id = 0;
this->id = -1;
this->name = "";
this->size = 0;
}

@ -7,7 +7,7 @@
/**
* @brief Time_point on nanosecunds (uint64_t)
*/
typedef quint64 microseconds;
typedef quint64 milliseconds;
namespace syncLib {
@ -20,11 +20,11 @@ struct Syncer
/**
* @brief seek - wher is play media file
*/
unsigned int seek;
milliseconds seek;
/**
* @brief run when is play media file (int)
*/
microseconds run;
milliseconds run;
};
/**

@ -3,8 +3,6 @@
#include <QMultimedia>
#include <QMediaPlayer>
#include <QSqlQuery>
#include "song.h"
#include "node.h"
#include "exaptions.h"
#include "time.h"
#include "thread"
@ -55,14 +53,37 @@ int Sync::save(const Song &song){
return qyery->value(0).toInt();
}
bool Sync::load(const SongHeader &song,Song &result){
result.clear();
if(song.id > -1){
QString qyer = QString("SELECT * from %0 where id=%1").arg(DATATABLE_NAME).arg(song.id);
if(!qyery->exec(qyer)){
return false;
}
}else if(!song.name.isEmpty() && song.size > 0){
QString qyer = QString("SELECT * from %0 where name=%1 and size=%2").arg(DATATABLE_NAME).arg(song.name).arg(song.size);
if(!qyery->exec(qyer)){
return false;
}
}else {
return false;
}
result.id = qyery->value(0).toInt();
result.name = qyery->value(1).toString();
result.size = qyery->value(2).toInt();
result.source = qyery->value(3).toByteArray();
return true;
}
/*
* information about chrono
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
*/
microseconds Sync::now(){
milliseconds Sync::now(){
auto tim = std::chrono::system_clock::now();
auto mc = std::chrono::time_point_cast<std::chrono::microseconds>(tim);
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
auto epoh = mc.time_since_epoch();
#ifdef QT_DEBUG
qDebug() << epoh.count();
@ -70,29 +91,37 @@ microseconds Sync::now(){
return epoh.count();
}
Clock Sync::from(const microseconds& mc){
std::chrono::duration<long> dur(mc);
Clock Sync::from(const milliseconds& mc){
std::chrono::milliseconds dur(mc);
return Clock(dur);
}
bool Sync::Play(SongHeader &header, Syncer *syncdata){
QString qyer = QString("SELECT * from %0 where name=%1 and size=%2").arg(DATATABLE_NAME).arg(header.name).arg(header.size);
if(!qyery->exec(qyer)){
return false;
}
Song song;
song.id = qyery->value(0).toInt();
song.name = qyery->value(1).toString();
song.size = qyery->value(2).toInt();
song.source = qyery->value(3).toByteArray();
return Sync::Play(song,syncdata);
}
bool Sync::Play(Song& song, Syncer *syncdata){
QBuffer buffer(&song.source);
player->setMedia(QMediaContent(), &buffer);
if(syncdata){
microseconds sync_time = syncdata->run - now();
if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
return false;
Clock run_time = from(syncdata->run);
do {
std::this_thread::yield();
} while (std::chrono::high_resolution_clock::now() < run_time);
player->setPosition(syncdata->seek);
if(syncdata && !sync(*syncdata)){
return false;
}
fbroadcaster = !bool(syncdata);
player->play();
playList->push_front(static_cast<SongHeader>(song));
return true;
}
bool Sync::Play(int id_song){
bool Sync::Play(int id_song, Syncer *syncdata){
QString qyer = QString("SELECT * from %0 where id=%1").arg(DATATABLE_NAME).arg(id_song);
if(!qyery->exec(qyer)){
@ -103,7 +132,7 @@ bool Sync::Play(int id_song){
song.name = qyery->value(1).toString();
song.size = qyery->value(2).toInt();
song.source = qyery->value(3).toByteArray();
return Sync::Play(song);
return Sync::Play(song,syncdata);
}
bool Sync::Play(QString url){
@ -136,6 +165,56 @@ void Sync::jump(const int seek){
player->setPosition(seek);
}
bool Sync::sync(const Syncer &sync){
milliseconds sync_time = sync.run - now();
if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
return false;
Clock run_time = from(sync.run);
do {
std::this_thread::yield();
} while (std::chrono::high_resolution_clock::now() < run_time);
player->setPosition(sync.seek);
return true;
}
bool Sync::createPackage(TypePackage type, package &pac){
pac.clear();
if(type & TypePackage::t_close){
pac.type = type;
}else if(type & TypePackage::t_sync){
if(!fbroadcaster)
return false;
pac.type = type;
pac.playdata.run = now() + SYNC_TIME;
pac.playdata.seek = player->position() + SYNC_TIME;
}else if(type & TypePackage::t_song_h){
if(!fbroadcaster || playList->isEmpty())
return false;
pac.type = type;
pac.header = playList->front();
}else if(type & TypePackage::t_song){
if(!fbroadcaster || playList->isEmpty())
return false;
pac.type = type;
if(!load(playList->front(), pac.source))
return false;
}else if(type & TypePackage::t_stop){
pac.type = type;
}else{
return false;
}
return pac.isValid();
}
Sync::~Sync(){
delete node;
delete db;
@ -144,3 +223,4 @@ Sync::~Sync(){
}

@ -1,6 +1,7 @@
#ifndef SYNC_H
#define SYNC_H
#include "song.h"
#include "node.h"
#include <chrono>
class QSqlDatabase;
class QMediaPlayer;
@ -21,11 +22,20 @@ private:
Node *node;
QSqlDatabase *db;
QMediaPlayer *player;
QList<SongHeader>* playList;
QSqlQuery *qyery;
bool fbroadcaster;
/**
* @brief initDB initialize local database of song
*/
void initDB();
/**
* @brief load song of database;
* @brief song -
* @brief result - the resulting value;
* @return true if everything's done
*/
bool load(const SongHeader &song, Song &result);
/**
* @brief save media data into local database.
* @param song savining media data.
@ -42,14 +52,28 @@ private:
* @brief now - get now time on microsecunds
* @return - count of microsecunds
*/
microseconds now();
milliseconds now();
/**
* @brief from cast to chrono secunds
* @param mcrs microseconds of uint_64
* @return microseconds of chrono
*/
Clock from(const microseconds &mcrs);
Clock from(const milliseconds &mcrs);
/**
* @brief createPackage - Create a package that shows current state of the node
* @param type - Type of an answer
* @param pac - the resulting value
* @return true if everything's done
*/
bool createPackage(TypePackage type ,package& pac);
public:
/**
* @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption.
* @param header of song
* @param syncdata data of synbced playning of media data.
* @return true if all done else false.
*/
bool Play(SongHeader &header, Syncer* syncdata = nullptr);
/**
* @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption.
* @param song playning media data.
@ -68,7 +92,7 @@ public:
* @param id_song of song.
* @return true if all done else false.
*/
bool Play(int id_song);
bool Play(int id_song, Syncer* syncdata = nullptr);
/**
* @brief Pause playning song.
*/
@ -82,6 +106,11 @@ public:
* @param seek - a new position of media data.
*/
void jump(const int seek);
/**
* @brief sync with server
* @param sync - data of sync
*/
bool sync(const Syncer& sync);
Sync();
~Sync();
};