Skip to content

Commit

Permalink
frontend-tools: Add scene switcher plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jp9000 committed Sep 7, 2016
1 parent 988bbc6 commit 39592ff
Show file tree
Hide file tree
Showing 10 changed files with 1,137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions UI/CMakeLists.txt
Expand Up @@ -239,3 +239,5 @@ if (UNIX AND UNIX_STRUCTURE AND NOT APPLE)
install(FILES forms/images/obs.png
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/256x256/apps)
endif()

add_subdirectory(frontend-plugins)
3 changes: 3 additions & 0 deletions UI/frontend-plugins/CMakeLists.txt
@@ -0,0 +1,3 @@
if(WIN32 OR APPLE)
add_subdirectory(frontend-tools)
endif()
46 changes: 46 additions & 0 deletions UI/frontend-plugins/frontend-tools/CMakeLists.txt
@@ -0,0 +1,46 @@
project(frontend-tools)

if(APPLE)
find_library(COCOA Cocoa)
include_directories(${COCOA})
endif()

set(frontend-tools_HEADERS
auto-scene-switcher.hpp
)
set(frontend-tools_SOURCES
frontend-tools.c
auto-scene-switcher.cpp
)
set(frontend-tools_UI
forms/auto-scene-switcher.ui
)

if(WIN32)
set(frontend-tools_PLATFORM_SOURCES
auto-scene-switcher-win.cpp)
elseif(APPLE)
set(frontend-tools_PLATFORM_SOURCES
auto-scene-switcher-osx.mm)
set_source_files_properties(auto-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc")

set(frontend-tools_PLATFORM_LIBS
${COCOA})
endif()

qt5_wrap_ui(frontend-tools_UI_HEADERS ${frontend-tools_UI})

add_library(frontend-tools MODULE
${frontend-tools_HEADERS}
${frontend-tools_SOURCES}
${frontend-tools_PLATFORM_SOURCES}
${frontend-tools_UI_HEADERS}
)
target_link_libraries(frontend-tools
${frontend-tools_PLATFORM_LIBS}
obs-frontend-api
Qt5::Widgets
libobs)

install_obs_plugin_with_data(frontend-tools data)
43 changes: 43 additions & 0 deletions UI/frontend-plugins/frontend-tools/auto-scene-switcher-osx.mm
@@ -0,0 +1,43 @@
#import <AppKit/AppKit.h>
#include <util/platform.h>
#include "auto-scene-switcher.hpp"

using namespace std;

void GetWindowList(vector<string> &windows)
{
windows.resize(0);

@autoreleasepool {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSArray *array = [ws runningApplications];
for (NSRunningApplication *app in array) {
NSString *name = app.localizedName;
if (!name)
continue;

const char *str = name.UTF8String;
if (str && *str)
windows.emplace_back(str);
}
}
}

void GetCurrentWindowTitle(string &title)
{
title.resize(0);

@autoreleasepool {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSRunningApplication *app = [ws frontmostApplication];
if (app) {
NSString *name = app.localizedName;
if (!name)
return;

const char *str = name.UTF8String;
if (str && *str)
title = str;
}
}
}
69 changes: 69 additions & 0 deletions UI/frontend-plugins/frontend-tools/auto-scene-switcher-win.cpp
@@ -0,0 +1,69 @@
#include <windows.h>
#include <util/platform.h>
#include "auto-scene-switcher.hpp"

using namespace std;

static bool GetWindowTitle(HWND window, string &title)
{
size_t len = (size_t)GetWindowTextLengthW(window);
wstring wtitle;

wtitle.resize(len);
if (!GetWindowTextW(window, &wtitle[0], (int)len + 1))
return false;

len = os_wcs_to_utf8(wtitle.c_str(), 0, nullptr, 0);
title.resize(len);
os_wcs_to_utf8(wtitle.c_str(), 0, &title[0], len + 1);
return true;
}

static bool WindowValid(HWND window)
{
LONG_PTR styles, ex_styles;
RECT rect;
DWORD id;

if (!IsWindowVisible(window))
return false;
GetWindowThreadProcessId(window, &id);
if (id == GetCurrentProcessId())
return false;

GetClientRect(window, &rect);
styles = GetWindowLongPtr(window, GWL_STYLE);
ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE);

if (ex_styles & WS_EX_TOOLWINDOW)
return false;
if (styles & WS_CHILD)
return false;

return true;
}

void GetWindowList(vector<string> &windows)
{
HWND window = GetWindow(GetDesktopWindow(), GW_CHILD);

while (window) {
string title;
if (WindowValid(window) && GetWindowTitle(window, title))
windows.emplace_back(title);
window = GetNextWindow(window, GW_HWNDNEXT);
}
}

