mirror of
https://github.com/QuasarApp/SoundBand.git
synced 2025-04-28 16:24:32 +00:00
fix sync nodes
This commit is contained in:
parent
17dabbaf6b
commit
acd5191c0e
@ -40,6 +40,7 @@ void ETcpSocket::error_(QAbstractSocket::SocketError i){
|
||||
}
|
||||
|
||||
void ETcpSocket::connected_(){
|
||||
calibration();
|
||||
emit Connected(this);
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,14 @@ ChronoTime::ChronoTime()
|
||||
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
|
||||
*/
|
||||
|
||||
milliseconds ChronoTime::now(){
|
||||
milliseconds ChronoTime::now(int calibration){
|
||||
auto tim = std::chrono::system_clock::now();
|
||||
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
|
||||
auto epoh = mc.time_since_epoch();
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << epoh.count();
|
||||
#endif
|
||||
return epoh.count();
|
||||
return epoh.count() + calibration;
|
||||
}
|
||||
|
||||
Clock ChronoTime::from(const milliseconds& mc){
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
* @brief now - get now time on microsecunds
|
||||
* @return - count of microsecunds
|
||||
*/
|
||||
static milliseconds now();
|
||||
static milliseconds now(int calibration = 0);
|
||||
/**
|
||||
* @brief from cast to chrono secunds
|
||||
* @param mcrs microseconds of uint_64
|
||||
|
@ -67,8 +67,7 @@ class InitDBError:public std::exception
|
||||
{
|
||||
public:
|
||||
QString what(){
|
||||
return QObject::tr("Error creating database..");
|
||||
return QObject::tr("Error creating database.");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // EXAPTIONS_H
|
||||
|
@ -38,20 +38,16 @@ bool package::isValid() const{
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_feedback & TypePackage::t_sync){
|
||||
return false;
|
||||
if(type & TypePackage::t_play){
|
||||
ret = ret && true;
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_sync && type & t_brodcaster){
|
||||
if(type & TypePackage::t_sync && type & t_brodcaster){
|
||||
ret = ret && (playdata.run > 0 && playdata.seek > 0);
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_feedback){
|
||||
ret = ret && !(type & t_brodcaster) && (playdata.run > 0 && playdata.seek > 0);
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_song_h && type & t_brodcaster){
|
||||
ret = ret && header.size > 0;
|
||||
|
||||
@ -80,8 +76,7 @@ QByteArray package::parseTo(){
|
||||
if(isValid()){
|
||||
stream << static_cast<unsigned char>(type);
|
||||
|
||||
if((type & TypePackage::t_sync && type & t_brodcaster) ||
|
||||
(type & TypePackage::t_feedback && !(type & t_brodcaster))){
|
||||
if(type & TypePackage::t_sync && type & t_brodcaster){
|
||||
stream << playdata.run;
|
||||
stream << playdata.seek;
|
||||
|
||||
@ -109,19 +104,18 @@ bool package::parseFrom(QByteArray &array){
|
||||
stream >> temp_type;
|
||||
type = static_cast<TypePackage> (temp_type);
|
||||
|
||||
if((type & TypePackage::t_sync && type & t_brodcaster) ||
|
||||
(type & TypePackage::t_feedback && !(type & t_brodcaster))){
|
||||
if(type & TypePackage::t_sync){
|
||||
stream >> playdata.run;
|
||||
stream >> playdata.seek;
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_song_h && type & t_brodcaster){
|
||||
if(type & TypePackage::t_song_h){
|
||||
stream >> header;
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_song && type & t_brodcaster){
|
||||
if(type & TypePackage::t_song){
|
||||
stream >> source;
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ typedef unsigned char Type;
|
||||
/**
|
||||
* @brief The TypePackage enum
|
||||
* t_void = this package empty and not valid.
|
||||
* t_feedback = feedback for synced.
|
||||
* t_play = play curent audio file.
|
||||
* t_song_h = the header of playing audio file.
|
||||
* t_song = the package with this type is necessary for translite media data on network.
|
||||
* t_sync = the infomation about sync playning media file on network.
|
||||
@ -24,7 +24,7 @@ typedef unsigned char Type;
|
||||
|
||||
enum TypePackage{
|
||||
t_void = 0x00,
|
||||
t_feedback = 0x01,
|
||||
t_play = 0x01,
|
||||
t_song_h = 0x02,
|
||||
t_song = 0x04,
|
||||
t_sync = 0x08,
|
||||
|
@ -3,14 +3,11 @@
|
||||
#include <QMultimedia>
|
||||
#include <QSqlQuery>
|
||||
#include "exaptions.h"
|
||||
#include <ctime>
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
#include "config.h"
|
||||
#include "thread"
|
||||
#include "chronotime.h"
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
#include <QDebug>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
namespace syncLib{
|
||||
@ -217,7 +214,7 @@ bool Sync::play(const Song &song, const Syncer *syncdata){
|
||||
|
||||
if(fbroadcaster){
|
||||
package pac;
|
||||
if(!createPackage(t_song_h | t_sync, pac)){
|
||||
if(!createPackage(t_play, pac)){
|
||||
throw CreatePackageExaption();
|
||||
}
|
||||
node->WriteAll(pac.parseTo());
|
||||
@ -243,7 +240,7 @@ bool Sync::play(int id_song, Syncer *syncdata){
|
||||
song.name = qyery->value(1).toString();
|
||||
song.size = qyery->value(2).toInt();
|
||||
song.source = qyery->value(3).toByteArray();
|
||||
return Sync::play(song ,syncdata);
|
||||
return Sync::play(song,syncdata);
|
||||
}
|
||||
|
||||
bool Sync::play(QString url){
|
||||
@ -251,6 +248,7 @@ bool Sync::play(QString url){
|
||||
if(id < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
return Sync::play(id);
|
||||
}
|
||||
|
||||
@ -275,13 +273,10 @@ bool Sync::sync(const Syncer &sync){
|
||||
milliseconds sync_time = sync.run - ChronoTime::now();
|
||||
if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
|
||||
return false;
|
||||
|
||||
Clock run_time = ChronoTime::from(sync.run);
|
||||
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
} while (std::chrono::high_resolution_clock::now() < run_time);
|
||||
|
||||
player->setPosition(sync.seek);
|
||||
return true;
|
||||
}
|
||||
@ -313,32 +308,29 @@ bool Sync::listen(ETcpSocket *server){
|
||||
}
|
||||
package pac;
|
||||
|
||||
if(!createPackage(t_sync,pac)){
|
||||
if(!createPackage(t_sync, pac)){
|
||||
return false;
|
||||
}
|
||||
|
||||
return server->Write(pac.parseTo());
|
||||
}
|
||||
|
||||
bool Sync::createPackage(Type type, package &pac){
|
||||
bool Sync::createPackage(Type type, package &pac, const ETcpSocket *for_){
|
||||
pac.clear();
|
||||
|
||||
pac.type = type;
|
||||
|
||||
if(type & TypePackage::t_sync && fbroadcaster){
|
||||
if(type & TypePackage::t_sync && fbroadcaster){
|
||||
|
||||
pac.playdata.run = ChronoTime::now() + SYNC_TIME;
|
||||
if(!for_ || !for_->isSynced()){
|
||||
return false;
|
||||
}
|
||||
|
||||
pac.playdata.run = ChronoTime::now(for_->getDifferenceTime()) + SYNC_TIME;
|
||||
pac.playdata.seek = player->position() + SYNC_TIME;
|
||||
|
||||
}
|
||||
|
||||
if( type & TypePackage::t_feedback && !fbroadcaster){
|
||||
|
||||
pac.playdata.run = ChronoTime::now();
|
||||
pac.playdata.seek = player->position();
|
||||
|
||||
}
|
||||
|
||||
if(type & TypePackage::t_song_h && fbroadcaster){
|
||||
if(!curentSong)
|
||||
return false;
|
||||
@ -394,27 +386,27 @@ void Sync::packageRender(ETcpSocket *socket){
|
||||
|
||||
// if requst from server
|
||||
|
||||
if(pkg.getType() & t_sync){
|
||||
if(!play(pkg.getHeader(), &pkg.getPlayData()) && !play(pkg.getSong(), &pkg.getPlayData())){
|
||||
if(pkg.getType() & t_play){
|
||||
|
||||
Type requestType = t_song_h;
|
||||
|
||||
if(pkg.getType() & t_song_h)
|
||||
requestType = t_song;
|
||||
|
||||
package answer;
|
||||
if(!createPackage(requestType | t_sync, answer)){
|
||||
throw CreatePackageExaption();
|
||||
}
|
||||
socket->Write(answer.parseTo());
|
||||
}else{
|
||||
package feedback;
|
||||
|
||||
if(!createPackage(t_feedback, feedback)){
|
||||
throw feedbackError();
|
||||
}
|
||||
socket->Write(feedback.parseTo());
|
||||
package answer;
|
||||
if(!createPackage(t_sync, answer)){
|
||||
throw CreatePackageExaption();
|
||||
}
|
||||
socket->Write(answer.parseTo());
|
||||
}
|
||||
|
||||
if(pkg.getType() & t_sync && !play(pkg.getHeader(), &pkg.getPlayData()) && !play(pkg.getSong(), &pkg.getPlayData())){
|
||||
|
||||
Type requestType = t_song_h;
|
||||
|
||||
if(pkg.getType() & t_song_h)
|
||||
requestType = t_song;
|
||||
|
||||
package answer;
|
||||
if(!createPackage(requestType | t_sync, answer)){
|
||||
throw CreatePackageExaption();
|
||||
}
|
||||
socket->Write(answer.parseTo());
|
||||
}
|
||||
|
||||
if(pkg.getType() & t_close){
|
||||
@ -434,33 +426,18 @@ void Sync::packageRender(ETcpSocket *socket){
|
||||
|
||||
}else{
|
||||
|
||||
if(pkg.getType() & t_sync ){
|
||||
if(pkg.getType() & t_sync){
|
||||
if(!curentSong){
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
Type responceType = pkg.getType();
|
||||
if(pkg.getType() & t_feedback){
|
||||
if(!curentSong){
|
||||
return ;
|
||||
throw SyncError();
|
||||
}
|
||||
|
||||
unsigned int diff = ChronoTime::abs(player->position() - (pkg.getPlayData().seek + (ChronoTime::now() - pkg.getPlayData().run)));
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << "diff " << socket->name() <<": " << diff;
|
||||
#endif
|
||||
|
||||
if(diff > 1){
|
||||
responceType = responceType | t_sync;
|
||||
}else{
|
||||
std::cout<<"Synced!!"<<std::endl;
|
||||
if(!socket->isSynced()){
|
||||
socket->calibration();
|
||||
}
|
||||
}
|
||||
|
||||
package answer;
|
||||
if(!createPackage(responceType & ~t_what & ~t_feedback & ~t_stop & ~t_brodcaster, answer)){
|
||||
if(!createPackage(pkg.getType() & ~t_what & ~t_play & ~t_stop & ~t_brodcaster, answer, socket)){
|
||||
throw CreatePackageExaption();
|
||||
}
|
||||
socket->Write(answer.parseTo());
|
||||
|
@ -13,6 +13,7 @@ class QSqlQuery;
|
||||
class QBuffer;
|
||||
namespace syncLib {
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
|
||||
|
||||
class Node;
|
||||
|
||||
@ -36,7 +37,6 @@ private:
|
||||
LocalScanner deepScaner;
|
||||
int port;
|
||||
QString dataBaseName;
|
||||
|
||||
/**
|
||||
* @brief findHeader set curent song if playList have playng song
|
||||
* @return true if all done
|
||||
@ -81,14 +81,13 @@ private:
|
||||
* @return song drom local database.
|
||||
*/
|
||||
Song fromDataBase(const int id);
|
||||
|
||||
/**
|
||||
* @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(Type type ,package& pac);
|
||||
bool createPackage(Type type , package& pac, const ETcpSocket *for_ = NULL);
|
||||
private slots:
|
||||
|
||||
/**
|
||||
@ -111,11 +110,10 @@ public:
|
||||
/**
|
||||
* @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption.
|
||||
* @param header of song
|
||||
* @param feedback - information about result of palying (cell default constructor if paying failed)
|
||||
* @param syncdata data of synbced playning of media data.
|
||||
* @return true if all done else false.
|
||||
*/
|
||||
bool play(const SongHeader &header, const Syncer *syncdata = nullptr);
|
||||
bool play(const SongHeader &header, const 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user