downloader works.

pull/175/head^2
Apex Liu 2019-11-01 03:33:18 +08:00
parent 2f7fc16235
commit a7b8b68ae6
7 changed files with 132 additions and 63 deletions

View File

@ -1,6 +1,7 @@
#include "downloader.h" #include "downloader.h"
#include "record_format.h" #include "record_format.h"
#include <QEventLoop>
#include <QNetworkReply> #include <QNetworkReply>
#include <qelapsedtimer.h> #include <qelapsedtimer.h>
@ -22,36 +23,50 @@ eventLoop.exec();
//================================================================= //=================================================================
Downloader::Downloader() { Downloader::Downloader() {
m_reply = nullptr; m_reply = nullptr;
m_code = codeUnknown; m_code = codeDownloading;
} }
Downloader::~Downloader() { Downloader::~Downloader() {
// qDebug("Downloader destroied.");
} }
void Downloader::run(QNetworkAccessManager* nam, QString& url, QString& sid, QString& filename) { void Downloader::run(QNetworkAccessManager* nam, const QString& url, const QString& sid, const QString& filename) {
m_code = codeDownloading;
m_filename = filename; m_filename = filename;
if(!m_filename.isEmpty()) { if(!m_filename.isEmpty()) {
m_file.setFileName(m_filename); m_file.setFileName(m_filename);
if(!m_file.open(QIODevice::WriteOnly | QFile::Truncate)){ if(!m_file.open(QIODevice::WriteOnly | QFile::Truncate)){
qDebug("open file for write failed."); qDebug("open file for write failed.");
m_code = codeFailed;
return; return;
} }
} }
m_code = codeDownloading;
QString cookie = QString("_sid=%1\r\n").arg(sid); QString cookie = QString("_sid=%1\r\n").arg(sid);
QNetworkRequest req; QNetworkRequest req;
req.setUrl(QUrl(url)); req.setUrl(QUrl(url));
req.setRawHeader("Cookie", cookie.toLatin1()); req.setRawHeader("Cookie", cookie.toLatin1());
QEventLoop eventLoop;
m_reply = nam->get(req); m_reply = nam->get(req);
connect(m_reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
connect(m_reply, &QNetworkReply::finished, this, &Downloader::_on_finished); connect(m_reply, &QNetworkReply::finished, this, &Downloader::_on_finished);
connect(m_reply, &QIODevice::readyRead, this, &Downloader::_on_data_ready); connect(m_reply, &QIODevice::readyRead, this, &Downloader::_on_data_ready);
eventLoop.exec();
disconnect(m_reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
disconnect(m_reply, &QNetworkReply::finished, this, &Downloader::_on_finished);
disconnect(m_reply, &QIODevice::readyRead, this, &Downloader::_on_data_ready);
delete m_reply;
m_reply = nullptr;
qDebug("Downloader::run(%p) end.", this);
} }
void Downloader::_on_data_ready() { void Downloader::_on_data_ready() {
// qDebug("Downloader::_on_data_ready(%p).", this);
QNetworkReply *reply = reinterpret_cast<QNetworkReply*>(sender()); QNetworkReply *reply = reinterpret_cast<QNetworkReply*>(sender());
if(m_filename.isEmpty()) { if(m_filename.isEmpty()) {
@ -62,17 +77,16 @@ void Downloader::_on_data_ready() {
} }
} }
void Downloader::reset() {
m_code = codeUnknown;
}
void Downloader::abort() { void Downloader::abort() {
if(m_reply) if(m_reply) {
qDebug("Downloader::abort(%p);", this);
m_reply->abort(); m_reply->abort();
m_code = codeAbort;
}
} }
void Downloader::_on_finished() { void Downloader::_on_finished() {
qDebug("download finished"); // qDebug("Downloader::_on_finished(%p).", this);
QNetworkReply *reply = reinterpret_cast<QNetworkReply*>(sender()); QNetworkReply *reply = reinterpret_cast<QNetworkReply*>(sender());
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
@ -83,14 +97,11 @@ void Downloader::_on_finished() {
//qDebug() << strError; //qDebug() << strError;
m_file.flush(); m_file.flush();
m_file.close(); m_file.close();
m_code = codeFailed; if(m_code != codeDownloading)
m_code = codeFailed;
return; return;
} }
disconnect(m_reply, &QNetworkReply::finished, this, &Downloader::_on_finished);
disconnect(m_reply, &QIODevice::readyRead, this, &Downloader::_on_data_ready);
// reply->deleteLater();
if(m_filename.isEmpty()) { if(m_filename.isEmpty()) {
m_data += reply->readAll(); m_data += reply->readAll();
} }

View File

@ -9,9 +9,9 @@ class Downloader : public QObject {
public: public:
enum EndCode{ enum EndCode{
codeUnknown = 0,
codeSuccess, codeSuccess,
codeDownloading, codeDownloading,
codeAbort,
codeFailed codeFailed
}; };
@ -20,9 +20,9 @@ public:
Downloader(); Downloader();
~Downloader(); ~Downloader();
void run(QNetworkAccessManager* nam, QString& url, QString& sid, QString& filename); void run(QNetworkAccessManager* nam, const QString& url, const QString& sid, const QString& filename);
void abort(); void abort();
void reset(); // void reset();
QByteArray& data(){return m_data;} QByteArray& data(){return m_data;}
EndCode code() {return m_code;} EndCode code() {return m_code;}

View File

@ -93,7 +93,7 @@ MainWindow::MainWindow(QWidget *parent) :
m_play_state = PLAY_STATE_UNKNOWN; m_play_state = PLAY_STATE_UNKNOWN;
m_thr_data = nullptr; m_thr_data = nullptr;
m_dl = nullptr; // m_dl = nullptr;
ui->setupUi(this); ui->setupUi(this);
@ -150,15 +150,15 @@ MainWindow::~MainWindow()
if(m_thr_data) { if(m_thr_data) {
m_thr_data->stop(); m_thr_data->stop();
disconnect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); disconnect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*)));
disconnect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*))); // disconnect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*)));
delete m_thr_data; delete m_thr_data;
m_thr_data = nullptr; m_thr_data = nullptr;
} }
if(m_dl) { // if(m_dl) {
delete m_dl; // delete m_dl;
m_dl = nullptr; // m_dl = nullptr;
} // }
delete ui; delete ui;
} }
@ -170,7 +170,7 @@ void MainWindow::set_resource(const QString &res) {
void MainWindow::_do_first_run() { void MainWindow::_do_first_run() {
m_thr_data = new ThrData(this, m_res); m_thr_data = new ThrData(this, m_res);
connect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*))); connect(m_thr_data, SIGNAL(signal_update_data(UpdateData*)), this, SLOT(_do_update_data(UpdateData*)));
connect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*))); // connect(m_thr_data, SIGNAL(signal_download(DownloadParam*)), this, SLOT(_do_download(DownloadParam*)));
m_thr_data->start(); m_thr_data->start();
_start_play_thread(); _start_play_thread();
@ -481,17 +481,17 @@ void MainWindow::_do_bar_fade() {
update(m_bar.rc()); update(m_bar.rc());
} }
void MainWindow::_do_download(DownloadParam* param) { //void MainWindow::_do_download(DownloadParam* param) {
qDebug("MainWindow::_do_download(). %s %s %s", param->url.toStdString().c_str(), param->sid.toStdString().c_str(), param->fname.toStdString().c_str()); // qDebug("MainWindow::_do_download(). %s %s %s", param->url.toStdString().c_str(), param->sid.toStdString().c_str(), param->fname.toStdString().c_str());
if(m_dl) { // if(m_dl) {
delete m_dl; // delete m_dl;
m_dl = nullptr; // m_dl = nullptr;
} // }
m_dl = new Downloader(); // m_dl = new Downloader();
m_dl->run(&m_nam, param->url, param->sid, param->fname); // m_dl->run(&m_nam, param->url, param->sid, param->fname);
} //}
void MainWindow::mouseMoveEvent(QMouseEvent *e) { void MainWindow::mouseMoveEvent(QMouseEvent *e) {
if(!m_show_default) { if(!m_show_default) {

View File

@ -36,8 +36,8 @@ public:
void restart(); void restart();
void speed(int s); void speed(int s);
Downloader* downloader() {return m_dl;} // Downloader* downloader() {return m_dl;}
void reset_downloader() {if(m_dl){delete m_dl;m_dl= nullptr;}} // void reset_downloader() {if(m_dl){delete m_dl;m_dl= nullptr;}}
private: private:
void paintEvent(QPaintEvent *e); void paintEvent(QPaintEvent *e);
@ -53,7 +53,7 @@ private slots:
void _do_bar_delay_hide(); void _do_bar_delay_hide();
// void _do_download(Downloader*); // void _do_download(Downloader*);
void _do_download(DownloadParam*); // void _do_download(DownloadParam*);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
@ -90,8 +90,8 @@ private:
QRect m_rc_message; QRect m_rc_message;
QNetworkAccessManager m_nam; // QNetworkAccessManager m_nam;
Downloader* m_dl; // Downloader* m_dl;
// for test // for test
TimeUseTest m_time_imgconvert_normal; TimeUseTest m_time_imgconvert_normal;

View File

@ -21,6 +21,7 @@ ThrData::ThrData(MainWindow* mainwin, const QString& res) {
m_res = res; m_res = res;
m_need_download = false; m_need_download = false;
m_need_stop = false; m_need_stop = false;
m_dl = nullptr;
#ifdef __APPLE__ #ifdef __APPLE__
QString data_path_base = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QString data_path_base = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
@ -48,12 +49,19 @@ GenericCacheLocation: "C:/Users/apex/AppData/Local/cache"
} }
ThrData::~ThrData() { ThrData::~ThrData() {
if(m_dl)
delete m_dl;
} }
void ThrData::stop() { void ThrData::stop() {
if(!isRunning()) if(!isRunning())
return; return;
m_need_stop = true; m_need_stop = true;
if(m_dl) {
m_dl->abort();
}
wait(); wait();
qDebug("data thread stop() end."); qDebug("data thread stop() end.");
} }
@ -70,10 +78,6 @@ void ThrData::_notify_error(const QString& msg) {
emit signal_update_data(_msg); emit signal_update_data(_msg);
} }
void ThrData::_notify_download(DownloadParam* param) {
emit signal_download(param);
}
// tp-player.exe http://teleport.domain.com:7190/{sub/path/}tp_1491560510_ca67fceb75a78c9d/1234 (注意并不直接访问此URI实际上其并不存在) // tp-player.exe http://teleport.domain.com:7190/{sub/path/}tp_1491560510_ca67fceb75a78c9d/1234 (注意并不直接访问此URI实际上其并不存在)
// TP服务器地址(可能包含子路径哦,例如上例中的{sub/path/}部分)/session-id(用于判断当前授权用户)/录像会话编号 // TP服务器地址(可能包含子路径哦,例如上例中的{sub/path/}部分)/session-id(用于判断当前授权用户)/录像会话编号
@ -84,11 +88,11 @@ void ThrData::run() {
if(!_load_keyframe()) if(!_load_keyframe())
return; return;
for(;;) { // for(;;) {
if(m_need_stop) // if(m_need_stop)
break; // break;
msleep(500); // msleep(500);
} // }
qDebug("ThrData thread run() end."); qDebug("ThrData thread run() end.");
} }
@ -149,8 +153,10 @@ bool ThrData::_load_header() {
// return false; // return false;
// } // }
Downloader* dl = m_mainwin->downloader(); //Downloader* dl = m_mainwin->downloader();
QByteArray& data = dl->data(); if(!m_dl)
return false;
QByteArray& data = m_dl->data();
if(data.size() != sizeof(TS_RECORD_HEADER)) { if(data.size() != sizeof(TS_RECORD_HEADER)) {
qDebug("invalid header file. %d", data.size()); qDebug("invalid header file. %d", data.size());
_notify_error(QString("%1\n\n%2").arg(LOCAL8BIT("指定的文件或目录不存在!"), _tmp_res)); _notify_error(QString("%1\n\n%2").arg(LOCAL8BIT("指定的文件或目录不存在!"), _tmp_res));
@ -285,29 +291,36 @@ bool ThrData::_load_header() {
} }
bool ThrData::_load_keyframe() { bool ThrData::_load_keyframe() {
// _notify_error(QString("%1").arg(LOCAL8BIT("测试!")));
QString tpk_fname = QString("%1/tp-rdp.tpk").arg(m_path_base); QString tpk_fname = QString("%1/tp-rdp.tpk").arg(m_path_base);
tpk_fname = QDir::toNativeSeparators(tpk_fname); tpk_fname = QDir::toNativeSeparators(tpk_fname);
if(m_need_download) { if(m_need_download) {
// download .tpr
QString url(m_url_base);
url += "/audit/get-file?act=read&type=rdp&rid=";
url += m_rid;
url += "&f=tp-rdp.tpk";
QString tmp_fname = QString("%1/tp-rdp.tpk.downloading").arg(m_path_base); QString tmp_fname = QString("%1/tp-rdp.tpk.downloading").arg(m_path_base);
tmp_fname = QDir::toNativeSeparators(tmp_fname); tmp_fname = QDir::toNativeSeparators(tmp_fname);
qDebug() << "TPK(tmp): " << tmp_fname;
qDebug() << "TPK(out): " << tpk_fname;
if(!_download_file(url, tmp_fname)) QFileInfo fi_tmp(tmp_fname);
return false; if(fi_tmp.isFile()) {
QFile::remove(tmp_fname);
}
QFile::rename(tmp_fname, tpk_fname); QFileInfo fi_tpk(tpk_fname);
if(!fi_tpk.exists()) {
QString url(m_url_base);
url += "/audit/get-file?act=read&type=rdp&rid=";
url += m_rid;
url += "&f=tp-rdp.tpk";
qDebug() << "TPK(tmp): " << tmp_fname;
if(!_download_file(url, tmp_fname))
return false;
if(!QFile::rename(tmp_fname, tpk_fname))
return false;
}
} }
qDebug() << "TPK: " << tpk_fname;
QFile f_kf(tpk_fname); QFile f_kf(tpk_fname);
if(!f_kf.open(QFile::ReadOnly)) { if(!f_kf.open(QFile::ReadOnly)) {
qDebug() << "Can not open " << tpk_fname << " for read."; qDebug() << "Can not open " << tpk_fname << " for read.";
@ -340,6 +353,46 @@ bool ThrData::_load_keyframe() {
return true; return true;
} }
bool ThrData::_download_file(const QString& url, const QString filename) {
if(!m_need_download) {
qDebug() << "download not necessary.";
return false;
}
if(m_dl) {
delete m_dl;
m_dl = nullptr;
}
m_dl = new Downloader();
QNetworkAccessManager* nam = new QNetworkAccessManager;
m_dl->run(nam, url, m_sid, filename);
// qDebug("m_dl.run(%p) end.", m_dl);
for(;;) {
if(m_dl->code() == Downloader::codeDownloading) {
msleep(100);
continue;
}
if(m_dl->code() != Downloader::codeSuccess) {
qDebug() << "download failed.";
_notify_error(QString("%1").arg(LOCAL8BIT("下载文件失败!")));
delete nam;
return false;
}
else {
qDebug() << "download ok.";
delete nam;
return true;
}
}
}
#if 0
bool ThrData::_download_file(const QString& url, const QString filename) { bool ThrData::_download_file(const QString& url, const QString filename) {
if(!m_need_download) { if(!m_need_download) {
qDebug() << "download not necessary."; qDebug() << "download not necessary.";
@ -373,6 +426,8 @@ bool ThrData::_download_file(const QString& url, const QString filename) {
} }
} }
} }
#endif
#if 0 #if 0
void ThrData::run() { void ThrData::run() {

View File

@ -72,7 +72,6 @@ private:
signals: signals:
void signal_update_data(UpdateData*); void signal_update_data(UpdateData*);
void signal_download(DownloadParam*);
private: private:
MainWindow* m_mainwin; MainWindow* m_mainwin;
@ -90,6 +89,8 @@ private:
QString m_rid; QString m_rid;
QString m_path_base; QString m_path_base;
Downloader* m_dl;
TS_RECORD_HEADER m_hdr; TS_RECORD_HEADER m_hdr;
KeyFrames m_kf; KeyFrames m_kf;
}; };

View File

@ -3,6 +3,8 @@ TARGET = tp-player
QT += core gui widgets network QT += core gui widgets network
#DEFINES += QT_NO_DEBUG_OUTPUT
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
bar.h \ bar.h \