void GetCurrentWindowTitle(string &title)
{
HWND window = GetForegroundWindow();
DWORD id;

GetWindowThreadProcessId(window, &id);
if (id == GetCurrentProcessId()) {
title = "";
return;
}
GetWindowTitle(window, title);
}

11 comments on commit 39592ff

@SuslikV
Copy link
Contributor

@SuslikV SuslikV commented on 39592ff Sep 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope, this is for API test only. Otherwise it's waste of time, imho. Absolutely Unnecessary Thing in OBS Studio.

@OsirisNL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

@Gol-D-Ace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not. Especially helpful for all the multi executable games like for example League of Legends. Also this feature is in OBS Classic.

@SuslikV
Copy link
Contributor

@SuslikV SuslikV commented on 39592ff Sep 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of Classic. And scene setup becomes complex. What benefits of the Studio, if under development only old features? Studio Mode can beat any autoswitching - maybe its implementation not clear to end users or nobody wants to use Studio because of hard to use this mode, that's why people asking for autoswitching? Not complaining, but I feel that something wrong with the Studio itself. Maybe I'm wrong.

@dodgepong
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm wrong.

You are indeed wrong.

If you can't understand the importance of feature parity with the legacy version to help people make the switch, I don't know what to tell you.

Studio Mode in no way supplants the idea of auto-switching -- users want the ability to be able to switch their scenes depending on the context of what they are currently doing without having to even bother looking at or messing with OBS so they can focus on what they are doing instead of fiddling with the stream.

@SuslikV
Copy link
Contributor

@SuslikV SuslikV commented on 39592ff Sep 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we had a lamp to know what camera is online now... Highlight the window with red rectangle via overlay. That overlay would not captured by OBS Studio itself. Possible improvement?

@dodgepong
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to give you the benefit of the doubt and assume that you genuinely don't understand what the scene switcher is for, because your comments are not making any sense whatsoever.

The auto-scene switcher is a tool that streamers can use to define conditions under which certain scenes should be displayed. For example, let's say you're playing League of Legends. LoL has a "launcher" window that is separate from the actual game window, so you might have a scene that shows things while you are in the launcher, and a scene that has things arranged while you are in-game. You might go back and forth between these scenes several times over the course of a stream, and it's annoying to have to remember to switch manually.

The auto-scene switcher can detect what the currently active window is, and you can set it up so that if you're using the launcher, it will display the Launcher scene, and if you're in game, it will display the In-game scene. It can do this without any input from the streamer, leaving them to worry about playing the game and entertaining the audience rather than fiddling with stream production. It's an ease-of-use tool that many streamers find very helpful for producing their streams.

It's not a replacement for the existing scene-switching capabilities, nor does it hide control/information from users in any way. Everything still appears as it always did, but now you have the option to say "If X window is selected, show scene Y". That's it.

@c3r1c3
Copy link
Contributor

@c3r1c3 c3r1c3 commented on 39592ff Sep 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bring on the feature/plugin parity.

@SuslikV
Copy link
Contributor

@SuslikV SuslikV commented on 39592ff Sep 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's annoying to have to remember to switch ...

because you don't know what is online until you have a look at OBS Studio preview window.

News presenter on TV always know - what camera is active right now.

About plugin itself, it has start and stop features, I don't mind, let it exist.

@c3r1c3
Copy link
Contributor

@c3r1c3 c3r1c3 commented on 39592ff Sep 17, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SuslikV, you do realize that if you have a 2nd monitor, and put OBS on said 2nd monitor, you can see your switches/tallies?

If you don't have 2+ monitors while streaming, that's like using consumer cameras without tally on a news set. Not OBS' fault if your setup isn't adequate to properly utilize the Scene Switcher plugin/option.

@SuslikV
Copy link
Contributor

@SuslikV SuslikV commented on 39592ff Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not the same (2nd monitor). I still think that OBS overlay (not recorded and recorded) is a good option. With it enabled you can see what is active right now (how it doing, and so on) and not turn your head to the second monitor to just check the things.

For example, you are selecting the window and you still don't know is the scene auto-switched or not (you need to look at the second monitor at OBS preview). Red outline of the window can can point you to the place what area is captured right now (you may use your own marks, it is just example). It is like camera's preview: you see how many photos you can make, where it points to, where it focused, what options is, but none of this is recorded into the photo.

Plugin is optional, so I don't mind.

Please sign in to comment.