mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Add brief description to Streamlink settings page
Add links to Streamlink website and download page to Streamlink settings page Make streamlink custom path usage more explicit Change how streamlink runs, it now works perfectly on Linux so that if you don't have a custom path set, it will try to just run "streamlink" in your PATH variable This needs testing on Windows again
This commit is contained in:
parent
aba8e1a18f
commit
49458e4fac
3 changed files with 115 additions and 46 deletions
|
@ -61,10 +61,6 @@ public:
|
|||
"/behaviour/autocompletion/onlyFetchChattersForSmallerStreamers", true};
|
||||
IntSetting smallStreamerLimit = {"/behaviour/autocompletion/smallStreamerLimit", 1000};
|
||||
|
||||
// Streamlink
|
||||
QStringSetting streamlinkPath = {"/behaviour/streamlink/path", ""};
|
||||
QStringSetting preferredQuality = {"/behaviour/streamlink/quality", "Choose"};
|
||||
QStringSetting streamlinkOpts = {"/behaviour/streamlink/options", ""};
|
||||
BoolSetting pauseChatHover = {"/behaviour/pauseChatHover", false};
|
||||
|
||||
/// Commands
|
||||
|
@ -114,6 +110,13 @@ public:
|
|||
|
||||
BoolSetting inlineWhispers = {"/whispers/enableInlineWhispers", true};
|
||||
|
||||
/// External tools
|
||||
// Streamlink
|
||||
BoolSetting streamlinkUseCustomPath = {"/external/streamlink/useCustomPath", false};
|
||||
QStringSetting streamlinkPath = {"/external/streamlink/customPath", ""};
|
||||
QStringSetting preferredQuality = {"/external/streamlink/quality", "Choose"};
|
||||
QStringSetting streamlinkOpts = {"/external/streamlink/options", ""};
|
||||
|
||||
void updateWordTypeMask();
|
||||
|
||||
void saveSnapshot();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "singletons/settingsmanager.hpp"
|
||||
#include "widgets/qualitypopup.hpp"
|
||||
|
||||
#include <QErrorMessage>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
|
@ -33,6 +34,17 @@ const char *GetDefaultBinaryPath()
|
|||
#endif
|
||||
}
|
||||
|
||||
QString getStreamlinkProgram()
|
||||
{
|
||||
auto app = getApp();
|
||||
|
||||
if (app->settings->streamlinkUseCustomPath) {
|
||||
return app->settings->streamlinkPath + "/" + GetBinaryName();
|
||||
} else {
|
||||
return GetBinaryName();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckStreamlinkPath(const QString &path)
|
||||
{
|
||||
QFileInfo fileinfo(path);
|
||||
|
@ -42,49 +54,57 @@ bool CheckStreamlinkPath(const QString &path)
|
|||
// throw Exception(fS("Streamlink path ({}) is invalid, file does not exist", path));
|
||||
}
|
||||
|
||||
if (fileinfo.isDir() || !fileinfo.isExecutable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return fileinfo.isExecutable();
|
||||
}
|
||||
|
||||
// TODO: Make streamlink binary finder smarter
|
||||
QString GetStreamlinkBinaryPath()
|
||||
void showStreamlinkNotFoundError()
|
||||
{
|
||||
static QErrorMessage *msg = new QErrorMessage;
|
||||
|
||||
auto app = getApp();
|
||||
|
||||
QString settingPath = app->settings->streamlinkPath;
|
||||
|
||||
QStringList paths;
|
||||
paths << settingPath;
|
||||
paths << GetDefaultBinaryPath();
|
||||
#ifdef _WIN32
|
||||
paths << settingPath + "\\" + GetBinaryName();
|
||||
paths << settingPath + "\\bin\\" + GetBinaryName();
|
||||
#else
|
||||
paths << "/usr/local/bin/streamlink";
|
||||
paths << "/bin/streamlink";
|
||||
#endif
|
||||
|
||||
for (const auto &path : paths) {
|
||||
if (CheckStreamlinkPath(path)) {
|
||||
return path;
|
||||
}
|
||||
if (app->settings->streamlinkUseCustomPath) {
|
||||
msg->showMessage(
|
||||
"Unable to find Streamlink executable\nMake sure your custom path is pointing "
|
||||
"to the DIRECTORY where the streamlink executable is located");
|
||||
} else {
|
||||
msg->showMessage("Unable to find Streamlink executable.\nIf you have Streamlink "
|
||||
"installed, you might need to enable the custom path option");
|
||||
}
|
||||
|
||||
throw Exception("Unable to find streamlink binary. Install streamlink or set the binary path "
|
||||
"in the settings dialog.");
|
||||
}
|
||||
|
||||
QProcess *createStreamlinkProcess()
|
||||
{
|
||||
auto p = new QProcess;
|
||||
p->setProgram(getStreamlinkProgram());
|
||||
|
||||
QObject::connect(p, &QProcess::errorOccurred, [=](auto err) {
|
||||
if (err == QProcess::FailedToStart) {
|
||||
showStreamlinkNotFoundError();
|
||||
} else {
|
||||
qDebug() << "Error occured: " << err; //
|
||||
}
|
||||
|
||||
p->deleteLater();
|
||||
});
|
||||
|
||||
QObject::connect(p, static_cast<void (QProcess::*)(int)>(&QProcess::finished), [=](int res) {
|
||||
p->deleteLater(); //
|
||||
});
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void GetStreamQualities(const QString &channelURL, std::function<void(QStringList)> cb)
|
||||
{
|
||||
QString path = GetStreamlinkBinaryPath();
|
||||
auto p = createStreamlinkProcess();
|
||||
|
||||
// XXX: Memory leak
|
||||
QProcess *p = new QProcess();
|
||||
|
||||
QObject::connect(p, static_cast<void (QProcess::*)(int)>(&QProcess::finished), [=](int) {
|
||||
QObject::connect(p, static_cast<void (QProcess::*)(int)>(&QProcess::finished), [=](int res) {
|
||||
if (res != 0) {
|
||||
qDebug() << "Got error code" << res;
|
||||
// return;
|
||||
}
|
||||
QString lastLine = QString(p->readAllStandardOutput());
|
||||
lastLine = lastLine.trimmed().split('\n').last().trimmed();
|
||||
if (lastLine.startsWith("Available streams: ")) {
|
||||
|
@ -106,17 +126,15 @@ void GetStreamQualities(const QString &channelURL, std::function<void(QStringLis
|
|||
}
|
||||
});
|
||||
|
||||
p->start(path, {channelURL, "--default-stream=KKona"});
|
||||
}
|
||||
p->setArguments({channelURL, "--default-stream=KKona"});
|
||||
|
||||
} // namespace
|
||||
p->start();
|
||||
}
|
||||
|
||||
void OpenStreamlink(const QString &channelURL, const QString &quality, QStringList extraArguments)
|
||||
{
|
||||
auto app = getApp();
|
||||
|
||||
QString path = GetStreamlinkBinaryPath();
|
||||
|
||||
QStringList arguments;
|
||||
|
||||
QString additionalOptions = app->settings->streamlinkOpts.getValue();
|
||||
|
@ -132,7 +150,15 @@ void OpenStreamlink(const QString &channelURL, const QString &quality, QStringLi
|
|||
arguments << quality;
|
||||
}
|
||||
|
||||
QProcess::startDetached(path, arguments);
|
||||
auto p = createStreamlinkProcess();
|
||||
|
||||
p->setArguments(arguments);
|
||||
|
||||
bool res = p->startDetached();
|
||||
|
||||
if (!res) {
|
||||
showStreamlinkNotFoundError();
|
||||
}
|
||||
}
|
||||
|
||||
void Start(const QString &channel)
|
||||
|
|
|
@ -11,6 +11,15 @@ namespace chatterino {
|
|||
namespace widgets {
|
||||
namespace settingspages {
|
||||
|
||||
namespace {
|
||||
|
||||
QString CreateLink(const QString &url, const QString &name)
|
||||
{
|
||||
return QString("<a href=\"" + url + "\"><span style=\"color: white;\">" + name + "</span></a>");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ExternalToolsPage::ExternalToolsPage()
|
||||
: SettingsPage("External tools", "")
|
||||
{
|
||||
|
@ -22,13 +31,44 @@ ExternalToolsPage::ExternalToolsPage()
|
|||
{
|
||||
auto group = layout.emplace<QGroupBox>("Streamlink");
|
||||
auto groupLayout = group.setLayoutType<QFormLayout>();
|
||||
groupLayout->addRow("Streamlink path:",
|
||||
this->createLineEdit(app->settings->streamlinkPath));
|
||||
|
||||
auto description =
|
||||
new QLabel("Streamlink is a command-line utility that pipes video streams from various "
|
||||
"services into a video player, such as VLC. Make sure to edit the "
|
||||
"configuration file before you use it!");
|
||||
description->setWordWrap(true);
|
||||
description->setStyleSheet("color: #bbb");
|
||||
|
||||
auto links = new QLabel(
|
||||
CreateLink("https://streamlink.github.io/", "Website") + " " +
|
||||
CreateLink("https://github.com/streamlink/streamlink/releases/latest", "Download"));
|
||||
links->setTextFormat(Qt::RichText);
|
||||
links->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::LinksAccessibleByKeyboard |
|
||||
Qt::LinksAccessibleByKeyboard);
|
||||
links->setOpenExternalLinks(true);
|
||||
|
||||
groupLayout->setWidget(0, QFormLayout::SpanningRole, description);
|
||||
groupLayout->setWidget(1, QFormLayout::SpanningRole, links);
|
||||
|
||||
auto customPathCb = this->createCheckBox(
|
||||
"Use custom path (Enable if using non-standard streamlink installation path)",
|
||||
app->settings->streamlinkUseCustomPath);
|
||||
groupLayout->setWidget(2, QFormLayout::SpanningRole, customPathCb);
|
||||
|
||||
auto customPath = this->createLineEdit(app->settings->streamlinkPath);
|
||||
customPath->setPlaceholderText("Path to folder where Streamlink executable can be found");
|
||||
groupLayout->addRow("Custom streamlink path:", customPath);
|
||||
groupLayout->addRow(
|
||||
"Prefered quality:",
|
||||
"Preferred quality:",
|
||||
this->createComboBox({STREAMLINK_QUALITY}, app->settings->preferredQuality));
|
||||
groupLayout->addRow("Additional options:",
|
||||
this->createLineEdit(app->settings->streamlinkOpts));
|
||||
|
||||
app->settings->streamlinkUseCustomPath.connect(
|
||||
[=](const auto &value, auto) {
|
||||
customPath->setEnabled(value); //
|
||||
},
|
||||
this->managedConnections);
|
||||
}
|
||||
|
||||
layout->addStretch(1);
|
||||
|
|
Loading…
Reference in a new issue