Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
265 changes: 211 additions & 54 deletions UI/auth-restream.cpp

Large diffs are not rendered by default.

23 changes: 21 additions & 2 deletions UI/auth-restream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,42 @@

class BrowserDock;

struct RestreamEventDescription {
std::string id;
std::string title;
qint64 scheduledFor;
std::string showId;
};

class RestreamAuth : public OAuthStreamKey {
Q_OBJECT

bool uiLoaded = false;
std::string showId;

QCefWidget *chatWidgetBrowser = NULL;
QCefWidget *titlesWidgetBrowser = NULL;
QCefWidget *channelWidgetBrowser = NULL;

virtual bool RetryLogin() override;

virtual void SaveInternal() override;
virtual bool LoadInternal() override;

bool GetChannelInfo();

virtual void LoadUI() override;

public:
RestreamAuth(const Def &d);
~RestreamAuth();

QVector<RestreamEventDescription> GetBroadcastInfo();
std::string GetStreamingKey(std::string eventId);
bool SelectShow(std::string eventId, std::string showId);
void ResetShow();
std::string GetShowId();
bool IsBroadcastReady();

static std::shared_ptr<Auth> Login(QWidget *parent, const std::string &service_name);
};

bool IsRestreamService(const std::string &service);
6 changes: 5 additions & 1 deletion UI/cmake/feature-restream.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
if(RESTREAM_CLIENTID AND RESTREAM_HASH MATCHES "^(0|[a-fA-F0-9]+)$" AND TARGET OBS::browser-panels)
target_sources(obs-studio PRIVATE auth-restream.cpp auth-restream.hpp)
target_sources(
obs-studio
PRIVATE auth-restream.cpp auth-restream.hpp window-restream-actions.cpp window-restream-actions.hpp
)

target_enable_feature(obs-studio "Restream API connection" RESTREAM_ENABLED)
else()
target_disable_feature(obs-studio "Restream API connection")
Expand Down
1 change: 1 addition & 0 deletions UI/cmake/ui-qt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ set(
forms/OBSRemux.ui
forms/OBSUpdate.ui
forms/OBSYoutubeActions.ui
forms/OBSRestreamActions.ui
forms/source-toolbar/browser-source-toolbar.ui
forms/source-toolbar/color-source-toolbar.ui
forms/source-toolbar/device-select-toolbar.ui
Expand Down
12 changes: 12 additions & 0 deletions UI/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1589,3 +1589,15 @@ MultitrackVideo.IncompatibleSettings.UpdateAndStartStreaming="Update Settings an
MultitrackVideo.IncompatibleSettings.AudioChannels="%1 is not currently compatible with [Audio → General → Channels] set to '%2', %3"
MultitrackVideo.IncompatibleSettings.AudioChannelsSingle="[Audio → General → Channels] needs to be set to '%1'"
MultitrackVideo.IncompatibleSettings.AudioChannelsMultiple="%1 requires multiple different settings for [Audio → General → Channels]"

# Restream Actions
Restream.Actions.WindowTitle="Restream Broadcast Setup"
Restream.Actions.BroadcastSelectTitle="Select Existing Broadcast"
Restream.Actions.DashboardButton="Open Restream";
Restream.Actions.BroadcastSelectButton="Select broadcast"
Restream.Actions.BroadcastSelectAndStartButton="Select broadcast and start streaming"
Restream.Actions.BroadcastScheduled="Scheduled"
Restream.Actions.BroadcastLoadingTitle="Loading broadcast information..."
Restream.Actions.BroadcastLoadingText="Loading broadcast information for %1, please wait..."
Restream.Actions.BroadcastLoadingFailureTitle="Failed to load broadcast information"
Restream.Actions.BroadcastLoadingFailureText="Failed to load broadcast information for %1\n\n%2: %3"
187 changes: 187 additions & 0 deletions UI/forms/OBSRestreamActions.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OBSRestreamActions</class>
<widget class="QDialog" name="OBSRestreamActions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>821</width>
<height>738</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Restream.Actions.WindowTitle</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="ytEventList">
<attribute name="title">
<string>Restream.Actions.BroadcastSelectTitle</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>191</width>
<height>216</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_11">
<property name="styleSheet">
<string notr="true">border: 1px solid black;</string>
</property>
<property name="text">
<string>&lt;big&gt;Go live now&lt;/big&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>4</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,2,3">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="dashboardButton">
<property name="text">
<string>Restream.Actions.DashboardButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Restream.Actions.BroadcastSelectButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="okButton">
<property name="text">
<string>Restream.Actions.BroadcastSelectAndStartButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ClickableLabel</class>
<extends>QLabel</extends>
<header>clickable-label.hpp</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
58 changes: 56 additions & 2 deletions UI/window-basic-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
#include "window-youtube-actions.hpp"
#include "youtube-api-wrappers.hpp"
#endif
#ifdef RESTREAM_ENABLED
#include "window-restream-actions.hpp"
#endif
#include "window-whats-new.hpp"
#include "context-bar-controls.hpp"
#include "obs-proxy-style.hpp"
Expand Down Expand Up @@ -6480,6 +6483,22 @@ void OBSBasic::ShowYouTubeAutoStartWarning()
}
#endif

