Skip to content
Closed
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
26 changes: 26 additions & 0 deletions UI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ if(BROWSER_AVAILABLE_INTERNAL)
add_definitions(-DBROWSER_AVAILABLE)
endif()

add_subdirectory(pre-stream-wizard)
add_subdirectory(obs-frontend-api)

# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -69,6 +70,7 @@ endif()
include_directories(${FFMPEG_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(SYSTEM "obs-frontend-api")
include_directories(SYSTEM "pre-stream-wizard")
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/deps/libff")
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/deps/json11")
Expand Down Expand Up @@ -188,6 +190,16 @@ set(obs_SOURCES
${obs_PLATFORM_SOURCES}
${obs_libffutil_SOURCES}
../deps/json11/json11.cpp
pre-stream-wizard/pre-stream-current-settings.cpp
pre-stream-wizard/pre-stream-wizard.cpp
pre-stream-wizard/page-input-display.cpp
pre-stream-wizard/page-start-prompt.cpp
pre-stream-wizard/page-select-settings.cpp
pre-stream-wizard/page-loading.cpp
pre-stream-wizard/page-completed.cpp
pre-stream-wizard/page-error.cpp
pre-stream-wizard/setting-selection-row.cpp
pre-stream-wizard/encoder-settings-provider-facebook.cpp
obs-app.cpp
window-dock.cpp
api-interface.cpp
Expand Down Expand Up @@ -220,6 +232,8 @@ set(obs_SOURCES
window-log-reply.cpp
window-projector.cpp
window-remux.cpp
common-settings.cpp
streaming-settings-util.cpp
auth-base.cpp
source-tree.cpp
scene-tree.cpp
Expand Down Expand Up @@ -258,6 +272,16 @@ set(obs_HEADERS
${obs_PLATFORM_HEADERS}
${obs_libffutil_HEADERS}
../deps/json11/json11.hpp
pre-stream-wizard/pre-stream-current-settings.hpp
pre-stream-wizard/pre-stream-wizard.hpp
pre-stream-wizard/page-input-display.hpp
pre-stream-wizard/page-start-prompt.hpp
pre-stream-wizard/page-select-settings.hpp
pre-stream-wizard/page-loading.hpp
pre-stream-wizard/page-completed.hpp
pre-stream-wizard/page-error.hpp
pre-stream-wizard/setting-selection-row.hpp
pre-stream-wizard/encoder-settings-provider-facebook.hpp
obs-app.hpp
platform.hpp
window-dock.hpp
Expand All @@ -282,6 +306,8 @@ set(obs_HEADERS
window-log-reply.hpp
window-projector.hpp
window-remux.hpp
common-settings.hpp
streaming-settings-util.hpp
auth-base.hpp
source-tree.hpp
scene-tree.hpp
Expand Down
184 changes: 184 additions & 0 deletions UI/common-settings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include "common-settings.hpp"

#include "audio-encoders.hpp"

bool CommonSettings::IsAdvancedMode(config_t *config)
{
const char *outputMode = config_get_string(config, "Output", "Mode");
return (strcmp(outputMode, "Advanced") == 0);
}

OBSData CommonSettings::GetDataFromJsonFile(const char *jsonFile)
{
char fullPath[512];
obs_data_t *data = nullptr;

int ret = GetProfilePath(fullPath, sizeof(fullPath), jsonFile);
if (ret > 0) {
BPtr<char> jsonData = os_quick_read_utf8_file(fullPath);
if (jsonData) {
data = obs_data_create_from_json(jsonData);
}
}

if (!data)
data = obs_data_create();

OBSData dataRet(data);
obs_data_release(data);
return dataRet;
}

void CommonSettings::GetConfigFPS(config_t *config, uint32_t &num,
uint32_t &den)
{
uint32_t type = config_get_uint(config, videoSection, "FPSType");

if (type == 1) //"Integer"
GetFPSInteger(config, num, den);
else if (type == 2) //"Fraction"
GetFPSFraction(config, num, den);
else if (false) //"Nanoseconds", currently not implemented
GetFPSNanoseconds(config, num, den);
else
GetFPSCommon(config, num, den);
}

double CommonSettings::GetConfigFPSDouble(config_t *config)
{
uint32_t num = 0;
uint32_t den = 0;
CommonSettings::GetConfigFPS(config, num, den);
return (double)num / (double)den;
}

void CommonSettings::GetFPSCommon(config_t *config, uint32_t &num,
uint32_t &den)
{
const char *val = config_get_string(config, videoSection, "FPSCommon");

if (strcmp(val, "10") == 0) {
num = 10;
den = 1;
} else if (strcmp(val, "20") == 0) {
num = 20;
den = 1;
} else if (strcmp(val, "24 NTSC") == 0) {
num = 24000;
den = 1001;
} else if (strcmp(val, "25 PAL") == 0) {
num = 25;
den = 1;
} else if (strcmp(val, "29.97") == 0) {
num = 30000;
den = 1001;
} else if (strcmp(val, "48") == 0) {
num = 48;
den = 1;
} else if (strcmp(val, "50 PAL") == 0) {
num = 50;
den = 1;
} else if (strcmp(val, "59.94") == 0) {
num = 60000;
den = 1001;
} else if (strcmp(val, "60") == 0) {
num = 60;
den = 1;
} else {
num = 30;
den = 1;
}
}

void CommonSettings::GetFPSInteger(config_t *config, uint32_t &num,
uint32_t &den)
{
num = (uint32_t)config_get_uint(config, videoSection, "FPSInt");
den = 1;
}

void CommonSettings::GetFPSFraction(config_t *config, uint32_t &num,
uint32_t &den)
{
num = (uint32_t)config_get_uint(config, videoSection, "FPSNum");
den = (uint32_t)config_get_uint(config, videoSection, "FPSDen");
}

void CommonSettings::GetFPSNanoseconds(config_t *config, uint32_t &num,
uint32_t &den)
{
num = 1000000000;
den = (uint32_t)config_get_uint(config, videoSection, "FPSNS");
}

int CommonSettings::GetAudioChannelCount(config_t *config)
{
const char *channelSetup =
config_get_string(config, "Audio", "ChannelSetup");

if (strcmp(channelSetup, "Mono") == 0)
return 1;
if (strcmp(channelSetup, "Stereo") == 0)
return 2;
if (strcmp(channelSetup, "2.1") == 0)
return 3;
if (strcmp(channelSetup, "4.0") == 0)
return 4;
if (strcmp(channelSetup, "4.1") == 0)
return 5;
if (strcmp(channelSetup, "5.1") == 0)
return 6;
if (strcmp(channelSetup, "7.1") == 0)
return 8;

return 2;
}

int CommonSettings::GetStreamingAudioBitrate(config_t *config)
{
if (IsAdvancedMode(config)) {
return GetAdvancedAudioBitrate(config);
}
return GetSimpleAudioBitrate(config);
}

int CommonSettings::GetSimpleAudioBitrate(config_t *config)
{
int bitrate = config_get_uint(config, "SimpleOutput", "ABitrate");
return FindClosestAvailableAACBitrate(bitrate);
}

int CommonSettings::GetAdvancedAudioBitrate(config_t *config)
{
int track = config_get_int(config, "AdvOut", "TrackIndex");
return GetAdvancedAudioBitrateForTrack(config, track - 1);
}

int CommonSettings::GetAdvancedAudioBitrateForTrack(config_t *config,
int trackIndex)
{
static const char *names[] = {
"Track1Bitrate", "Track2Bitrate", "Track3Bitrate",
"Track4Bitrate", "Track5Bitrate", "Track6Bitrate",
};

// Sanity check for out of bounds, clamp to bounds
if (trackIndex > 5) {
trackIndex = 5;
} else if (trackIndex < 0) {
trackIndex = 0;
}

int bitrate = (int)config_get_uint(config, "AdvOut", names[trackIndex]);
return FindClosestAvailableAACBitrate(bitrate);
}

int CommonSettings::GetVideoBitrateInUse(config_t *config)
{
if (!IsAdvancedMode(config)) {
return config_get_int(config, "SimpleOutput", "VBitrate");
}

OBSData streamEncSettings = GetDataFromJsonFile("streamEncoder.json");
return obs_data_get_int(streamEncSettings, "bitrate");
}
49 changes: 49 additions & 0 deletions UI/common-settings.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Helper to get common video and audio setting that are accessed from more than
one file.
*/
#pragma once

#include <obs.hpp>
#include "obs-app.hpp"

class CommonSettings {

public:
static bool IsAdvancedMode(config_t *config);
/* Shared Utility Functions --------------------------*/
static OBSData GetDataFromJsonFile(const char *jsonFile);

/* Framerate ----------------------------------------*/
static void GetConfigFPS(config_t *config, uint32_t &num,
uint32_t &den);
static double GetConfigFPSDouble(config_t *config);

/* Audio Data ---------------------------------------*/
// Returns int of audio, sub (the .1 in 2.1) is a channel i.e., 2.1 -> 3ch
static int GetAudioChannelCount(config_t *config);
// Gets streaming track's bitrate, simple or advanced mode
static int GetStreamingAudioBitrate(config_t *config);
static int GetSimpleAudioBitrate(config_t *config);
static int GetAdvancedAudioBitrate(config_t *config);
// Advanced setting's streaming bitrate for track number (starts at 1)
static int GetAdvancedAudioBitrateForTrack(config_t *config,
int trackIndex);

/* Stream Encoder ——————————————————————————————————*/
static int GetVideoBitrateInUse(config_t *config);
static void SetAllVideoBitrates(config_t *config, int newBitrate);

private:
// Reused Strings
static constexpr const char *videoSection = "Video";

static void GetFPSCommon(config_t *config, uint32_t &num,
uint32_t &den);
static void GetFPSInteger(config_t *config, uint32_t &num,
uint32_t &den);
static void GetFPSFraction(config_t *config, uint32_t &num,
uint32_t &den);
static void GetFPSNanoseconds(config_t *config, uint32_t &num,
uint32_t &den);
};
42 changes: 42 additions & 0 deletions UI/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ LogViewer="Log Viewer"
ShowOnStartup="Show on startup"
OpenFile="Open file"
AddValue="Add %1"
Loading="Loading"

# warning if program already open
AlreadyRunning.Title="OBS is already running"
Expand Down Expand Up @@ -707,6 +708,43 @@ Basic.Settings.Stream.MissingUrlAndApiKey="URL and Stream Key are missing.\n\nOp
Basic.Settings.Stream.MissingUrl="Stream URL is missing.\n\nOpen settings to enter the URL in the 'Stream' tab."
Basic.Settings.Stream.MissingStreamKey="Stream key is missing.\n\nOpen settings to enter the stream key in the 'Stream' tab."

## Pre-Live Wizard and Settings
Basic.Settings.Stream.PreLiveWizard.RunNow="Check stream settings"
PreLiveWizard.Title="Verify Stream Settings"
PreLiveWizard.Prompt.Title="Verify stream settings before stream"
PreLiveWizard.Prompt.Subtitle.Default="The streaming wizard suggests the most up-to-date settings to improve your stream's reliability, quality, and latency. \n\nSelect the resolution to stream to your account:"
PreLiveWizard.Prompt.Subtitle.FB="Your destination is set to Facebook Live."
PreLiveWizard.Prompt.Explainer="The Streaming wizard suggests the most up-to-date settings to improve your stream's reliability, quality, and latency."
PreLiveWizard.Prompt.ResSelectTitle="Select a resolution to stream:"
PreLiveWizard.Prompt.ResolutionHelp.FB="If you're unsure, click Open Facebook Live, then click on the \"Stream Health\" tab and scroll down to find your maximum resolution."
PreLiveWizard.Prompt.ResolutionHelpButton.FB="Open Facebook Live"
PreLiveWizard.Prompt.ResolutionHelpButton.FB.ToolTip="Open Facebook Live in your default web browser"
PreLiveWizard.Prompt.Resolution.720="720p (Recommended for general purpose)"
PreLiveWizard.Prompt.Resolution.1080="1080p (Recommended for gaming)"
PreLiveWizard.Prompt.Resolution.Current="%1x%2 (Current setting)"
PreLiveWizard.Loading.Title="Fetching updated settings"
PreLiveWizard.Configure.ServiceNotAvailable.Title="Service not supported"
PreLiveWizard.Configure.ServiceNotAvailable.Description="The service selected in stream settings does not yet have an encoder configuration service."
PreLiveWizard.Configure.Error.Url="Settings setup failed. Query: "
PreLiveWizard.Configure.Error.JsonParse="Problem with server response"
PreLiveWizard.Configure.Error.JsonParse.Description="Wizard is unavailable at the moment."
PreLiveWizard.Configure.Error.NoData="No new settings recieved."
PreLiveWizard.Configure.Error.NoData.Description=" "
PreLiveWizard.Selection.Title="Suggested Settings"
PreLiveWizard.Selection.Description="Suggested video settings for your best stream:"
PreLiveWizard.Completed.Title="Encoder configured"
PreLiveWizard.Completed.BodyText="Applied suggested settings and encoder is setup to stream. You can now close the wizard."
PreLiveWizard.Completed.FacebookOnly="To finish going live go to Facebook Live:"
PreLiveWizard.Error.Title="There was an issue verifying settings"
PreLiveWizard.Error.Subtitle="This doesn't block you from starting your stream."
PreLiveWizard.Error.Generic.Headline="Encoder service is not working right now."
PreLiveWizard.Error.Generic.BodyText="You can exit the wizard and try again."
PreLiveWizard.Error.NetworkTimeout="Check your network connection before starting a stream."
PreLiveWizard.Output.Mode.CodecProfile="Profile"
PreLiveWizard.Output.Mode.CodecLevel="Level"
PreLiveWizard.Output.Mode.RateControl="Rate Control"
PreLiveWizard.Output.Mode.StreamBuffer="Stream Buffer"

# basic mode 'output' settings
Basic.Settings.Output="Output"
Basic.Settings.Output.Format="Recording Format"
Expand Down Expand Up @@ -797,6 +835,10 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio Encoder"
Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Encoder Settings (if any)"
Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Settings (if any)"
Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframe interval (frames)"
Basic.Settings.Output.Adv.FFmpeg.GOPType="GOP Type"
Basic.Settings.Output.Adv.FFmpeg.GOPClosed="Closed GOP"
Basic.Settings.Output.Adv.FFmpeg.BFrames="B-Frames"
Basic.Settings.Output.Adv.FFmpeg.ReferenceFrames="Reference frames"
Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Show all codecs (even if potentially incompatible)"

# Screenshot
Expand Down
Loading