diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5ade419 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# OBS Adapter for WebNowPlaying-Redux +A OBS script to display information from [WebNowPlaying-Redux](https://github.com/keifufu/WebNowPlaying-Redux). + +This scripts adds sources for: +- Player +- Title +- Artist +- Album +- Duration +- Position +- Cover Art +- A custom format like "{Artist} - {Title} ({Position}/{Duration})" + +You can modify these sources however you want, the script will only update the text. +If you delete a source, it will stay deleted until you click "Create Sources" again. + +# Installing +- Install Python 3.10 ([download link](https://www.python.org/downloads/release/python-31010/)), make sure to check 'Add python.exe to PATH' +- Open cmd and run `pip install pywnp` +- In OBS, go to Tools -> Scripts -> Python Settings, and add your Python path. + On windows, run `where python` to see where it installed. +- Download wnp-obs.py from [Releases](https://github.com/keifufu/WebNowPlaying-Redux-OBS/releases/latest), then add it in the Scripts tab. +- Click "Create Sources" in the Scripts window. + +# Updating +- Replace wnp-obs.py with the latest wnp-obs.py from [Releases](https://github.com/keifufu/WebNowPlaying-Redux-OBS/releases/latest) +- Open cmd and run `pip install --upgrade pywnp` \ No newline at end of file diff --git a/wnp-obs.py b/wnp-obs.py new file mode 100644 index 0000000..2ecafc1 --- /dev/null +++ b/wnp-obs.py @@ -0,0 +1,117 @@ +from pywnp import WNPRedux +import obspython as obs + +Player = 'N/A' +Title = 'N/A' +Artist = 'N/A' +Album = 'N/A' +Duration = '0:00' +Position = '0:00' +CoverUrl = 'https://keifufu.dev/wnpredux/nocover.png' + +format = '{title} - {artist} ({position}/{duration})' + +def script_description(): + description = 'Web Now Playing for OBS' + description += 'Display current song as a text on your screen.' + description += 'Available placeholders:' + description += '{player}, {title}, {artist}, {album}, {duration}, {position}' + return description + +def script_defaults(settings): + obs.obs_data_set_default_string(settings, 'format', format) + +def script_properties(): + props = obs.obs_properties_create() + obs.obs_properties_add_text(props, 'format', 'Format', obs.OBS_TEXT_DEFAULT) + obs.obs_properties_add_button(props, 'cs', 'Create Sources', create_sources) + return props + +def script_update(settings): + global format + format = obs.obs_data_get_string(settings, 'format') + +def script_load(settings): + def logger(type, message): + print(f'WNP - {type}: {message}') + WNPRedux.Initialize(6534, '1.0.0', logger) + obs.timer_add(update, 250) + +def script_unload(): + WNPRedux.Close() + obs.timer_remove(update) + +def update(): + if WNPRedux.isInitialized: + global Player, Title, Artist, Album, Duration, Position, CoverUrl + Player = WNPRedux.mediaInfo.Player or 'N/A' + Title = WNPRedux.mediaInfo.Title or 'N/A' + Artist = WNPRedux.mediaInfo.Artist or 'N/A' + Album = WNPRedux.mediaInfo.Album or 'N/A' + Duration = WNPRedux.mediaInfo.Duration + Position = WNPRedux.mediaInfo.Position + CoverUrl = WNPRedux.mediaInfo.CoverUrl or 'https://keifufu.dev/wnpredux/nocover.png' + update_source('Player', 'text', Player) + update_source('Title', 'text', Title) + update_source('Artist', 'text', Artist) + update_source('Album', 'text', Album) + update_source('Duration', 'text', Duration) + update_source('Position', 'text', Position) + update_source('Cover', 'url', CoverUrl) + try: + update_source('Formatted', 'text', format.format(player=Player, title=Title, artist=Artist, album=Album, duration=Duration, position=Position)) + except: + pass + +def create_sources(props, prop): + create_text_source('WNP-Player', 'N/A') + create_text_source('WNP-Title', 'N/A') + create_text_source('WNP-Artist', 'N/A') + create_text_source('WNP-Album', 'N/A') + create_text_source('WNP-Duration', '0:00') + create_text_source('WNP-Position', '0:00') + create_browser_source('WNP-Cover', 'https://keifufu.dev/wnpredux/nocover.png') + try: + create_text_source('WNP-Formatted', format.format(player=Player, title=Title, artist=Artist, album=Album, duration=Duration, position=Position)) + except: + pass + +def update_source(type, key, value): + source = obs.obs_get_source_by_name(f'WNP-{type}') + if source is not None: + settings = obs.obs_data_create() + obs.obs_data_set_string(settings, key, value) + obs.obs_source_update(source, settings) + obs.obs_data_release(settings) + obs.obs_source_release(source) + +def create_text_source(name, placeholder): + source = obs.obs_get_source_by_name(name) + if source is None: + current_scene = obs.obs_frontend_get_current_scene() + scene = obs.obs_scene_from_source(current_scene) + settings = obs.obs_data_create() + obs.obs_data_set_string(settings, 'text', placeholder) + source = obs.obs_source_create('text_gdiplus', name, settings, None) + obs.obs_scene_add(scene, source) + obs.obs_scene_release(scene) + obs.obs_data_release(settings) + obs.obs_source_release(source) + return source + +def create_browser_source(name, url): + source = obs.obs_get_source_by_name(name) + if source is None: + current_scene = obs.obs_frontend_get_current_scene() + scene = obs.obs_scene_from_source(current_scene) + settings = obs.obs_data_create() + obs.obs_data_set_string(settings, 'url', url) + obs.obs_data_set_int(settings, 'width', 300) + obs.obs_data_set_int(settings, 'height', 300) + obs.obs_data_set_string(settings, 'css', 'img { width: auto; height: 100%; aspect-ratio: 1; object-fit:cover; }') + source = obs.obs_source_create('browser_source', name, settings, None) + obs.obs_scene_add(scene, source) + obs.obs_scene_release(scene) + obs.obs_data_release(settings) + obs.obs_source_release(source) + return source \ No newline at end of file