Update MediaClient
This commit is contained in:
43
MediaClient/MediaClientForMobile/formClass/About.cpp
Normal file
43
MediaClient/MediaClientForMobile/formClass/About.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "About.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
About::About(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
ui.labVersion->setText(QString("Happytime Media Client %1").arg(VERSION_STRING));
|
||||
|
||||
connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(close()));
|
||||
|
||||
showMaximized();
|
||||
}
|
||||
|
||||
|
||||
About::~About()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
41
MediaClient/MediaClientForMobile/formClass/About.h
Normal file
41
MediaClient/MediaClientForMobile/formClass/About.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef _ABOUT_H_
|
||||
#define _ABOUT_H_
|
||||
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_About.h"
|
||||
|
||||
class About : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
About(QWidget *parent = 0);
|
||||
~About();
|
||||
|
||||
private:
|
||||
Ui::About ui;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
186
MediaClient/MediaClientForMobile/formClass/FileBrowse.cpp
Normal file
186
MediaClient/MediaClientForMobile/formClass/FileBrowse.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "FileBrowse.h"
|
||||
#include "ui_FileBrowse.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QScreen>
|
||||
#include <QApplication>
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <QJniObject>
|
||||
#elif defined(IOS)
|
||||
#include <ios/ios_launcher.h>
|
||||
#endif
|
||||
|
||||
FileBrowse::FileBrowse(int fileFormat, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::FileBrowse)
|
||||
, m_bEditing(false)
|
||||
, m_fileFormat(fileFormat)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
initDialog();
|
||||
connSignalSlot();
|
||||
}
|
||||
|
||||
FileBrowse::~FileBrowse()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void FileBrowse::initDialog()
|
||||
{
|
||||
QStringList filters;
|
||||
|
||||
if (m_fileFormat == FILE_FORMAT_PIC)
|
||||
{
|
||||
filters << "*.jpg";
|
||||
m_basePath = getSnapshotPath();
|
||||
ui->labTips->setText(tr("Album"));
|
||||
}
|
||||
else
|
||||
{
|
||||
filters << "*.mp4";
|
||||
filters << "*.avi";
|
||||
m_basePath = getRecordPath();
|
||||
ui->labTips->setText(tr("Video"));
|
||||
}
|
||||
|
||||
ui->labPath->setText(tr("Path") + QString(" : ") + m_basePath);
|
||||
|
||||
m_pModel = new FileListModel(m_fileFormat, this);
|
||||
m_pModel->setNameFilters(filters);
|
||||
m_pModel->setDirPath(m_basePath);
|
||||
|
||||
ui->chkAll->setVisible(false);
|
||||
ui->fileList->setModel(m_pModel);
|
||||
|
||||
showMaximized();
|
||||
}
|
||||
|
||||
void FileBrowse::connSignalSlot()
|
||||
{
|
||||
QObject::connect(ui->btnBack, SIGNAL(clicked()), this, SLOT(slotBack()));
|
||||
QObject::connect(ui->btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()));
|
||||
QObject::connect(ui->chkAll, SIGNAL(clicked(bool)), this, SLOT(slotCheckAll(bool)));
|
||||
QObject::connect(ui->fileList, SIGNAL(clicked(QModelIndex)), this, SLOT(slotItemClicked(QModelIndex)));
|
||||
}
|
||||
|
||||
void FileBrowse::slotBack()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void FileBrowse::slotEdit()
|
||||
{
|
||||
if (!m_bEditing)
|
||||
{
|
||||
m_bEditing = true;
|
||||
ui->chkAll->setVisible(true);
|
||||
m_pModel->setCheckable(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteSelectedFiles();
|
||||
|
||||
m_bEditing = false;
|
||||
ui->chkAll->setVisible(false);
|
||||
m_pModel->setCheckable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FileBrowse::slotCheckAll(bool flag)
|
||||
{
|
||||
int row = m_pModel->rowCount();
|
||||
QModelIndex index;
|
||||
|
||||
for (int i = 0; i < row; i++)
|
||||
{
|
||||
index = m_pModel->index(i);
|
||||
m_pModel->setData(index, flag, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
|
||||
void FileBrowse::slotItemClicked(QModelIndex index)
|
||||
{
|
||||
if (m_bEditing)
|
||||
{
|
||||
int flag = m_pModel->data(index, Qt::CheckStateRole).toInt();
|
||||
if (flag == Qt::Checked)
|
||||
{
|
||||
m_pModel->setData(index, false, Qt::CheckStateRole);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pModel->setData(index, true, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QString name = m_pModel->data(index, Qt::DisplayRole).toString();
|
||||
QString path = m_basePath + "/" + name;
|
||||
|
||||
#if defined(ANDROID)
|
||||
QJniObject str = QJniObject::fromString(path);
|
||||
QJniObject provider = QJniObject::fromString(FILE_PROVIDER);
|
||||
QJniObject::callStaticMethod<void>("org/happytimesoft/util/HtUtil",
|
||||
"openFile",
|
||||
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
QNativeInterface::QAndroidApplication::context(),
|
||||
str.object<jstring>(),
|
||||
provider.object<jstring>());
|
||||
#elif defined(IOS)
|
||||
iosLaunchFile(path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void FileBrowse::deleteSelectedFiles()
|
||||
{
|
||||
int flag;
|
||||
int row = m_pModel->rowCount();
|
||||
QModelIndex index;
|
||||
|
||||
for (int i = row - 1; i >= 0; i--)
|
||||
{
|
||||
index = m_pModel->index(i);
|
||||
flag = m_pModel->data(index, Qt::CheckStateRole).toInt();
|
||||
if (flag == Qt::Checked)
|
||||
{
|
||||
QString name = m_pModel->data(index, Qt::DisplayRole).toString();
|
||||
QString path = m_basePath + "/" + name;
|
||||
|
||||
QFile::remove(path);
|
||||
|
||||
m_pModel->removeRows(i, 1, index.parent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
60
MediaClient/MediaClientForMobile/formClass/FileBrowse.h
Normal file
60
MediaClient/MediaClientForMobile/formClass/FileBrowse.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef FILEBROWSE_H
|
||||
#define FILEBROWSE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "FileListModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class FileBrowse;
|
||||
}
|
||||
|
||||
class FileBrowse : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FileBrowse(int fileFormat, QWidget *parent = 0);
|
||||
~FileBrowse();
|
||||
|
||||
private slots:
|
||||
void slotBack();
|
||||
void slotEdit();
|
||||
void slotCheckAll(bool flag);
|
||||
void slotItemClicked(QModelIndex);
|
||||
|
||||
private:
|
||||
void initDialog();
|
||||
void connSignalSlot();
|
||||
void deleteSelectedFiles();
|
||||
|
||||
private:
|
||||
Ui::FileBrowse *ui;
|
||||
|
||||
QString m_basePath;
|
||||
bool m_bEditing;
|
||||
FileListModel * m_pModel;
|
||||
int m_fileFormat;
|
||||
};
|
||||
|
||||
#endif // FILEBROWSE_H
|
||||
|
||||
|
||||
50
MediaClient/MediaClientForMobile/formClass/InstMsgDialog.cpp
Normal file
50
MediaClient/MediaClientForMobile/formClass/InstMsgDialog.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "InstMsgDialog.h"
|
||||
#include "ui_InstMsgDialog.h"
|
||||
#include <QTimer>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include "utils.h"
|
||||
|
||||
InstMsgDialog::InstMsgDialog(QString msg, int timelen, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::InstMsgDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QRect rect = this->rect();
|
||||
|
||||
rect.setWidth(QGuiApplication::primaryScreen()->geometry().width());
|
||||
rect.setHeight(40);
|
||||
setGeometry(rect);
|
||||
|
||||
ui->labMsg->setText(msg);
|
||||
|
||||
QTimer::singleShot(timelen, this, SLOT(close()));
|
||||
}
|
||||
|
||||
InstMsgDialog::~InstMsgDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
|
||||
43
MediaClient/MediaClientForMobile/formClass/InstMsgDialog.h
Normal file
43
MediaClient/MediaClientForMobile/formClass/InstMsgDialog.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef INSTMSGDIALOG_H
|
||||
#define INSTMSGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class InstMsgDialog;
|
||||
}
|
||||
|
||||
class InstMsgDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InstMsgDialog(QString msg, int timelen, QWidget *parent = 0);
|
||||
~InstMsgDialog();
|
||||
|
||||
private:
|
||||
Ui::InstMsgDialog *ui;
|
||||
};
|
||||
|
||||
#endif // INSTMSGDIALOG_H
|
||||
|
||||
|
||||
863
MediaClient/MediaClientForMobile/formClass/MediaClient.cpp
Normal file
863
MediaClient/MediaClientForMobile/formClass/MediaClient.cpp
Normal file
@@ -0,0 +1,863 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "MediaClient.h"
|
||||
#include "InstMsgDialog.h"
|
||||
#include "OpenMedia.h"
|
||||
#include "config.h"
|
||||
#include "FileBrowse.h"
|
||||
#include "About.h"
|
||||
#include "utils.h"
|
||||
#include "SystemSetting.h"
|
||||
#include "rtsp_cln.h"
|
||||
#include "rtmp_cln.h"
|
||||
#include "http_flv_cln.h"
|
||||
#include "http_mjpeg_cln.h"
|
||||
#include "srt_cln.h"
|
||||
#include <QScreen>
|
||||
#include <QTransform>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <QJniObject>
|
||||
#endif
|
||||
|
||||
MediaClient::MediaClient(QWidget *parent, Qt::WindowFlags flags)
|
||||
: QDialog(parent, flags)
|
||||
, m_curWidget(NULL)
|
||||
, m_recvBytes(0)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
initDialog();
|
||||
|
||||
connSignalSlot();
|
||||
}
|
||||
|
||||
MediaClient::~MediaClient()
|
||||
{
|
||||
QList<CHANNEL> channels;
|
||||
|
||||
saveChannel(channels, ui.videoWidget1);
|
||||
saveChannel(channels, ui.videoWidget2);
|
||||
saveChannel(channels, ui.videoWidget3);
|
||||
saveChannel(channels, ui.videoWidget4);
|
||||
saveChannel(channels, ui.videoWidget5);
|
||||
saveChannel(channels, ui.videoWidget6);
|
||||
saveChannel(channels, ui.videoWidget7);
|
||||
saveChannel(channels, ui.videoWidget8);
|
||||
saveChannel(channels, ui.videoWidget9);
|
||||
|
||||
saveChannels(channels);
|
||||
|
||||
saveLayoutMode(m_layoutMode);
|
||||
|
||||
ui.videoWidget1->stop();
|
||||
ui.videoWidget2->stop();
|
||||
ui.videoWidget3->stop();
|
||||
ui.videoWidget4->stop();
|
||||
ui.videoWidget5->stop();
|
||||
ui.videoWidget6->stop();
|
||||
ui.videoWidget7->stop();
|
||||
ui.videoWidget8->stop();
|
||||
ui.videoWidget9->stop();
|
||||
|
||||
#if defined(ANDROID)
|
||||
QJniObject::callStaticMethod<void>("org/happytimesoft/util/HtUtil", "enableLockScreen");
|
||||
#endif
|
||||
|
||||
log_close();
|
||||
|
||||
QDesktopServices::openUrl(QUrl("https://www.happytimesoft.com/", QUrl::TolerantMode));
|
||||
}
|
||||
|
||||
void MediaClient::saveChannel(QList<CHANNEL> &channels, VideoWidget * widget)
|
||||
{
|
||||
CHANNEL channel;
|
||||
|
||||
if (widget->isPlaying())
|
||||
{
|
||||
channel.url = widget->getUrl();
|
||||
channel.user = widget->getUser();
|
||||
channel.pass = widget->getPass();
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.url = "";
|
||||
channel.user = "";
|
||||
channel.pass = "";
|
||||
}
|
||||
|
||||
channels.append(channel);
|
||||
}
|
||||
|
||||
void MediaClient::closeEvent(QCloseEvent * event)
|
||||
{
|
||||
if (QMessageBox::Yes == QMessageBox::question(this, tr("Quit"), tr("Are you sure want to quit?")))
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::initLog()
|
||||
{
|
||||
char file[512] = {'\0'};
|
||||
QString path = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).last();
|
||||
|
||||
sprintf(file, "%s/mediaclient.log", path.toStdString().c_str());
|
||||
|
||||
log_init(file);
|
||||
}
|
||||
|
||||
void MediaClient::initDialog()
|
||||
{
|
||||
setWindowTitle(QString("Happytime media client %1").arg(VERSION_STRING));
|
||||
|
||||
#if defined(ANDROID)
|
||||
QJniObject str = QJniObject::fromString("android.permission.WRITE_EXTERNAL_STORAGE");
|
||||
QJniObject::callStaticMethod<jint>("org/happytimesoft/util/HtUtil",
|
||||
"requestPermission",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)I",
|
||||
QNativeInterface::QAndroidApplication::context(),
|
||||
str.object<jstring>());
|
||||
#endif
|
||||
|
||||
loadSystemConfig();
|
||||
|
||||
if (m_syscfg.enableLog)
|
||||
{
|
||||
initLog();
|
||||
|
||||
log_set_level(m_syscfg.logLevel);
|
||||
}
|
||||
|
||||
ui.labTipInfo->setText("");
|
||||
ui.labStatistics->setText("");
|
||||
|
||||
ui.cmbLayout->addItem(QIcon(":/res/Resources/1.png"), "1", 1);
|
||||
ui.cmbLayout->addItem(QIcon(":/res/Resources/2.png"), "2", 2);
|
||||
ui.cmbLayout->addItem(QIcon(":/res/Resources/4.png"), "4", 4);
|
||||
ui.cmbLayout->addItem(QIcon(":/res/Resources/6.png"), "6", 6);
|
||||
ui.cmbLayout->addItem(QIcon(":/res/Resources/9.png"), "9", 9);
|
||||
|
||||
QScreen * pScreen = QApplication::primaryScreen();
|
||||
|
||||
setupLayout(pScreen->orientation());
|
||||
|
||||
connect(pScreen, SIGNAL(orientationChanged(Qt::ScreenOrientation)),
|
||||
this, SLOT(slotOrientationChanged(Qt::ScreenOrientation)));
|
||||
|
||||
if (1 == m_syscfg.layoutMode)
|
||||
{
|
||||
slotLayoutOne();
|
||||
ui.cmbLayout->setCurrentIndex(0);
|
||||
}
|
||||
else if (2 == m_syscfg.layoutMode)
|
||||
{
|
||||
slotLayoutTwo();
|
||||
ui.cmbLayout->setCurrentIndex(1);
|
||||
}
|
||||
else if (6 == m_syscfg.layoutMode)
|
||||
{
|
||||
slotLayoutSix();
|
||||
ui.cmbLayout->setCurrentIndex(3);
|
||||
}
|
||||
else if (9 == m_syscfg.layoutMode)
|
||||
{
|
||||
slotLayoutNine();
|
||||
ui.cmbLayout->setCurrentIndex(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
slotLayoutFour();
|
||||
ui.cmbLayout->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
m_curWidget = ui.videoWidget1;
|
||||
m_curWidget->parentWidget()->setStyleSheet("background-color: blue;");
|
||||
|
||||
// when video playing, prevent auto lock screen
|
||||
|
||||
#if defined(ANDROID)
|
||||
QJniObject::callStaticMethod<void>("org/happytimesoft/util/HtUtil",
|
||||
"disableLockScreen",
|
||||
"(Landroid/content/Context;)V",
|
||||
QNativeInterface::QAndroidApplication::context());
|
||||
#endif
|
||||
|
||||
loadChannels();
|
||||
|
||||
#ifndef IOS
|
||||
ui.btnQuit->hide();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MediaClient::connSignalSlot()
|
||||
{
|
||||
connect(ui.cmbLayout, SIGNAL(currentIndexChanged(int)), this, SLOT(slotLayoutChanged(int)));
|
||||
connect(ui.btnPlay, SIGNAL(clicked()), this, SLOT(slotPlay()));
|
||||
connect(ui.btnPause, SIGNAL(clicked()), this, SLOT(slotPause()));
|
||||
connect(ui.btnStop, SIGNAL(clicked()), this, SLOT(slotStop()));
|
||||
connect(ui.btnSnapshot, SIGNAL(clicked()), this, SLOT(slotSnapshot()));
|
||||
connect(ui.btnRecord, SIGNAL(clicked()), this, SLOT(slotRecord()));
|
||||
connect(ui.btnVolume, SIGNAL(clicked()), this, SLOT(slotVolume()));
|
||||
connect(ui.btnSetting, SIGNAL(clicked()), this, SLOT(slotSystemSetting()));
|
||||
connect(ui.btnOpenSnapshot, SIGNAL(clicked()), this, SLOT(slotOpenSnapshot()));
|
||||
connect(ui.btnOpenRecord, SIGNAL(clicked()), this, SLOT(slotOpenRecording()));
|
||||
connect(ui.btnAbout, SIGNAL(clicked()), this, SLOT(slotAbout()));
|
||||
connect(ui.btnQuit, SIGNAL(clicked()), this, SLOT(close()));
|
||||
|
||||
connVideoWidget(ui.videoWidget1);
|
||||
connVideoWidget(ui.videoWidget2);
|
||||
connVideoWidget(ui.videoWidget3);
|
||||
connVideoWidget(ui.videoWidget4);
|
||||
connVideoWidget(ui.videoWidget5);
|
||||
connVideoWidget(ui.videoWidget6);
|
||||
connVideoWidget(ui.videoWidget7);
|
||||
connVideoWidget(ui.videoWidget8);
|
||||
connVideoWidget(ui.videoWidget9);
|
||||
}
|
||||
|
||||
void MediaClient::connVideoWidget(VideoWidget * widget)
|
||||
{
|
||||
connect(widget, SIGNAL(snapshotResult(bool)), this, SLOT(slotSnapshotResult(bool)));
|
||||
connect(widget, SIGNAL(recordResult(bool)), this, SLOT(slotRecordResult(bool)));
|
||||
connect(widget, SIGNAL(updateStatistics(int)), this, SLOT(slotUpdateStatistics(int)));
|
||||
connect(widget, SIGNAL(widgetSelecting(QWidget*)), this, SLOT(slotWidgetSelecting(QWidget*)));
|
||||
connect(widget, SIGNAL(callState(QWidget*,int)), this, SLOT(slotCallState(QWidget*,int)));
|
||||
}
|
||||
|
||||
void MediaClient::loadSystemConfig()
|
||||
{
|
||||
m_syscfg.enableLog = getEnableLogFlag();
|
||||
m_syscfg.videoRenderMode = getVideoRenderMode();
|
||||
m_syscfg.rtpMulticast = getRtpMulticast();
|
||||
m_syscfg.rtpOverUdp = getRtpOverUdp();
|
||||
m_syscfg.rtspOverHttp = getRtspOverHttp();
|
||||
m_syscfg.rtspOverHttpPort = getRtspOverHttpPort();
|
||||
m_syscfg.rtspOverWs = getRtspOverWs();
|
||||
m_syscfg.rtspOverWsPort = getRtspOverWsPort();
|
||||
m_syscfg.logLevel = getLogLevel();
|
||||
m_syscfg.hwDecoding = getHWDecoding();
|
||||
m_syscfg.layoutMode = getLayoutMode();
|
||||
m_syscfg.recordTime = getRecordTime();
|
||||
m_syscfg.recordSize = getRecordSize();
|
||||
}
|
||||
|
||||
void MediaClient::loadChannels()
|
||||
{
|
||||
QList<CHANNEL> channels;
|
||||
|
||||
getChannels(channels);
|
||||
|
||||
if (channels.size() > 0 && !channels[0].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget1->play(channels[0].url, channels[0].user, channels[0].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 1 && !channels[1].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget2->play(channels[1].url, channels[1].user, channels[1].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 2 && !channels[2].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget3->play(channels[2].url, channels[2].user, channels[2].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 3 && !channels[3].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget4->play(channels[3].url, channels[3].user, channels[3].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 4 && !channels[4].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget5->play(channels[4].url, channels[4].user, channels[4].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 5 && !channels[5].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget6->play(channels[5].url, channels[5].user, channels[5].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 6 && !channels[6].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget7->play(channels[6].url, channels[6].user, channels[6].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 7 && !channels[7].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget8->play(channels[7].url, channels[7].user, channels[7].pass);
|
||||
}
|
||||
|
||||
if (channels.size() > 8 && !channels[8].url.isEmpty())
|
||||
{
|
||||
ui.videoWidget9->play(channels[8].url, channels[8].user, channels[8].pass);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutOne()
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->hide();
|
||||
ui.widget3->hide();
|
||||
ui.widget4->hide();
|
||||
ui.widget5->hide();
|
||||
ui.widget6->hide();
|
||||
ui.widget7->hide();
|
||||
ui.widget8->hide();
|
||||
ui.widget9->hide();
|
||||
|
||||
m_layoutMode = 1;
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutTwo()
|
||||
{
|
||||
QScreen * pScreen = QApplication::primaryScreen();
|
||||
Qt::ScreenOrientation orientation = pScreen->orientation();
|
||||
|
||||
if (orientation == Qt::LandscapeOrientation ||
|
||||
orientation == Qt::InvertedLandscapeOrientation) // width > height
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->show();
|
||||
ui.widget3->hide();
|
||||
ui.widget4->hide();
|
||||
ui.widget5->hide();
|
||||
ui.widget6->hide();
|
||||
ui.widget7->hide();
|
||||
ui.widget8->hide();
|
||||
ui.widget9->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->hide();
|
||||
ui.widget3->hide();
|
||||
ui.widget4->show();
|
||||
ui.widget5->hide();
|
||||
ui.widget6->hide();
|
||||
ui.widget7->hide();
|
||||
ui.widget8->hide();
|
||||
ui.widget9->hide();
|
||||
}
|
||||
|
||||
m_layoutMode = 2;
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutFour()
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->show();
|
||||
ui.widget3->hide();
|
||||
ui.widget4->show();
|
||||
ui.widget5->show();
|
||||
ui.widget6->hide();
|
||||
ui.widget7->hide();
|
||||
ui.widget8->hide();
|
||||
ui.widget9->hide();
|
||||
|
||||
m_layoutMode = 4;
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutSix()
|
||||
{
|
||||
QScreen * pScreen = QApplication::primaryScreen();
|
||||
Qt::ScreenOrientation orientation = pScreen->orientation();
|
||||
|
||||
if (orientation == Qt::LandscapeOrientation ||
|
||||
orientation == Qt::InvertedLandscapeOrientation) // width > height
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->show();
|
||||
ui.widget3->show();
|
||||
ui.widget4->show();
|
||||
ui.widget5->show();
|
||||
ui.widget6->show();
|
||||
ui.widget7->hide();
|
||||
ui.widget8->hide();
|
||||
ui.widget9->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->show();
|
||||
ui.widget3->hide();
|
||||
ui.widget4->show();
|
||||
ui.widget5->show();
|
||||
ui.widget6->hide();
|
||||
ui.widget7->show();
|
||||
ui.widget8->show();
|
||||
ui.widget9->hide();
|
||||
}
|
||||
|
||||
m_layoutMode = 6;
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutNine()
|
||||
{
|
||||
ui.widget1->show();
|
||||
ui.widget2->show();
|
||||
ui.widget3->show();
|
||||
ui.widget4->show();
|
||||
ui.widget5->show();
|
||||
ui.widget6->show();
|
||||
ui.widget7->show();
|
||||
ui.widget8->show();
|
||||
ui.widget9->show();
|
||||
|
||||
m_layoutMode = 9;
|
||||
}
|
||||
|
||||
void MediaClient::slotLayoutChanged(int index)
|
||||
{
|
||||
if (0 == index)
|
||||
{
|
||||
slotLayoutOne();
|
||||
}
|
||||
else if (1 == index)
|
||||
{
|
||||
slotLayoutTwo();
|
||||
}
|
||||
else if (2 == index)
|
||||
{
|
||||
slotLayoutFour();
|
||||
}
|
||||
else if (3 == index)
|
||||
{
|
||||
slotLayoutSix();
|
||||
}
|
||||
else if (4 == index)
|
||||
{
|
||||
slotLayoutNine();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotWidgetSelecting(QWidget * pWidget)
|
||||
{
|
||||
if (m_curWidget != pWidget)
|
||||
{
|
||||
m_curWidget->parentWidget()->setStyleSheet("background-color: white;");
|
||||
|
||||
m_curWidget = (VideoWidget *) pWidget;
|
||||
m_curWidget->parentWidget()->setStyleSheet("background-color: blue;");
|
||||
|
||||
if (m_curWidget->isRecording())
|
||||
{
|
||||
ui.labTipInfo->setText(tr("Recording ..."));
|
||||
|
||||
QIcon icon;
|
||||
icon.addFile(QString(":/res/Resources/stop_record.png"));
|
||||
ui.btnRecord->setIcon(icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.labTipInfo->setText("");
|
||||
|
||||
QIcon icon;
|
||||
icon.addFile(QString(":/res/Resources/video_record.png"));
|
||||
ui.btnRecord->setIcon(icon);
|
||||
}
|
||||
|
||||
if (m_curWidget->isMute())
|
||||
{
|
||||
ui.btnVolume->setIcon(QIcon(QString::fromUtf8(":/res/Resources/mute.png")));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.btnVolume->setIcon(QIcon(QString::fromUtf8(":/res/Resources/volume.png")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotPlay()
|
||||
{
|
||||
QString url = m_curWidget->getUrl();
|
||||
QString user = m_curWidget->getUser();
|
||||
QString pass = m_curWidget->getPass();
|
||||
|
||||
if (url.isEmpty())
|
||||
{
|
||||
url = m_url;
|
||||
user = m_user;
|
||||
pass = m_pass;
|
||||
}
|
||||
|
||||
OpenMedia dlg(url, user, pass, this);
|
||||
|
||||
dlg.resize(width(), dlg.height());
|
||||
|
||||
if (QDialog::Accepted == dlg.exec())
|
||||
{
|
||||
m_url = dlg.getUrl();
|
||||
m_user = dlg.getUser();
|
||||
m_pass = dlg.getPass();
|
||||
|
||||
m_curWidget->play(m_url, m_user, m_pass);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotPause()
|
||||
{
|
||||
m_curWidget->pause();
|
||||
}
|
||||
|
||||
void MediaClient::slotStop()
|
||||
{
|
||||
m_curWidget->stop();
|
||||
|
||||
ui.labTipInfo->setText(tr(""));
|
||||
ui.btnVolume->setIcon(QIcon(QString::fromUtf8(":/res/Resources/volume.png")));
|
||||
ui.btnRecord->setIcon(QIcon(QString::fromUtf8(":/res/Resources/video_record.png")));
|
||||
}
|
||||
|
||||
void MediaClient::slotCallState(QWidget* pWidget, int event)
|
||||
{
|
||||
if (m_curWidget != pWidget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == RTSP_EVE_CONNECTING ||
|
||||
event == RTMP_EVE_CONNECTING ||
|
||||
event == HTTP_FLV_EVE_CONNECTING ||
|
||||
event == MJPEG_EVE_CONNECTING ||
|
||||
event == SRT_EVE_CONNECTING)
|
||||
{
|
||||
ui.labTipInfo->setText(tr("Connecting..."));
|
||||
}
|
||||
else if (event == RTSP_EVE_CONNFAIL ||
|
||||
event == RTMP_EVE_CONNFAIL ||
|
||||
event == HTTP_FLV_EVE_CONNFAIL ||
|
||||
event == MJPEG_EVE_CONNFAIL ||
|
||||
event == SRT_EVE_CONNFAIL)
|
||||
{
|
||||
ui.labTipInfo->setText(tr("Connect failed"));
|
||||
}
|
||||
else if (event == RTSP_EVE_CONNSUCC ||
|
||||
event == MJPEG_EVE_CONNSUCC ||
|
||||
event == RTMP_EVE_VIDEOREADY ||
|
||||
event == RTMP_EVE_AUDIOREADY ||
|
||||
event == HTTP_FLV_EVE_VIDEOREADY ||
|
||||
event == HTTP_FLV_EVE_AUDIOREADY ||
|
||||
event == SRT_EVE_VIDEOREADY ||
|
||||
event == SRT_EVE_AUDIOREADY)
|
||||
{
|
||||
ui.labTipInfo->setText(tr(""));
|
||||
}
|
||||
else if (event == RTSP_EVE_NOSIGNAL ||
|
||||
event == RTMP_EVE_NOSIGNAL ||
|
||||
event == HTTP_FLV_EVE_NOSIGNAL ||
|
||||
event == MJPEG_EVE_NOSIGNAL ||
|
||||
event == SRT_EVE_NOSIGNAL)
|
||||
{
|
||||
ui.labTipInfo->setText(tr("NO Signal"));
|
||||
}
|
||||
else if (event == RTSP_EVE_NODATA ||
|
||||
event == RTMP_EVE_NODATA ||
|
||||
event == HTTP_FLV_EVE_NODATA ||
|
||||
event == MJPEG_EVE_NODATA ||
|
||||
event == SRT_EVE_NODATA)
|
||||
{
|
||||
ui.labTipInfo->setText(tr("No Data"));
|
||||
}
|
||||
else if (event == RTSP_EVE_RESUME ||
|
||||
event == RTMP_EVE_RESUME ||
|
||||
event == HTTP_FLV_EVE_RESUME ||
|
||||
event == MJPEG_EVE_RESUME ||
|
||||
event == SRT_EVE_RESUME)
|
||||
{
|
||||
ui.labTipInfo->setText(tr(""));
|
||||
}
|
||||
else if (event == RTSP_EVE_AUTHFAILED ||
|
||||
event == RTMP_EVE_AUTHFAILED||
|
||||
event == HTTP_FLV_EVE_AUTHFAILED ||
|
||||
event == MJPEG_EVE_AUTHFAILED ||
|
||||
event == SRT_EVE_AUTHFAILED)
|
||||
{
|
||||
ui.labTipInfo->setText(tr("Authenticate failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotSnapshot()
|
||||
{
|
||||
m_curWidget->snapshot();
|
||||
}
|
||||
|
||||
void MediaClient::slotRecord()
|
||||
{
|
||||
m_curWidget->record();
|
||||
|
||||
if (m_curWidget->isRecording())
|
||||
{
|
||||
ui.labTipInfo->setText(tr(" Recording ..."));
|
||||
|
||||
ui.btnRecord->setIcon(QIcon(QString::fromUtf8(":/res/Resources/stop_record.png")));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.labTipInfo->setText("");
|
||||
|
||||
ui.btnRecord->setIcon(QIcon(QString::fromUtf8(":/res/Resources/video_record.png")));
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotSnapshotResult(bool ret)
|
||||
{
|
||||
QString msg;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
msg = tr("Snapshot success");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = tr("Snapshot failed");
|
||||
}
|
||||
|
||||
InstMsgDialog dlg(msg, 2000);
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MediaClient::slotRecordResult(bool ret)
|
||||
{
|
||||
ui.btnRecord->setIcon(QIcon(QString::fromUtf8(":/res/Resources/video_record.png")));
|
||||
|
||||
QString msg;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
msg = tr("Video recording success");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = tr("Video recording failed");
|
||||
}
|
||||
|
||||
InstMsgDialog dlg(msg, 2000);
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MediaClient::slotVolume()
|
||||
{
|
||||
if (!m_curWidget->isPlaying())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_curWidget->isMute())
|
||||
{
|
||||
ui.btnVolume->setIcon(QIcon(QString::fromUtf8(":/res/Resources/volume.png")));
|
||||
|
||||
m_curWidget->setMute(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.btnVolume->setIcon(QIcon(QString::fromUtf8(":/res/Resources/mute.png")));
|
||||
|
||||
m_curWidget->setMute(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotUpdateStatistics(int bytes)
|
||||
{
|
||||
int kb = 0, mb = 0;
|
||||
char buff[100];
|
||||
|
||||
m_recvBytes += bytes;
|
||||
|
||||
if (m_recvBytes >= 1000)
|
||||
{
|
||||
kb = m_recvBytes / 1000;
|
||||
}
|
||||
|
||||
if (kb >= 1000)
|
||||
{
|
||||
mb = kb / 1000;
|
||||
kb = kb % 1000;
|
||||
kb = kb / 10;
|
||||
|
||||
sprintf(buff, " %d.%02d MB", mb, kb);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buff, " %d KB", kb);
|
||||
}
|
||||
|
||||
ui.labStatistics->setText(tr("RX:") + buff);
|
||||
}
|
||||
|
||||
void MediaClient::slotOrientationChanged(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
setupLayout(orientation);
|
||||
}
|
||||
|
||||
void MediaClient::setupLayout(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
log_print(HT_LOG_DBG, "setupLayout, orientation = %d\r\n", orientation);
|
||||
|
||||
if (orientation == Qt::LandscapeOrientation ||
|
||||
orientation == Qt::InvertedLandscapeOrientation) // width > height
|
||||
{
|
||||
ui.infoWidget->layout()->removeWidget(ui.cmbLayout);
|
||||
ui.infoWidget->layout()->removeWidget(ui.labTipInfo);
|
||||
ui.infoWidget->layout()->removeWidget(ui.labStatistics);
|
||||
ui.infoWidget->hide();
|
||||
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer1);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnPlay);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnPause);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnStop);
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer2);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnVolume);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnSnapshot);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnRecord);
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer3);
|
||||
|
||||
ui.toolWidget->layout()->addWidget(ui.cmbLayout);
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer1);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnPlay);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnPause);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnStop);
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer2);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnVolume);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnSnapshot);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnRecord);
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer3);
|
||||
ui.toolWidget->layout()->addWidget(ui.labStatistics);
|
||||
}
|
||||
else // height > width
|
||||
{
|
||||
ui.infoWidget->layout()->removeWidget(ui.cmbLayout);
|
||||
ui.infoWidget->layout()->removeWidget(ui.labTipInfo);
|
||||
ui.infoWidget->layout()->removeWidget(ui.labStatistics);
|
||||
|
||||
ui.toolWidget->layout()->removeWidget(ui.labTipInfo);
|
||||
ui.toolWidget->layout()->removeWidget(ui.labStatistics);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnPlay);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnPause);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnStop);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnVolume);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnSnapshot);
|
||||
ui.toolWidget->layout()->removeWidget(ui.btnRecord);
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer1);
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer2);
|
||||
ui.toolWidget->layout()->removeItem(ui.horizontalSpacer3);
|
||||
|
||||
ui.infoWidget->layout()->addWidget(ui.cmbLayout);
|
||||
ui.infoWidget->layout()->addWidget(ui.labTipInfo);
|
||||
ui.infoWidget->layout()->addWidget(ui.labStatistics);
|
||||
ui.infoWidget->show();
|
||||
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer1);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnPlay);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnPause);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnStop);
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer2);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnVolume);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnSnapshot);
|
||||
ui.toolWidget->layout()->addWidget(ui.btnRecord);
|
||||
ui.toolWidget->layout()->addItem(ui.horizontalSpacer3);
|
||||
}
|
||||
|
||||
if (m_layoutMode == 2)
|
||||
{
|
||||
slotLayoutTwo();
|
||||
}
|
||||
else if (m_layoutMode == 6)
|
||||
{
|
||||
slotLayoutSix();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotSystemSetting()
|
||||
{
|
||||
SystemSetting dlg(m_syscfg, this);
|
||||
|
||||
if (QDialog::Accepted == dlg.exec())
|
||||
{
|
||||
SysConfig config = dlg.getSysConfig();
|
||||
|
||||
/* apply system config parameter */
|
||||
|
||||
if (m_syscfg.enableLog != config.enableLog)
|
||||
{
|
||||
if (m_syscfg.enableLog)
|
||||
{
|
||||
log_close();
|
||||
}
|
||||
else
|
||||
{
|
||||
initLog();
|
||||
}
|
||||
}
|
||||
|
||||
log_set_level(config.logLevel);
|
||||
|
||||
/* update system config parameter */
|
||||
m_syscfg.enableLog = config.enableLog;
|
||||
m_syscfg.videoRenderMode = config.videoRenderMode;
|
||||
m_syscfg.rtpMulticast = config.rtpMulticast;
|
||||
m_syscfg.rtpOverUdp = config.rtpOverUdp;
|
||||
m_syscfg.rtspOverHttp = config.rtspOverHttp;
|
||||
m_syscfg.rtspOverHttpPort = config.rtspOverHttpPort;
|
||||
m_syscfg.rtspOverWs = config.rtspOverWs;
|
||||
m_syscfg.rtspOverWsPort = config.rtspOverWsPort;
|
||||
m_syscfg.logLevel = config.logLevel;
|
||||
m_syscfg.hwDecoding = config.hwDecoding;
|
||||
m_syscfg.recordTime = config.recordTime;
|
||||
m_syscfg.recordSize = config.recordSize;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaClient::slotOpenSnapshot()
|
||||
{
|
||||
FileBrowse * pDlg = new FileBrowse(FILE_FORMAT_PIC, this);
|
||||
|
||||
pDlg->exec();
|
||||
|
||||
delete pDlg;
|
||||
}
|
||||
|
||||
void MediaClient::slotOpenRecording()
|
||||
{
|
||||
FileBrowse * pDlg = new FileBrowse(FILE_FORMAT_VIDEO, this);
|
||||
|
||||
pDlg->exec();
|
||||
|
||||
delete pDlg;
|
||||
}
|
||||
|
||||
void MediaClient::slotAbout()
|
||||
{
|
||||
About dlg(this);
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
90
MediaClient/MediaClientForMobile/formClass/MediaClient.h
Normal file
90
MediaClient/MediaClientForMobile/formClass/MediaClient.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef MEDIACLIENT_H
|
||||
#define MEDIACLIENT_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_MediaClient.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
class MediaClient : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MediaClient(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::Widget);
|
||||
~MediaClient();
|
||||
|
||||
private slots:
|
||||
void slotLayoutOne();
|
||||
void slotLayoutTwo();
|
||||
void slotLayoutFour();
|
||||
void slotLayoutSix();
|
||||
void slotLayoutNine();
|
||||
void slotLayoutChanged(int index);
|
||||
void slotPlay();
|
||||
void slotPause();
|
||||
void slotStop();
|
||||
void slotCallState(QWidget* pWidget, int event);
|
||||
void slotSnapshot();
|
||||
void slotRecord();
|
||||
void slotVolume();
|
||||
void slotSnapshotResult(bool ret);
|
||||
void slotRecordResult(bool ret);
|
||||
void slotUpdateStatistics(int bytes);
|
||||
void slotOrientationChanged(Qt::ScreenOrientation orientation);
|
||||
void slotWidgetSelecting(QWidget * pWidget);
|
||||
void slotSystemSetting();
|
||||
void slotOpenSnapshot();
|
||||
void slotOpenRecording();
|
||||
void slotAbout();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent * event);
|
||||
|
||||
private:
|
||||
void initLog();
|
||||
void initDialog();
|
||||
void connSignalSlot();
|
||||
void saveChannel(QList<CHANNEL> &channels, VideoWidget * widget);
|
||||
void connVideoWidget(VideoWidget * widget);
|
||||
void showBitrate(int bitrate);
|
||||
void setupLayout(Qt::ScreenOrientation orientation);
|
||||
void loadSystemConfig();
|
||||
void loadChannels();
|
||||
|
||||
private:
|
||||
Ui::MediaClient ui;
|
||||
|
||||
VideoWidget * m_curWidget;
|
||||
int m_layoutMode;
|
||||
uint64 m_recvBytes;
|
||||
|
||||
QString m_url;
|
||||
QString m_user;
|
||||
QString m_pass;
|
||||
|
||||
SysConfig m_syscfg;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
69
MediaClient/MediaClientForMobile/formClass/OpenMedia.cpp
Normal file
69
MediaClient/MediaClientForMobile/formClass/OpenMedia.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "OpenMedia.h"
|
||||
#include "utils.h"
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
OpenMedia::OpenMedia(QString &url, QString &user, QString &pass, QWidget *parent, Qt::WindowFlags flags)
|
||||
: QDialog(parent, flags)
|
||||
, m_url(url)
|
||||
, m_user(user)
|
||||
, m_pass(pass)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
ui.editUrl->setText(m_url);
|
||||
ui.editUser->setText(m_user);
|
||||
ui.editPass->setText(m_pass);
|
||||
|
||||
connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(close()));
|
||||
connect(ui.btnConfirm, SIGNAL(clicked()), this, SLOT(slotConfirm()));
|
||||
}
|
||||
|
||||
OpenMedia::~OpenMedia()
|
||||
{
|
||||
}
|
||||
|
||||
void OpenMedia::slotConfirm()
|
||||
{
|
||||
m_url = ui.editUrl->text();
|
||||
m_user = ui.editUser->text();
|
||||
m_pass = ui.editPass->text();
|
||||
|
||||
if (m_url.isEmpty())
|
||||
{
|
||||
ui.editUrl->setFocus();
|
||||
return;
|
||||
}
|
||||
else if (!isUrl(m_url))
|
||||
{
|
||||
QMessageBox::information(NULL, tr("Tips"), tr("Invalid URL format!"));
|
||||
ui.editUrl->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
49
MediaClient/MediaClientForMobile/formClass/OpenMedia.h
Normal file
49
MediaClient/MediaClientForMobile/formClass/OpenMedia.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef OPEN_MEDIA_H
|
||||
#define OPEN_MEDIA_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_OpenMedia.h"
|
||||
|
||||
class OpenMedia : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OpenMedia(QString &url, QString &user, QString &pass, QWidget *parent = 0, Qt::WindowFlags flags = Qt::Widget);
|
||||
~OpenMedia();
|
||||
|
||||
QString getUrl() { return m_url; }
|
||||
QString getUser() { return m_user; }
|
||||
QString getPass() { return m_pass; }
|
||||
|
||||
public slots:
|
||||
void slotConfirm();
|
||||
|
||||
private:
|
||||
Ui::OpenMedia ui;
|
||||
QString m_url;
|
||||
QString m_user;
|
||||
QString m_pass;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
128
MediaClient/MediaClientForMobile/formClass/SystemSetting.cpp
Normal file
128
MediaClient/MediaClientForMobile/formClass/SystemSetting.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "SystemSetting.h"
|
||||
#include "utils.h"
|
||||
#include "video_decoder.h"
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QScreen>
|
||||
|
||||
|
||||
SystemSetting::SystemSetting(SysConfig &config, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_syscfg(config)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
initDialog();
|
||||
connSignalSlot();
|
||||
}
|
||||
|
||||
SystemSetting::~SystemSetting()
|
||||
{
|
||||
}
|
||||
|
||||
void SystemSetting::initDialog()
|
||||
{
|
||||
ui.cmbLogLevel->addItem(tr("TRACE"));
|
||||
ui.cmbLogLevel->addItem(tr("DEBUG"));
|
||||
ui.cmbLogLevel->addItem(tr("INFO"));
|
||||
ui.cmbLogLevel->addItem(tr("WARNING"));
|
||||
ui.cmbLogLevel->addItem(tr("ERROR"));
|
||||
ui.cmbLogLevel->addItem(tr("FATAL"));
|
||||
|
||||
ui.cmbVideoRenderMode->addItem(tr("Keep the original aspect ratio"));
|
||||
ui.cmbVideoRenderMode->addItem(tr("Fill the whole window"));
|
||||
|
||||
#if defined(ANDROID)
|
||||
ui.cmbHWDecoding->addItem(tr("Automatic"), HW_DECODING_AUTO);
|
||||
ui.cmbHWDecoding->addItem(tr("Media Codec"), HW_DECODING_MEDIACODEC);
|
||||
ui.cmbHWDecoding->addItem(tr("Disable"), HW_DECODING_DISABLE);
|
||||
#elif defined(IOS)
|
||||
ui.cmbHWDecoding->addItem(tr("Automatic"), HW_DECODING_AUTO);
|
||||
ui.cmbHWDecoding->addItem(tr("Videotoolbox"), HW_DECODING_VIDEOTOOLBOX);
|
||||
ui.cmbHWDecoding->addItem(tr("Disable"), HW_DECODING_DISABLE);
|
||||
#endif
|
||||
|
||||
ui.chkEnableLog->setChecked(m_syscfg.enableLog);
|
||||
ui.chkRtpMulticast->setChecked(m_syscfg.rtpMulticast);
|
||||
ui.chkRtpOverUdp->setChecked(m_syscfg.rtpOverUdp);
|
||||
ui.chkRtspOverHttp->setChecked(m_syscfg.rtspOverHttp);
|
||||
ui.spinHttpPort->setValue(m_syscfg.rtspOverHttpPort);
|
||||
ui.chkRtspOverWs->setChecked(m_syscfg.rtspOverWs);
|
||||
ui.spinWsPort->setValue(m_syscfg.rtspOverWsPort);
|
||||
ui.cmbVideoRenderMode->setCurrentIndex(m_syscfg.videoRenderMode);
|
||||
ui.cmbLogLevel->setCurrentIndex(m_syscfg.logLevel);
|
||||
ui.timeRecordTime->setTime(QTime(0,0,0,0).addSecs(m_syscfg.recordTime));
|
||||
ui.spinRecordSize->setValue(m_syscfg.recordSize);
|
||||
|
||||
for (int i = 0; i < ui.cmbHWDecoding->count(); i++)
|
||||
{
|
||||
if (ui.cmbHWDecoding->itemData(i).toInt() == m_syscfg.hwDecoding)
|
||||
{
|
||||
ui.cmbHWDecoding->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
showMaximized();
|
||||
}
|
||||
|
||||
void SystemSetting::connSignalSlot()
|
||||
{
|
||||
connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(close()));
|
||||
connect(ui.btnConfirm, SIGNAL(clicked()), this, SLOT(slotConfirm()));
|
||||
}
|
||||
|
||||
void SystemSetting::slotConfirm()
|
||||
{
|
||||
m_syscfg.enableLog = ui.chkEnableLog->isChecked();
|
||||
m_syscfg.logLevel = ui.cmbLogLevel->currentIndex();
|
||||
m_syscfg.rtpMulticast = ui.chkRtpMulticast->isChecked();
|
||||
m_syscfg.rtpOverUdp = ui.chkRtpOverUdp->isChecked();
|
||||
m_syscfg.rtspOverHttp = ui.chkRtspOverHttp->isChecked();
|
||||
m_syscfg.rtspOverHttpPort = ui.spinHttpPort->value();
|
||||
m_syscfg.rtspOverWs = ui.chkRtspOverWs->isChecked();
|
||||
m_syscfg.rtspOverWsPort = ui.spinWsPort->value();
|
||||
m_syscfg.recordTime = QTime(0, 0, 0, 0).secsTo(ui.timeRecordTime->time());
|
||||
m_syscfg.recordSize = ui.spinRecordSize->value();
|
||||
m_syscfg.videoRenderMode = ui.cmbVideoRenderMode->currentIndex();
|
||||
m_syscfg.hwDecoding = ui.cmbHWDecoding->currentData().toInt();
|
||||
|
||||
saveEnableLogFlag(m_syscfg.enableLog);
|
||||
saveLogLevel(m_syscfg.logLevel);
|
||||
saveRtpMulticast(m_syscfg.rtpMulticast);
|
||||
saveRtpOverUdp(m_syscfg.rtpOverUdp);
|
||||
saveRtspOverHttp(m_syscfg.rtspOverHttp);
|
||||
saveRtspOverHttpPort(m_syscfg.rtspOverHttpPort);
|
||||
saveRtspOverWs(m_syscfg.rtspOverWs);
|
||||
saveRtspOverWsPort(m_syscfg.rtspOverWsPort);
|
||||
saveRecordTime(m_syscfg.recordTime);
|
||||
saveRecordSize(m_syscfg.recordSize);
|
||||
saveVideoRenderMode(m_syscfg.videoRenderMode);
|
||||
saveHWDecoding(m_syscfg.hwDecoding);
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
|
||||
|
||||
56
MediaClient/MediaClientForMobile/formClass/SystemSetting.h
Normal file
56
MediaClient/MediaClientForMobile/formClass/SystemSetting.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef _SYSTEM_SETTING_H_
|
||||
#define _SYSTEM_SETTING_H_
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include <QDialog>
|
||||
#include "ui_SystemSetting.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
class SystemSetting : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SystemSetting(SysConfig &config, QWidget *parent = 0);
|
||||
~SystemSetting();
|
||||
|
||||
SysConfig getSysConfig(){return m_syscfg;}
|
||||
|
||||
private slots:
|
||||
void slotConfirm();
|
||||
|
||||
private:
|
||||
void initDialog();
|
||||
void connSignalSlot();
|
||||
|
||||
private:
|
||||
Ui::SystemSetting ui;
|
||||
|
||||
SysConfig m_syscfg;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
732
MediaClient/MediaClientForMobile/formClass/VideoWidget.cpp
Normal file
732
MediaClient/MediaClientForMobile/formClass/VideoWidget.cpp
Normal file
@@ -0,0 +1,732 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "VideoWidget.h"
|
||||
#include "utils.h"
|
||||
#include "InstMsgDialog.h"
|
||||
#include "rtsp_player.h"
|
||||
#include "rtmp_player.h"
|
||||
#include "http_flv_player.h"
|
||||
#include "http_mjpeg_player.h"
|
||||
#include "srt_player.h"
|
||||
#include "file_player.h"
|
||||
#include "http_test.h"
|
||||
#include <QPainter>
|
||||
#include <QMessageBox>
|
||||
#include <QScreen>
|
||||
#include <QPaintEvent>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QApplication>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <QJniObject>
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#define VERTEXIN 0
|
||||
#define TEXTUREIN 1
|
||||
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
VideoWidget::VideoWidget(QWidget * parent, Qt::WindowFlags f)
|
||||
: QOpenGLWidget(parent, f)
|
||||
, m_pPlayer(NULL)
|
||||
, m_bMute(FALSE)
|
||||
, m_bRecording(FALSE)
|
||||
, m_pRenderFrame(NULL)
|
||||
#ifdef BACKCHANNEL
|
||||
, m_nBackChannelFlag(0)
|
||||
#endif
|
||||
{
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
m_timerReconn.setSingleShot(true);
|
||||
|
||||
connect(&m_timerReconn, SIGNAL(timeout()), this, SLOT(slotReconn()));
|
||||
connect(this, SIGNAL(imageReady()), this, SLOT(update()), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
VideoWidget::~VideoWidget()
|
||||
{
|
||||
closeVideo();
|
||||
|
||||
makeCurrent();
|
||||
vbo.destroy();
|
||||
textureY->destroy();
|
||||
textureU->destroy();
|
||||
textureV->destroy();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void VideoWidget::play(QString url, QString acct, QString pass)
|
||||
{
|
||||
if (m_url == url && m_acct == acct && m_pass == pass)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
closeVideo();
|
||||
|
||||
m_url = url;
|
||||
m_acct = acct;
|
||||
m_pass = pass;
|
||||
m_base = getBaseName(url);
|
||||
|
||||
if (!m_url.isEmpty())
|
||||
{
|
||||
makeCall();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::pause()
|
||||
{
|
||||
if (m_pPlayer)
|
||||
{
|
||||
m_pPlayer->pause();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::stop()
|
||||
{
|
||||
closeVideo();
|
||||
}
|
||||
|
||||
void VideoWidget::closePlayer()
|
||||
{
|
||||
m_timerReconn.stop();
|
||||
|
||||
if (m_pPlayer)
|
||||
{
|
||||
delete m_pPlayer;
|
||||
m_pPlayer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::closeVideo()
|
||||
{
|
||||
closePlayer();
|
||||
|
||||
m_url = "";
|
||||
m_acct = "";
|
||||
m_pass = "";
|
||||
m_bRecording = FALSE;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_pRenderFrame)
|
||||
{
|
||||
av_frame_free(&m_pRenderFrame);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
BOOL VideoWidget::isRecording()
|
||||
{
|
||||
if (m_pPlayer)
|
||||
{
|
||||
return m_pPlayer->isRecording();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void VideoWidget::makeCall()
|
||||
{
|
||||
BOOL isFile = 0;
|
||||
BOOL isRtsp = FALSE;
|
||||
|
||||
if (isRtspUrl(m_url))
|
||||
{
|
||||
isRtsp = TRUE;
|
||||
m_pPlayer = new CRtspPlayer(this);
|
||||
}
|
||||
else if (isRtmpUrl(m_url))
|
||||
{
|
||||
m_pPlayer = new CRtmpPlayer(this);
|
||||
}
|
||||
else if (isHttpUrl(m_url))
|
||||
{
|
||||
HTTPCTT ctt;
|
||||
|
||||
if (http_test(m_url.toStdString().c_str(), m_acct.toStdString().c_str(), m_pass.toStdString().c_str(), &ctt, 2*1000))
|
||||
{
|
||||
if (CTT_RTSP_TUNNELLED == ctt)
|
||||
{
|
||||
isRtsp = TRUE;
|
||||
m_pPlayer = new CRtspPlayer(this);
|
||||
}
|
||||
else if (CTT_FLV == ctt)
|
||||
{
|
||||
m_pPlayer = new CHttpFlvPlayer(this);
|
||||
}
|
||||
else if (CTT_MULTIPART == ctt)
|
||||
{
|
||||
m_pPlayer = new CHttpMjpegPlayer(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPlayer = new CHttpFlvPlayer(this);
|
||||
}
|
||||
}
|
||||
else if (isSrtUrl(m_url))
|
||||
{
|
||||
m_pPlayer = new CSrtPlayer(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
isFile = 1;
|
||||
m_pPlayer = new CFilePlayer(this);
|
||||
}
|
||||
|
||||
if (NULL == m_pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect(m_pPlayer, SIGNAL(notify(int)), this, SLOT(slotPlayerNotify(int)), Qt::QueuedConnection);
|
||||
connect(m_pPlayer, SIGNAL(snapshoted(AVFrame*)), this, SLOT(slotSnapshoted(AVFrame*)), Qt::QueuedConnection);
|
||||
connect(m_pPlayer, SIGNAL(imageReady(AVFrame*)), this, SLOT(slotImageReady(AVFrame*)), Qt::QueuedConnection);
|
||||
connect(m_pPlayer, SIGNAL(updateStatistics(int)), this, SIGNAL(updateStatistics(int)));
|
||||
|
||||
if (m_pPlayer->open(m_url, 0))
|
||||
{
|
||||
m_pPlayer->setAuthInfo(m_acct, m_pass);
|
||||
m_pPlayer->setHWDecoding(getHWDecoding());
|
||||
|
||||
if (isRtsp)
|
||||
{
|
||||
m_pPlayer->setRtpOverUdp(getRtpOverUdp());
|
||||
m_pPlayer->setRtpMulticast(getRtpMulticast());
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
m_pPlayer->setRtspOverHttp(getRtspOverHttp(), getRtspOverHttpPort());
|
||||
#endif
|
||||
#ifdef OVER_WEBSOCKET
|
||||
m_pPlayer->setRtspOverWs(getRtspOverWs(), getRtspOverWsPort());
|
||||
#endif
|
||||
#ifdef BACKCHANNEL
|
||||
m_pPlayer->setBCFlag(m_nBackChannelFlag);
|
||||
#endif
|
||||
}
|
||||
else if (isFile)
|
||||
{
|
||||
setMute(m_bMute);
|
||||
}
|
||||
|
||||
m_pPlayer->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
closePlayer();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
emit widgetSelecting(this);
|
||||
}
|
||||
|
||||
BOOL VideoWidget::micphone()
|
||||
{
|
||||
#ifdef BACKCHANNEL
|
||||
if (NULL == m_pPlayer)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
QJniObject str = QJniObject::fromString("android.permission.RECORD_AUDIO");
|
||||
QJniObject::callStaticMethod<jint>("org/happytimesoft/util/HtUtil",
|
||||
"requestPermission",
|
||||
"(Landroid/content/Context;Ljava/lang/String;)I",
|
||||
QNativeInterface::QAndroidApplication::context(),
|
||||
str.object<jstring>());
|
||||
#endif
|
||||
|
||||
closePlayer();
|
||||
|
||||
if (m_nBackChannelFlag)
|
||||
{
|
||||
m_nBackChannelFlag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nBackChannelFlag = 1;
|
||||
}
|
||||
|
||||
makeCall();
|
||||
|
||||
if (m_pPlayer)
|
||||
{
|
||||
m_pPlayer->setBCDataFlag(m_nBackChannelFlag);
|
||||
|
||||
return m_pPlayer->getBCFlag();
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void VideoWidget::setMute(BOOL flag)
|
||||
{
|
||||
m_bMute = flag;
|
||||
|
||||
if (m_pPlayer)
|
||||
{
|
||||
m_pPlayer->setVolume(flag ? HTVOLUME_MIN : HTVOLUME_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL VideoWidget::isPlaying()
|
||||
{
|
||||
if (m_pPlayer)
|
||||
{
|
||||
return m_pPlayer->isPlaying() || m_pPlayer->isPaused();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void VideoWidget::snapshot()
|
||||
{
|
||||
if (m_pPlayer)
|
||||
{
|
||||
m_pPlayer->snapshot(VIDEO_FMT_RGB24);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::slotSnapshoted(AVFrame * frame)
|
||||
{
|
||||
QImage image = QImage(frame->data[0], frame->width, frame->height, frame->linesize[0], QImage::Format_RGB888);
|
||||
QString file = getSnapshotPath() + "/" + getTempFile(m_base, ".jpg");
|
||||
|
||||
if (!image.save(file, "JPG"))
|
||||
{
|
||||
emit snapshotResult(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit snapshotResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL VideoWidget::record()
|
||||
{
|
||||
if (NULL == m_pPlayer)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (m_pPlayer->isRecording())
|
||||
{
|
||||
stopRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
startRecord();
|
||||
}
|
||||
|
||||
m_bRecording = m_pPlayer->isRecording();
|
||||
|
||||
return m_bRecording;
|
||||
}
|
||||
|
||||
void VideoWidget::startRecord()
|
||||
{
|
||||
if (NULL == m_pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pPlayer->isRecording())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QString file = getRecordPath() + "/" + getTempFile(m_base, ".avi");
|
||||
|
||||
m_pPlayer->record(file);
|
||||
}
|
||||
|
||||
void VideoWidget::stopRecord()
|
||||
{
|
||||
if (NULL == m_pPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pPlayer->isRecording())
|
||||
{
|
||||
m_pPlayer->stopRecord();
|
||||
|
||||
emit recordResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
QRect VideoWidget::getVideoRenderRect(int videoW, int videoH)
|
||||
{
|
||||
QRect rect = this->rect();
|
||||
qreal ratio = QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||
int w = rect.width() * ratio;
|
||||
int h = rect.height() * ratio;
|
||||
|
||||
if (getVideoRenderMode() == RENDER_MODE_KEEP) // keep the original aspect ratio
|
||||
{
|
||||
int iw = videoW;
|
||||
int ih = videoH;
|
||||
int nw, nh;
|
||||
|
||||
double vratio = iw / (double)ih;
|
||||
double wratio = w / (double)h;
|
||||
|
||||
if (vratio > wratio)
|
||||
{
|
||||
nw = w;
|
||||
nh = w * ih / iw;
|
||||
}
|
||||
else
|
||||
{
|
||||
nw = h * iw / ih;
|
||||
nh = h;
|
||||
}
|
||||
|
||||
rect.setLeft((w - nw) / 2);
|
||||
rect.setTop((h - nh) / 2);
|
||||
rect.setRight(rect.left() + nw);
|
||||
rect.setBottom(rect.top() + nh);
|
||||
}
|
||||
else // fill the whole window
|
||||
{
|
||||
rect.setLeft(0);
|
||||
rect.setTop(0);
|
||||
rect.setRight(w);
|
||||
rect.setBottom(h);
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void VideoWidget::slotImageReady(AVFrame * frame)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (m_pRenderFrame)
|
||||
{
|
||||
av_frame_free(&m_pRenderFrame);
|
||||
}
|
||||
|
||||
if (m_pPlayer)
|
||||
{
|
||||
m_pRenderFrame = frame;
|
||||
|
||||
emit imageReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::slotPlayerNotify(int event)
|
||||
{
|
||||
if (event == RTSP_EVE_CONNFAIL ||
|
||||
event == RTMP_EVE_CONNFAIL ||
|
||||
event == HTTP_FLV_EVE_CONNFAIL ||
|
||||
event == MJPEG_EVE_CONNFAIL ||
|
||||
event == SRT_EVE_CONNFAIL)
|
||||
{
|
||||
m_timerReconn.start(5 * 1000);
|
||||
}
|
||||
else if (event == RTSP_EVE_CONNSUCC ||
|
||||
event == MJPEG_EVE_CONNSUCC)
|
||||
{
|
||||
setMute(m_bMute);
|
||||
|
||||
// Re-record after reconnect
|
||||
if (m_bRecording)
|
||||
{
|
||||
startRecord();
|
||||
}
|
||||
}
|
||||
else if (event == RTMP_EVE_VIDEOREADY ||
|
||||
event == HTTP_FLV_EVE_VIDEOREADY ||
|
||||
event == SRT_EVE_VIDEOREADY)
|
||||
{
|
||||
// Re-record after reconnect
|
||||
if (m_bRecording)
|
||||
{
|
||||
startRecord();
|
||||
}
|
||||
}
|
||||
else if (event == RTMP_EVE_AUDIOREADY ||
|
||||
event == HTTP_FLV_EVE_AUDIOREADY ||
|
||||
event == SRT_EVE_AUDIOREADY)
|
||||
{
|
||||
setMute(m_bMute);
|
||||
}
|
||||
else if (event == RTSP_EVE_NOSIGNAL ||
|
||||
event == RTMP_EVE_NOSIGNAL ||
|
||||
event == HTTP_FLV_EVE_NOSIGNAL ||
|
||||
event == MJPEG_EVE_NOSIGNAL ||
|
||||
event == SRT_EVE_NOSIGNAL)
|
||||
{
|
||||
m_timerReconn.start(5 * 1000);
|
||||
}
|
||||
else if (event == RTSP_EVE_NODATA ||
|
||||
event == RTMP_EVE_NODATA ||
|
||||
event == HTTP_FLV_EVE_NODATA ||
|
||||
event == MJPEG_EVE_NODATA ||
|
||||
event == SRT_EVE_NODATA)
|
||||
{
|
||||
m_timerReconn.start(5 * 1000);
|
||||
}
|
||||
else if (event == RTSP_EVE_RESUME ||
|
||||
event == RTMP_EVE_RESUME ||
|
||||
event == HTTP_FLV_EVE_RESUME ||
|
||||
event == MJPEG_EVE_RESUME ||
|
||||
event == SRT_EVE_RESUME)
|
||||
{
|
||||
m_timerReconn.stop();
|
||||
}
|
||||
else if (event == RTSP_EVE_STOPPED ||
|
||||
event == RTMP_EVE_STOPPED ||
|
||||
event == HTTP_FLV_EVE_STOPPED ||
|
||||
event == MJPEG_EVE_STOPPED ||
|
||||
event == SRT_EVE_STOPPED)
|
||||
{
|
||||
m_timerReconn.start(5 * 1000);
|
||||
}
|
||||
|
||||
emit callState(this, event);
|
||||
}
|
||||
|
||||
void VideoWidget::slotReconn()
|
||||
{
|
||||
closePlayer();
|
||||
|
||||
makeCall();
|
||||
}
|
||||
|
||||
QString VideoWidget::getBaseName(QString &url)
|
||||
{
|
||||
if (isUrl(url))
|
||||
{
|
||||
char host[100] = {'\0'};
|
||||
|
||||
url_split(url.toStdString().c_str(), NULL, 0, NULL, 0, NULL, 0, host, sizeof(host), NULL, NULL, 0);
|
||||
|
||||
return QString(host);
|
||||
}
|
||||
else
|
||||
{
|
||||
QFileInfo fileInfo(url);
|
||||
|
||||
return fileInfo.baseName();
|
||||
}
|
||||
}
|
||||
|
||||
void VideoWidget::initializeGL()
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
static const GLfloat vertices[]
|
||||
{
|
||||
-1.0f, -1.0f,
|
||||
-1.0f, +1.0f,
|
||||
+1.0f, +1.0f,
|
||||
+1.0f, -1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
};
|
||||
|
||||
if (!vbo.create())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, vbo.create failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (!vbo.bind())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, vbo.bind failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
vbo.allocate(vertices, sizeof(vertices));
|
||||
|
||||
QOpenGLShader * vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||
const char * vsrc =
|
||||
"attribute vec4 vertexIn; \n"
|
||||
"attribute vec2 textureIn; \n"
|
||||
"varying highp vec2 textureOut; \n"
|
||||
"void main(void) \n"
|
||||
"{ \n"
|
||||
" gl_Position = vertexIn; \n"
|
||||
" textureOut = textureIn; \n"
|
||||
"}";
|
||||
if (!vshader->compileSourceCode(vsrc))
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, compile vertex source failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
QOpenGLShader * fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
|
||||
const char * fsrc =
|
||||
"varying highp vec2 textureOut; \n"
|
||||
"uniform sampler2D tex_y; \n"
|
||||
"uniform sampler2D tex_u; \n"
|
||||
"uniform sampler2D tex_v; \n"
|
||||
"void main(void) \n"
|
||||
"{ \n"
|
||||
" lowp vec3 yuv; \n"
|
||||
" lowp vec3 rgb; \n"
|
||||
" yuv.x = texture2D(tex_y, textureOut).r; \n"
|
||||
" yuv.y = texture2D(tex_u, textureOut).r - 0.5; \n"
|
||||
" yuv.z = texture2D(tex_v, textureOut).r - 0.5; \n"
|
||||
" rgb = mat3( 1, 1, 1, \n"
|
||||
" 0, -0.39465, 2.03211, \n"
|
||||
" 1.13983, -0.58060, 0) * yuv; \n"
|
||||
" gl_FragColor = vec4(rgb, 1); \n"
|
||||
"}";
|
||||
if (!fshader->compileSourceCode(fsrc))
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, compile fragment source failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
program = new QOpenGLShaderProgram(this);
|
||||
|
||||
if (!program->addShader(vshader))
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, add vertex shader failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (!program->addShader(fshader))
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, add fragment shader failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
program->bindAttributeLocation("vertexIn", VERTEXIN);
|
||||
program->bindAttributeLocation("textureIn", TEXTUREIN);
|
||||
|
||||
if (!program->link())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, link failed. %s\r\n", __FUNCTION__, program->log().toStdString().c_str());
|
||||
}
|
||||
|
||||
if (!program->bind())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, program bind failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
program->enableAttributeArray(VERTEXIN);
|
||||
program->enableAttributeArray(TEXTUREIN);
|
||||
program->setAttributeBuffer(VERTEXIN, GL_FLOAT, 0, 2, 2*sizeof(GLfloat));
|
||||
program->setAttributeBuffer(TEXTUREIN, GL_FLOAT, 8*sizeof(GLfloat), 2, 2*sizeof(GLfloat));
|
||||
|
||||
textureUniformY = program->uniformLocation("tex_y");
|
||||
textureUniformU = program->uniformLocation("tex_u");
|
||||
textureUniformV = program->uniformLocation("tex_v");
|
||||
|
||||
textureY = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||
textureU = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||
textureV = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||
|
||||
if (!textureY->create())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, textureY create failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (!textureU->create())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, textureU create failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (!textureV->create())
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, textureV create failed\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
idY = textureY->textureId();
|
||||
idU = textureU->textureId();
|
||||
idV = textureV->textureId();
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0f);
|
||||
}
|
||||
|
||||
void VideoWidget::paintGL()
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (NULL == m_pRenderFrame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int videoW = m_pRenderFrame->width;
|
||||
int videoH = m_pRenderFrame->height;
|
||||
|
||||
QRect rect = getVideoRenderRect(videoW, videoH);
|
||||
|
||||
glViewport(rect.left(), rect.top(), rect.width(), rect.height());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, idY);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, videoW, videoH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pRenderFrame->data[0]);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, idU);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, videoW >> 1, videoH >> 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pRenderFrame->data[1]);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, idV);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, videoW >> 1, videoH >> 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pRenderFrame->data[2]);
|
||||
|
||||
glUniform1i(textureUniformY, 0);
|
||||
glUniform1i(textureUniformU, 1);
|
||||
glUniform1i(textureUniformV, 2);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
117
MediaClient/MediaClientForMobile/formClass/VideoWidget.h
Normal file
117
MediaClient/MediaClientForMobile/formClass/VideoWidget.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef VIDEO_WIDGET_H
|
||||
#define VIDEO_WIDGET_H
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "video_player.h"
|
||||
#include <QWidget>
|
||||
#include <QMutex>
|
||||
#include <QSwipeGesture>
|
||||
#include <QGestureEvent>
|
||||
#include <QTimer>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
|
||||
class VideoWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VideoWidget(QWidget * parent = 0, Qt::WindowFlags f = Qt::Widget);
|
||||
~VideoWidget();
|
||||
|
||||
void play(QString url, QString user, QString pass);
|
||||
void pause();
|
||||
void stop();
|
||||
void snapshot();
|
||||
BOOL record();
|
||||
void stopRecord();
|
||||
void setMute(BOOL flag);
|
||||
BOOL micphone();
|
||||
BOOL isPlaying();
|
||||
BOOL isMute() {return m_bMute;}
|
||||
BOOL isRecording();
|
||||
QString getUrl() { return m_url; }
|
||||
QString getUser() { return m_acct; }
|
||||
QString getPass() { return m_pass; }
|
||||
|
||||
private slots:
|
||||
void slotImageReady(AVFrame * frame);
|
||||
void slotPlayerNotify(int event);
|
||||
void slotReconn();
|
||||
void slotSnapshoted(AVFrame * frame);
|
||||
|
||||
signals:
|
||||
void callState(QWidget *, int);
|
||||
void snapshotResult(bool);
|
||||
void recordResult(bool);
|
||||
void updateStatistics(int);
|
||||
void imageReady();
|
||||
void widgetSelecting(QWidget *);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void initializeGL();
|
||||
void paintGL();
|
||||
|
||||
private:
|
||||
void closePlayer();
|
||||
void closeVideo();
|
||||
void makeCall();
|
||||
QRect getVideoRenderRect(int videoW, int videoH);
|
||||
void startRecord();
|
||||
QString getBaseName(QString &url);
|
||||
|
||||
private:
|
||||
QString m_url;
|
||||
QString m_acct;
|
||||
QString m_pass;
|
||||
QString m_base;
|
||||
|
||||
CVideoPlayer * m_pPlayer;
|
||||
QTimer m_timerReconn;
|
||||
BOOL m_bMute;
|
||||
BOOL m_bRecording;
|
||||
QMutex m_mutex;
|
||||
AVFrame * m_pRenderFrame;
|
||||
|
||||
#ifdef BACKCHANNEL
|
||||
int m_nBackChannelFlag;
|
||||
#endif
|
||||
|
||||
QOpenGLShaderProgram * program;
|
||||
QOpenGLBuffer vbo;
|
||||
GLuint textureUniformY;
|
||||
GLuint textureUniformU;
|
||||
GLuint textureUniformV;
|
||||
QOpenGLTexture* textureY = nullptr;
|
||||
QOpenGLTexture* textureU = nullptr;
|
||||
QOpenGLTexture* textureV = nullptr;
|
||||
GLuint idY, idU, idV;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user