This was created to enable marquee (with pause) effect in OBS and to share the rendering work with OBS.
-
Have a marquee effect that OBS does not have.
-
Sharing the rendering work with OBS to reduce rendering lag.
-
Low system resource usage while highly customizable.
-
Developed under Python 3.8.
-
Running from multiple sources may result in some contents being skipped.
-
Add Custom CSS in
Browser Source
with selectorbody
to configure some global style, for example,font-size
.
-
Run
py -m flask run
.- Be sure to install
flask
in your Python environment.
- Be sure to install
-
Create a
Browser Source
in OBS with the URL which flask is running on. Default tohttp://127.0.0.1/5000
.-
The height is defaulted to
100vh
. The height of the window. -
All things above are customizable by modifying
templates/main.html
.
-
For more functions, check the endpoints section.
The monospaced
texts alongside with the section title is the corresponding config file section name.
There are 3 components of the marquee:
-
[FILE]
Foobar2K Now Playing -
[FILE]
Static Text -
[API]
Youtube Data API (v3)- Currently only support "current viewers"
To "install" or "uninstall" the component, go to
content.py
and change the variableinput_fns
.
FILE
Components
-
There's a
Path
field inconfig.ini
to specify the file path for the corresponding component. -
The first line of the file needs to be
1
, or the rest of the file will not be read.
-
Setup
-
Install
foo_np_simple
. -
Setup the output using
$crlf()
to separate lines(outputs) in FB2K.- Remember that the first line will indicate if the file will be read. Anything besides
1
will skip the read.
- Remember that the first line will indicate if the file will be read. Anything besides
-
Copy the file output path, and paste it under
Foobar2K/Path
inconfig.ini
.
-
-
Setup
-
Create a text file somewhere.
-
Insert the text you want to display. Use newline to separate them.
- Remember that the first line will indicate if the file will be read. Anything besides
1
will skip the read.
- Remember that the first line will indicate if the file will be read. Anything besides
-
Remember the file path, and set it under
StaticText/Path
inconfig.ini
.
-
-
Note
-
An empty line with a white space will be considered as the content separator in the static texts.
- Output flow:
FB2K -> Static Text -> Youtube -> FB2K -> ...
- Output flow:
-
An empty line without a white space will make the static texts being outputted separately.
- Output flow:
FB2K -> Static Text (Section 1) -> Youtube -> FB2K -> Static Text (Section 2) -> Youtube -> FB2K -> Static Text (Section 1)...
- Output flow:
-
Lines beginning with
//
will be skipped.
-
-
Setup
-
Environment variable
YT_VIDEO_ID
: The video ID to track the current viewers -
Environment variable
YT_API_KEY
: The API key acquired using Google Cloud Console
-
-
Note
- Output will be skipped if the current viewer is 0 or inaccessible.
There are some configurable settings in config.ini
:
-
Timezone
: list of timezones to be displayed. Separated by comma,
.-
Must be the
pytz
timezone identifiers. -
List of the available identifiers can be found here
-
Some common identifiers:
Asia/Taipei
US/Pacific
US/Mountain
US/Central
US/Eastern
-
-
ToNext
: Count of the calls to change to the timezone.
There are some configurable settings in config.ini
:
-
DisplaySec
: Time length in second(s) from time up to display the timer and remove the end message ifup
is1
andend_msg
is given. -
SpecialSec
: If the current timer is countdown, and the time left is less than or equal to this number in seconds, SE will be played, and some special effects will be applied for timer.
Marquee with styles applied.
/ Stylable CSS selector | Description |
---|---|
div#content |
Content of the marquee |
Current timestamp expression with styles applied.
Automatically update once a second.
This can be changed by modifying the js in the corresponding template
.
The timezone for the current time will constantly switching between the configured timezone. Check this section for configuring the corresponding settings.
/ Stylable CSS selector | Description |
---|---|
span#date |
Date expression |
span#time |
Time expression |
span#tz |
Timezone expression |
Current timer status with styles applied.
Automatically update once a second.
This can be changed by modifying the js in the corresponding template
.
Parameter | Description | Type | Valid Values |
---|---|---|---|
dt |
Target datetime of the timer. | Required | Any expression that could be understood by python-dateutil 's parser. |
up |
If the timer should count up. | Optional | 0 or 1 |
end_msg |
End message of the timer. | Optional | Any string |
Stylable CSS selector | Description |
---|---|
div.count-up |
Timer which is counting up (now > dt) |
div.count-down |
Timer which is counting down (dt > now) |
div.message |
Timer which is expired, displaying end message |
Similar to /timer. The only difference is that /timer uses a timestamp as the changing point, while this receives a time offset. The time offset will be counted down first, then do the same behavior as /timer.
The chrono will restart if the Browser Source
is refreshed.
To start counting up at the beginning, set the time with a negative value.
For example, to start counting up from 34 mins, set the parameter as ...?m=-34
.
Parameter | Description | Type | Valid Values |
---|---|---|---|
d |
Days of the time offset. | Optional | Any numeric value |
h |
Hours of the time offset. | Optional | Any numeric value |
m |
Minutes of the time offset. | Optional | Any numeric value |
s |
Seconds of the time offset. | Optional | Any numeric value |
up |
If the timer should count up. | Optional | 0 or 1 |
end_msg |
End message of the timer. | Optional | Any string |
Stylable CSS selector | Description |
---|---|
div.count-up |
Timer which is counting up (now > dt) |
div.count-down |
Timer which is counting down (dt > now) |
div.message |
Timer which is expired, displaying end message |
Display the given text.
Parameter | Description | Type | Valid Values |
---|---|---|---|
txt |
Text to be displayed | Optional | Any string |
Stylable CSS selector | Description |
---|---|
div.content |
Content of the text |
Pure text of the next content of the marquee.
Pure text of the current time.
Current timer status with styles applied.
Parameter | Description | Type | Valid Values |
---|---|---|---|
dt |
Target datetime of the timer. | Required | Any expression that could be understood by python-dateutil 's parser. |
up |
If the timer should count up. | Optional | 0 or 1 |
end_msg |
End message of the timer. | Optional | Any string |