#ifdef RESTREAM_ENABLED
void OBSBasic::RestreamActionDialogOk(bool start_now)
{
auto *restreamAuth = dynamic_cast<RestreamAuth *>(GetAuth());

autoStartBroadcast = true;
autoStopBroadcast = true;
broadcastReady = restreamAuth->IsBroadcastReady();

emit BroadcastStreamReady(broadcastReady);

if (broadcastReady && start_now)
QMetaObject::invokeMethod(this, "StartStreaming");
}
#endif

void OBSBasic::StartStreaming()
{
if (outputHandler->StreamingActive())
Expand Down Expand Up @@ -6613,6 +6632,14 @@ void OBSBasic::BroadcastButtonClicked()
broadcastActive = false;
broadcastReady = false;

#ifdef RESTREAM_ENABLED
Auth *const auth = GetAuth();
if (auth && IsRestreamService(auth->service())) {
auto restreamAuth = dynamic_cast<RestreamAuth *>(auth);
broadcastReady = restreamAuth->IsBroadcastReady();
}
#endif

autoStopBroadcast = true;
QMetaObject::invokeMethod(this, "StopStreaming");
emit BroadcastStreamReady(broadcastReady);
Expand All @@ -6623,16 +6650,37 @@ void OBSBasic::BroadcastButtonClicked()
void OBSBasic::SetBroadcastFlowEnabled(bool enabled)
{
emit BroadcastFlowEnabled(enabled);

#ifdef RESTREAM_ENABLED
Auth *const auth = GetAuth();
if (auth && IsRestreamService(auth->service())) {
auto restreamAuth = dynamic_cast<RestreamAuth *>(auth);
broadcastReady = restreamAuth->IsBroadcastReady();
emit BroadcastStreamReady(broadcastReady);
}
#endif
}

void OBSBasic::SetupBroadcast()
{
#ifdef YOUTUBE_ENABLED
#if defined YOUTUBE_ENABLED || defined RESTREAM_ENABLED
Auth *const auth = GetAuth();
if (IsYouTubeService(auth->service())) {
#endif
#ifdef YOUTUBE_ENABLED
if (auth && IsYouTubeService(auth->service())) {
OBSYoutubeActions dialog(this, auth, broadcastReady);
connect(&dialog, &OBSYoutubeActions::ok, this, &OBSBasic::YouTubeActionDialogOk);
dialog.exec();
return;
}
#endif
#ifdef RESTREAM_ENABLED
if (auth && IsRestreamService(auth->service())) {

OBSRestreamActions dialog(this, auth, broadcastReady);
connect(&dialog, &OBSRestreamActions::ok, this, &OBSBasic::RestreamActionDialogOk);
dialog.exec();
return;
}
#endif
}
Expand Down Expand Up @@ -6949,6 +6997,12 @@ void OBSBasic::StreamingStop(int code, QString last_error)
youtubeAppDock->IngestionStopped();
#endif

#ifdef RESTREAM_ENABLED
Auth *const auth = GetAuth();
if (auth && IsRestreamService(auth->service()))
broadcastActive = false;
#endif

blog(LOG_INFO, STREAMING_STOP);

if (encode_error) {
Expand Down
3 changes: 3 additions & 0 deletions UI/window-basic-main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,9 @@ class OBSBasic : public OBSMainWindow {
void ShowYouTubeAutoStartWarning();
void YouTubeActionDialogOk(const QString &broadcast_id, const QString &stream_id, const QString &key,
bool autostart, bool autostop, bool start_now);
#endif
#ifdef RESTREAM_ENABLED
void RestreamActionDialogOk(bool start_now);
#endif
void BroadcastButtonClicked();
void SetBroadcastFlowEnabled(bool enabled);
Expand Down
Loading