Pass network proxy settings to gstreamer

Fixes #558
This commit is contained in:
Jonas Kvinge 2020-11-04 22:16:20 +01:00
parent 47e2905edf
commit 914dee8571
7 changed files with 71 additions and 0 deletions

View File

@ -34,6 +34,7 @@
#include "engine_fwd.h"
#include "enginebase.h"
#include "settings/backendsettingspage.h"
#include "settings/networkproxysettingspage.h"
Engine::Base::Base()
: volume_(100),
@ -56,6 +57,7 @@ Engine::Base::Base()
fadeout_pause_enabled_(false),
fadeout_duration_(2),
fadeout_duration_nanosec_(2 * kNsecPerSec),
proxy_authentication_(false),
about_to_end_emitted_(false) {}
Engine::Base::~Base() {}
@ -127,6 +129,31 @@ void Engine::Base::ReloadSettings() {
s.endGroup();
s.beginGroup(NetworkProxySettingsPage::kSettingsGroup);
if (s.contains("engine") && s.value("engine").toBool()) {
QString proxy_host = s.value("hostname").toString();
int proxy_port = s.value("port").toInt();
if (proxy_host.isEmpty() || proxy_port <= 0) {
proxy_address_.clear();
proxy_authentication_ = false;
proxy_user_.clear();
proxy_pass_.clear();
}
else {
proxy_address_ = QString("%1:%2").arg(proxy_host).arg(proxy_port);
proxy_authentication_ = s.value("use_authentication").toBool();
proxy_user_ = s.value("username").toString();
proxy_pass_ = s.value("password").toString();
}
}
else {
proxy_address_.clear();
proxy_authentication_ = false;
proxy_user_.clear();
proxy_pass_.clear();
}
s.endGroup();
}
void Engine::Base::EmitAboutToEnd() {

View File

@ -200,6 +200,12 @@ public:
qint64 fadeout_pause_duration_;
qint64 fadeout_pause_duration_nanosec_;
// Proxy
QString proxy_address_;
bool proxy_authentication_;
QString proxy_user_;
QString proxy_pass_;
private:
bool about_to_end_emitted_;
Q_DISABLE_COPY(Base)

View File

@ -811,6 +811,7 @@ std::shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline() {
ret->set_buffer_duration_nanosec(buffer_duration_nanosec_);
ret->set_buffer_low_watermark(buffer_low_watermark_);
ret->set_buffer_high_watermark(buffer_high_watermark_);
ret->set_proxy_settings(proxy_address_, proxy_authentication_, proxy_user_, proxy_pass_);
ret->AddBufferConsumer(this);
for (GstBufferConsumer *consumer : buffer_consumers_) {

View File

@ -84,6 +84,7 @@ GstEnginePipeline::GstEnginePipeline(GstEngine *engine)
buffer_low_watermark_(BackendSettingsPage::kDefaultBufferLowWatermark),
buffer_high_watermark_(BackendSettingsPage::kDefaultBufferHighWatermark),
buffering_(false),
proxy_authentication_(false),
segment_start_(0),
segment_start_received_(false),
end_offset_nanosec_(-1),
@ -196,6 +197,13 @@ void GstEnginePipeline::set_buffer_high_watermark(const double value) {
buffer_high_watermark_ = value;
}
void GstEnginePipeline::set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass) {
proxy_address_ = address;
proxy_authentication_ = authentication;
proxy_user_ = user;
proxy_pass_ = pass;
}
bool GstEnginePipeline::InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec) {
stream_url_ = stream_url;
@ -491,6 +499,19 @@ void GstEnginePipeline::SourceSetupCallback(GstPlayBin *bin, GParamSpec*, gpoint
g_object_set(element, "ssl-strict", FALSE, nullptr);
}
if (!instance->proxy_address_.isEmpty() && g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy")) {
qLog(Debug) << "Setting proxy to" << instance->proxy_address_;
g_object_set(element, "proxy", instance->proxy_address_.toUtf8().constData(), nullptr);
if (instance->proxy_authentication_ &&
g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-id") &&
g_object_class_find_property(G_OBJECT_GET_CLASS(element), "proxy-pw") &&
!instance->proxy_user_.isEmpty() &&
!instance->proxy_pass_.isEmpty())
{
g_object_set(element, "proxy-id", instance->proxy_user_.toUtf8().constData(), "proxy-pw", instance->proxy_pass_.toUtf8().constData(), nullptr);
}
}
// If the pipeline was buffering we stop that now.
if (instance->buffering_) {
instance->buffering_ = false;

View File

@ -73,6 +73,7 @@ class GstEnginePipeline : public QObject {
void set_buffer_duration_nanosec(const qint64 duration_nanosec);
void set_buffer_low_watermark(const double value);
void set_buffer_high_watermark(const double value);
void set_proxy_settings(const QString &address, const bool authentication, const QString &user, const QString &pass);
// Creates the pipeline, returns false on error
bool InitFromUrl(const QByteArray &stream_url, const QUrl original_url, const qint64 end_nanosec);
@ -213,6 +214,12 @@ class GstEnginePipeline : public QObject {
double buffer_high_watermark_;
bool buffering_;
// Proxy
QString proxy_address_;
bool proxy_authentication_;
QString proxy_user_;
QString proxy_pass_;
// These get called when there is a new audio buffer available
QList<GstBufferConsumer*> buffer_consumers_;
QMutex buffer_consumers_mutex_;

View File

@ -75,6 +75,7 @@ void NetworkProxySettingsPage::Load() {
ui_->proxy_auth->setChecked(s.value("use_authentication", false).toBool());
ui_->proxy_username->setText(s.value("username").toString());
ui_->proxy_password->setText(s.value("password").toString());
ui_->proxy_engine->setChecked(s.value("engine", true).toBool());
s.endGroup();
Init(ui_->layout_networkproxysettingspage->parentWidget());
@ -100,6 +101,7 @@ void NetworkProxySettingsPage::Save() {
s.setValue("use_authentication", ui_->proxy_auth->isChecked());
s.setValue("username", ui_->proxy_username->text());
s.setValue("password", ui_->proxy_password->text());
s.setValue("engine", ui_->proxy_engine->isChecked());
s.endGroup();
NetworkProxyFactory::Instance()->ReloadSettings();

View File

@ -127,6 +127,13 @@
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="proxy_engine">
<property name="text">
<string>Use proxy settings for streaming</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>