Coder Social home page Coder Social logo

occ-ai / obs-urlsource Goto Github PK

View Code? Open in Web Editor NEW
143.0 4.0 18.0 457 KB

OBS plugin to fetch data from a URL or file, connect to an API or AI service, parse responses and display text, image or audio on scene

Home Page: https://obsproject.com/forum/resources/url-api-source-fetch-live-data-and-display-it-on-screen.1756/

License: GNU General Public License v2.0

CMake 31.49% Shell 3.20% C 2.53% C++ 62.78%
obs plugin api http url live-streaming livestream obs-plugin obs-studio obs-studio-plugin real-time-data

obs-urlsource's Introduction

URL/API Source - Connect Anything to OBS

GitHub GitHub Workflow Status Total downloads GitHub release (latest by date) Discord

Introduction

The URL/API Source is a plugin for OBS Studio that allows fetcing data from a URL, API endpoint or file and displays it as text, image or even audio. OBS Forums page | Blog post

If this free plugin has been valuable to you consider adding a ⭐ to this GH repo, rating it on OBS, subscribing to my YouTube channel where I post updates, and supporting my work on GitHub, Patreon or OpenCollective

Usage Tutorials

Watch quick tutorials on how to use and setup the URL/API source on your OBS scene.

Additional things to do with URL/API source to upgrade your content:

Inspiration

Out of ideas on what to do with URL/API Source? Here's a repo with 1,000s of public APIs https://github.com/public-apis/public-apis

Dynamic Templating

The URL source supports both input and output templating using the Inja engine.

Output templates include {{output}} in case of a singular extraction from the response or {{output1}},{{output2}},... in case of multiple extracted value. In addition the {{body}} variable contains the entire body of the response in case of JSON. Advanced output templating functions can be achieved through Inja like looping over arrays, etc.

The input template works for the URL (querystring or REST path) or the POST body

Use the {{input}} variable to insert the output from a Text source. Inja advanced templates are available too. A special function strftime is available for formatting the current time using conventions from C++ STL (strftime), as well as urlencode which is useful for dynamic input in the querystring.

HTML Subset

The internal template renderer supports HTML4 and CSS with a reduced subset of feautures. It is quite powerful and can render tables and apply various styling to the text.

Image render is supported with the <img /> tag, and external URLs are supported as well. For example <img src="{{output}}" /> could be used to dynamically render an image URL coming from the response.

Code Walkthrough

Watch an explanation of the major parts of the code and how they work together.

Features:

  • HTTP request types: GET, POST
  • Request headers (for e.g. API Key or Auth token)
  • Request body for POST
  • Multiple dynamic inputs from several Text or Image sources (base64)
  • Output parsing: JSON (JSONPointer & JSONPath), XML/HTML (XPath & XQuery), Key-Value, Regex and CSS selectors
  • Update timer for live updating data
  • Test of the request to find the right parsing
  • Output styling (font, color, etc.) and formatting (via regex post processing)
  • Output Image (via image URL or image data on the response)
  • Output text to external Text Source and audio to external Media Source
  • Output to multiple sources with one request (Output Mapping)
  • Multi-value (array, union) parsed output capture, object unpacking (via Inja)
  • Dynamic input aggregations (time-based, "empty"-based)

Coming soon:

  • Authentication (Basic, Digest, OAuth)
  • Websocket support
  • More parsing options (CSV, etc.)
  • More request types (HTTP PUT / DELETE / PATCH, and GraphQL)
  • More output formats (Markdown, slim, reStructured, HAML, etc.)

Check out our other plugins:

  • Background Removal removes background from webcam without a green screen.
  • Detect will find and track >80 types of objects in any source that provides an image in real-time
  • LocalVocal speech AI assistant plugin for real-time, local transcription (captions), translation and more language functions
  • Polyglot translation AI plugin for real-time, local translation to hunderds of languages
  • 🚧 Experimental 🚧 CleanStream for real-time filler word (uh,um) and profanity removal from live audio stream

If you like this work, which is given to you completely free of charge, please consider supporting it on GitHub: https://github.com/sponsors/royshil

Download

Check out the latest releases for downloads and install instructions.

Building

The plugin was built and tested on Mac OSX (Intel & Apple silicon), Windows and Linux.

Start by cloning this repo to a directory of your choice.

Mac OSX

Using the CI pipeline scripts, locally you would just call the zsh script. By default this builds a universal binary for both Intel and Apple Silicon. To build for a specific architecture please see .github/scripts/.build.zsh for the -arch options.

$ ./.github/scripts/build-macos -c Release

Install

The above script should succeed and the plugin files (e.g. obs-urlsource.plugin) will reside in the ./release/Release folder off of the root. Copy the .plugin file to the OBS directory e.g. ~/Library/Application Support/obs-studio/plugins.

To get .pkg installer file, run for example

$ ./.github/scripts/package-macos -c Release

(Note that maybe the outputs will be in the Release folder and not the install folder like pakage-macos expects, so you will need to rename the folder from build_x86_64/Release to build_x86_64/install)

Linux (Ubuntu)

Use the CI scripts again

$ ./.github/scripts/build-linux.sh

Copy the results to the standard OBS folders on Ubuntu

$ sudo cp -R release/RelWithDebInfo/lib/* /usr/lib/x86_64-linux-gnu/
$ sudo cp -R release/RelWithDebInfo/share/* /usr/share/

Note: The official OBS plugins guide recommends adding plugins to the ~/.config/obs-studio/plugins folder.

Windows

Use the CI scripts again, for example:

> .github/scripts/Build-Windows.ps1 -Target x64 -CMakeGenerator "Visual Studio 17 2022"

The build should exist in the ./release folder off the root. You can manually install the files in the OBS directory.

obs-urlsource's People

Contributors

destroy666x avatar flexiondotorg avatar royshil avatar tinkoliu avatar umireon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

obs-urlsource's Issues

Need a way to pass dynamic values in the URL

I'm making an API call to Oura Rings v2 API. It expects a start and end datetime as follows:

https://api.ouraring.com/v2/usercollection/heartrate?start_datetime=2023-10-13T12%3A56%3A00-10%3A00&end_datetime=2023-10-15T15%3A11%3A00-10%3A00&next_token=

This project is so close to doing exactly what I want. But having to update these querystring values manually is a non-starter for me. Do you support any way for me to specify variables that I can dynamically set in the URL?

For example, having something like {{now}} and then being able to do things like {{now-1}} would be pretty sweet.

Feature request: More dynamic input options to data source

Love the plugin! Thank you!

I have a use case where I use the plugin to scrape data from a bowling alley score website. Would it be possible to get more GDI Texts as dynamic inputs added to the source?

I'm not sure if this is a bug. I'm trying to use dynamic text input in the "RegEx" field, but OBS crashes. That would be very helpful to have. Also adding a dynamic input to the source URL would be very helpful for scraping purposes.

Regex also only returns the first match even when there are more. I'm not sure if this my fault, but setting RegEx flag "g" does not help.

I have hard time understanding the different Regex options as they are not behaving as I would expect them to. If you could direct me to where I could read more, I would appreciate that.

Aggregate to empty is requested, skipping

Hi,

When I leave the "Agg to empty" option unchecked, api requests occur, but each time there are three requests, with the first and last requests being empty.

However, when I select the "Agg to empty option", "Test Request" fails with "Aggregate to empty is requested, skipping", and nothing further happens.

I'm attempting to use urlsource along with LMStudio and closed captions (https://github.com/ratwithacompiler/OBS-captions-plugin).

This is on Windows 11.

'utf-8' codec can't decode

image
image
image

Body :
{
"model": "gpt-3.5-turbo-instruct",
"prompt": "translate this Korean text to English: {{input}}",
"max_tokens": 7,
"temperature": 0
}

If I delete $[*].fact I get this error.

image

Mac Install

OBS log gives this error - Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))

Please add item separator setting when there are multiple parts (or an array)

Separator setting would be really handy to quickly style output for e.g. news tickers and similar things.

Currently you can, as far as I know:

  • use {output0} | {output1} | {output...} kind of output if there are multiple, but that's not too efficient and readable to set up if there are let's say 50 or 100 parts
  • not really do anything when it's an array directly, unless the structure of the output is clearly and uniquely distinguishable in terms of a regex. But then you need access to the output and you could set it to what I mentioned above anyways.

Array parsing in JSON

I have Json:
{ "info": { "id": 3569, "game": "basketball", "title": "УЛМ vs ТИМ", "round_number": 2, "matchround_id": 2222, "tournament_id": 192 }, "teams": [ { "id": 238, "sort": 1, "info": { "title": "УЛМ", "title_en": "УЛМ", "color": null, "disqualification": false }, "statistic": { "currentRound": { "id": 2, "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "penalty_goal": 0, "timeout": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0 }, "match": { "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "match_win": 0, "penalty_goal": 0, "timeout": 0, "match_lose": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0, "id": 3569, "rounds": [ { "id": 1, "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "penalty_goal": 0, "timeout": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0 } ], "goal": 0 }, "matchround": { "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "match_win": 0, "penalty_goal": 0, "timeout": 0, "match_lose": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0, "total_shot": 0, "id": 2222, "goal": 0 }, "tournament": { "goal": 0 } }, "athletes": [ { "id": 873, "sort": 1, "info": { "name": "Данилюк В.А.", "name_en": "Данилюк В.", "nickname": null, "slot": null, "disqualification": false, "number": 1, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 871, "sort": 2, "info": { "name": "Зайнов Е.В.", "name_en": "Зайнов Е.", "nickname": null, "slot": null, "disqualification": false, "number": 4, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 871, "sort": 3, "info": { "name": "Зайнов Е.В.", "name_en": "Зайнов Е.", "nickname": null, "slot": null, "disqualification": false, "number": 3, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 875, "sort": 4, "info": { "name": "Новоселов Н.А.", "name_en": "Новоселов Н.", "nickname": null, "slot": null, "disqualification": false, "number": 2, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } } ] }, { "id": 236, "sort": 2, "info": { "title": "ТИМ", "title_en": "ТИМ", "color": null, "disqualification": false }, "statistic": { "currentRound": { "id": 2, "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "penalty_goal": 0, "timeout": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0 }, "match": { "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "match_win": 0, "penalty_goal": 0, "timeout": 0, "match_lose": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0, "id": 3569, "rounds": [ { "id": 1, "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "penalty_goal": 0, "timeout": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0 } ], "goal": 0 }, "matchround": { "team_foal": 0, "1_point_goal": 0, "2_point_goal": 0, "team_rebound": 0, "match_win": 0, "penalty_goal": 0, "timeout": 0, "match_lose": 0, "1_point_shot": 0, "miss_-1": 0, "challenge": 0, "miss_-2": 0, "penalty_miss": 0, "2_point_shot": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "point": 0, "media_timeout": 0, "total_shot": 0, "id": 2222, "goal": 0 }, "tournament": { "goal": 0 } }, "athletes": [ { "id": 873, "sort": 1, "info": { "name": "Данилюк В.А.", "name_en": "Данилюк В.", "nickname": null, "slot": null, "disqualification": false, "number": 8, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 872, "sort": 2, "info": { "name": "Иванов Д.О.", "name_en": "Иванов Д.", "nickname": null, "slot": null, "disqualification": false, "number": 7, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 871, "sort": 3, "info": { "name": "Зайнов Е.В.", "name_en": "Зайнов Е.", "nickname": null, "slot": null, "disqualification": false, "number": 6, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } }, { "id": 875, "sort": 4, "info": { "name": "Новоселов Н.А.", "name_en": "Новоселов Н.", "nickname": null, "slot": null, "disqualification": false, "number": 5, "position": null, "reserve": false }, "statistic": { "currentRound": { "id": 2, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 }, "match": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 3569, "rounds": [ { "id": 1, "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0 } ] }, "matchround": { "1_point_goal": 0, "2_point_goal": 0, "penalty_goal": 0, "miss_-1": 0, "1_point_shot": 0, "miss_-2": 0, "2_point_shot": 0, "penalty_miss": 0, "turnover": 0, "block": 0, "rebound": 0, "pass": 0, "foal": 0, "dsql_foal": 0, "id": 2222 } } } ] } ] }

and then i did that i have error:
Monosnap HTTP Request Builder 2023-08-28 11-28-54

{{Input}} = Invalid URL?

I am trying to create dynamic images in OBS controled by a Google Sheet using urlsource. I have Google Sheets choose from a list of Imgur image urls which I want to use as a dynamic input for an image URL Source.

I have a Google Sheet that outputs a string to a URL Source succesfully. The string is then output to a Text (GDI+) succesfully. Here is that pictured:

urlsource_issue_part1

The string itself is a url to an Imgur file I want to use as a dynamic input for a different URL Source. I can use it as a url directly like this:

urlsource_issue_part2

But, when I try and use the Text (GDI+) as a dynamic input, it doesn't work. Testing the request just returns with "URL is Invalid":

urlsource_issue_part3

I've uninstalled urlsource and reinstalled it already, so I am on version 0.2.7 now. I was able to get this working yesterday, but for some reason can't seem to figure out the issue. Maybe I just don't understand Inja or something.

Output to multiple sources

I would like to pull one API request, and output different values to different text, image, and other sources.
Alternatively, an option to cache results if the data source is the same for multiple urlsource entries, so I don't make multiple API calls.

Save current output into a setting/property

This request comes from this use case - I'm trying to update Advanced Scene Switcher variable based on setting change, then I'd like to modify its variable based on new response. As of now I need to redirect it to some hidden text source and check if that source's text setting changes. Which adds unnecessary clutter/overhead per each request.

Would be nice if this followed OBS sources and stored current output value as a hidden setting/property so that could be checked directly instead, e.g. as Text or Output. Not the biggest deal ofc, but could be done some day when you're bored.

incompatible architecture (have 'x86_64', need 'arm64'))

hi, i'm using a m1 mac and did install the "universal" installer of 0.0.5:

error: os_dlopen(/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource->/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource): dlopen(/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource, 0x0101): tried: '/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource' (no such file), '/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))

warning: Module '/Users/tom/Library/Application Support/obs-studio/plugins/obs-urlsource.plugin/Contents/MacOS/obs-urlsource' not loaded

inja templating {{input}} not working

local inference server running in LMStudio
URLsource with http POST &

  1. request body without templating
    { "messages": [{ "role": "user", "content": "hello"}]} --> works & returns expected response body
  2. request body with improper templating like
    { "messages": [{ "role": "user", "content": "hello {input}"}]} --> works & returns response body with garbage content (as expected), which means there was no text replacement to begin with
  3. request body with proper templating
    { "messages": [{ "role": "user", "content": "hello {{input}}"}]} --> {"error":"'messages' field is required"}
    which means the templating escaped and destroyed the json structure without leaving a json syntax error

Environments (same error in both environments):
a) Apple Silicon, Sonoma, fresh OBS , LMStudio, URLsource
b) Win11 x64, fresh OBS, LMStudio, URLsource

Obs segfault

Hi and thank you for this initiative !

On Debian 12 with OBS 29.1.3, when I select URL Source to add a new source, OBS crash instantly, heres a backtrace:

info: User switched to scene 'Scène 4'
[New Thread 0x7fff067026c0 (LWP 163118)]
[New Thread 0x7fff05f016c0 (LWP 163119)]
[New Thread 0x7fff04f676c0 (LWP 163120)]

Thread 1 "obs" received signal SIGSEGV, Segmentation fault.
__memcpy_ssse3 () at ../sysdeps/x86_64/multiarch/memmove-ssse3.S:104
104	../sysdeps/x86_64/multiarch/memmove-ssse3.S: Aucun fichier ou dossier de ce type.
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) 
(gdb) bt
#0  __memcpy_ssse3 () at ../sysdeps/x86_64/multiarch/memmove-ssse3.S:104
#1  0x00007fff68cf1ca9 in  () at /home/organ/.config/obs-studio/plugins/obs-urlsource/bin/64bit/obs-urlsource.so
#2  0x00007fff68cf273b in  () at /home/organ/.config/obs-studio/plugins/obs-urlsource/bin/64bit/obs-urlsource.so
#3  0x00007ffff6787cb2 in  () at /usr/local/lib/libobs.so.0
#4  0x00007ffff6788149 in obs_source_create () at /usr/local/lib/libobs.so.0
#5  0x0000555555784b82 in  ()
#6  0x0000555555785711 in  ()
#7  0x00005555555f0de3 in  ()
#8  0x00007ffff456cc18 in  () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#9  0x00007ffff573a862 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#10 0x00007ffff456cee3 in  () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#11 0x00007ffff56826f2 in QAbstractButton::clicked(bool) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#12 0x00007ffff567a7fa in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#13 0x00007ffff567abba in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#14 0x00007ffff568766f in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#15 0x00007ffff55c8554 in QWidget::event(QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#16 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#17 0x00007ffff557b931 in QApplication::notify(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#18 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#19 0x00007ffff55783e8 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) ()
    at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#20 0x00007ffff55d5f95 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#21 0x00007ffff55d72f5 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#22 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#23 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#24 0x00007ffff4b8e28b in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#25 0x00007ffff4bd653c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#26 0x00007fffe97b52fa in  () at /lib/x86_64-linux-gnu/libQt6XcbQpa.so.6
#27 0x00007ffff251c7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#28 0x00007ffff251ca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#29 0x00007ffff251cacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#30 0x00007ffff4707f7c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#31 0x00007ffff452d57a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#32 0x00007ffff57a08ff in QDialog::exec() () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#33 0x0000555555695df3 in  ()
#34 0x00005555556a5fb6 in  ()
#35 0x00007ffff456cee3 in  () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#36 0x00007ffff4e32b22 in QAction::triggered(bool) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#37 0x00007ffff4e37db1 in QAction::activate(QAction::ActionEvent) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#38 0x00007ffff5720b8a in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#39 0x00007ffff572131b in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
--Type <RET> for more, q to quit, c to continue without paging--c
#40 0x00007ffff55c8554 in QWidget::event(QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#41 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#42 0x00007ffff557b931 in QApplication::notify(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#43 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#44 0x00007ffff55783e8 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) ()
    at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#45 0x00007ffff55d658f in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#46 0x00007ffff55d72f5 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#47 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#48 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#49 0x00007ffff4b8e28b in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#50 0x00007ffff4bd653c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#51 0x00007fffe97b52fa in  () at /lib/x86_64-linux-gnu/libQt6XcbQpa.so.6
#52 0x00007ffff251c7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#53 0x00007ffff251ca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#54 0x00007ffff251cacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#55 0x00007ffff4707f7c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#56 0x00007ffff452d57a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#57 0x00007ffff572364f in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#58 0x00007ffff572376f in QMenu::exec(QPoint const&, QAction*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#59 0x00005555556b0083 in  ()
#60 0x00005555556b01df in  ()
#61 0x00005555555f41c7 in  ()
#62 0x00007ffff456cc18 in  () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#63 0x00007ffff4e32b22 in QAction::triggered(bool) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#64 0x00007ffff4e37db1 in QAction::activate(QAction::ActionEvent) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#65 0x00007ffff567ab5d in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#66 0x00007ffff568766f in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#67 0x00007ffff577e8fa in QToolButton::mouseReleaseEvent(QMouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#68 0x00007ffff55c8554 in QWidget::event(QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#69 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#70 0x00007ffff557b931 in QApplication::notify(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#71 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#72 0x00007ffff55783e8 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) ()
    at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#73 0x00007ffff55d5f95 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#74 0x00007ffff55d72f5 in  () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#75 0x00007ffff5582a53 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Widgets.so.6
#76 0x00007ffff45238b8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#77 0x00007ffff4b8e28b in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#78 0x00007ffff4bd653c in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Gui.so.6
#79 0x00007fffe97b52fa in  () at /lib/x86_64-linux-gnu/libQt6XcbQpa.so.6
#80 0x00007ffff251c7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#81 0x00007ffff251ca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#82 0x00007ffff251cacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#83 0x00007ffff4707f7c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#84 0x00007ffff452d57a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#85 0x00007ffff45266a8 in QCoreApplication::exec() () at /lib/x86_64-linux-gnu/libQt6Core.so.6
#86 0x00005555555e7645 in main ()
(gdb) 

Thanks.

"s in JSON value are remaining escaped in output text

At least when sent to text source:
image

This is an example of pure JSON output from the website:

{"id":"60bb3a7b5ca974e38fcf21b5688d868f","text":"The first episode of \"Joanie Loves Chachi\" was the highest rated American program in the history of Korean television, a country where \"Chachi\" translates to \"penis\".  ","source":"djtech.net","source_url":"http://www.djtech.net/humor/useless_facts.htm","language":"en","permalink":"https://uselessfacts.jsph.pl/api/v2/facts/60bb3a7b5ca974e38fcf21b5688d868f"}

"s should be unescaped. You can test with permalink from JSON above.

Output is image option not working with animated gifs

Hello,
is it possible to show animated image in URL/API source.
If I add image layer as a source in my sene I can see gif animating...
but if I use URL/API as a source and then "output is image" I get static gif.
Is there any way that plugin will display animated image.
I am trying to do some weather overlays with animated icons..

thank you,
Sebastian

[FEAT] Regex replace

Is it possible to use regex to do string replace?

I use DecAPI to put live counters in my stream. DecAPI returns text and in most cases always just a number, but the viewercount endpoint returns channelname is offline when the channel is not live as the "number" of live viewers when the channel is streaming.

I'd like to replace "channelname is offline" with "0". Is that possible using URL Source regex?

Not working with multiple updating objects

I have this as dynamic input (So there keep coming new messages) :

[{"name":"Bastiaan","text":"Test","timestamp":1707513736,"media_url":null,"media":null},{"name":"Bastiaan","text":"Jaja","timestamp":1710155677,"media_url":null,"media":null},{"name":"Bastiaan","text":"Nee","timestamp":1710155684,"media_url":null,"media":null}]

Is it possible to make it work with multiple objects like this?

Special characters URL not rendering on "Output is an image URL"

On Windows, when checking Output is an image URL and my file name is containing some special characters, the rendering doesn't work. Tested with Ö in a filename found in /Players/1/Loadout/ImageName.

image

The result as text is as expected, the image exists at this path (tried with both / and \), I even tried to rename and thats when I find out the Ö character was the problem :

image

When checking Output is an image URL, the render doesn't work :

image

Trying to use the LibreTranslate API and tells me that the URL is wrong with dynamic input

I'm trying to use the LibreTranslate API and tells me that the URL is wrong, but only when I use the dynamic input, when I deactivate it, makes the request right

  • URL

On the LibreTranslate API test website also fails

http://127.0.0.1:5000/translate
  • Header
Content-Type: application/json
  • JSON

None

{"q":"This is a test","source":"en","target":"es","format":"text","api_key":""}

Dynamic (has been tested with variable and without variable)

{"q":"{input}","source":"en","target":"es","format":"text","api_key":""}

Dynamic Input

image

None

image

Does not install on Ubuntu 22.04 (XFCE)

Congratulations on the fantastic work. I tested the plugin on Windows and it works perfectly. However, for application I use Ubuntu 22.04 (XFCE) on VPS at Vultr. I've tried several times to install the plugin but I can't. During installation via terminal, error messages do not appear, but the plugin does not appear in Note. Could someone check and help me resolve it? Thanks.

Add a way to use limited (rather than whole) JSON output as unparsed variable in inja

[
  {
    "fact": "something"
  },
  {
    "fact": "else"
  }
]
  • JSON path: $[*].fact

body is for whole JSON output as the result is the same for the JSON path above and also for $ (root), even though results are different. Is there any way to have the JSON Path output as body or another variable? I don't think it's possible but I may have missed something.

I'd like to feed the result of that JSON Path to {{ join(body, " | ") }} as body

Add a way to Add icon images to the Plugin

I really wanna Do something Cool for my Streams when someone Follows Etc, it will Add a Hart image of my choice that is local or URL etc but then it will also Not be too big or too small or even covered by the data being displayed like follower usernames and such.

Styling problems due to invalid HTML?

I think these are no proper HTML tag pairs (div not closed, no beginning text):

<body>
   <div id="text">{text}</text>
 </body>

Had some styling problems - could not find many supported stylings (e.g. text-shadow seems to have no effect). Perhaps that's the reason.

Text is sometimes drawn despite redirecting to text source

Don't kow how to reproduce it consistently, but every now and then the text from URL source is shown despite being redirected to an active and visible text source. Showing and hiding the URL source sometimes fixes it, also selecting None and then again the text source in the dropdown also sometimes fixes it, but it's also inconsistent.

Workaround of hiding the text source doesn't work as then the data isn't polled each XYZ ms.

Settings don't update when set via a WebSocket request

I am using OBS WebSocket to remotely update the 'url' and 'request_data' settings. I notice that when observing the data in OBS, the properties are not updating. I am trying to do this to dynamically update the URL value for a stream. This is an idea I had for getting text-to-speech working with different voices from ElevenLabs but I cannot seem to dynamically update the url.

OBS: 30.1.0
obs-urlsource: 0.2.6
obs-websocket: 5.0.1

Expected Behavior:
When calling 'SetInputSettings' via a WebSocket connection, the settings are updated and persist for the source.

Actual Behavior:
When calling 'SetInputSettings' via a WebSocket connection, the settings do not persist and are not consumed by the source. On a call to 'GetInputSettings', I see the setting values are updated but OBS does not show the updated settings when opening the 'Properties' window.

Add GraphQL support

I don't see it planned features, so leaving it here in advance as no plugin has support for this technology in OBS yet.

Parsed outputs are cut off if too many

When there are a lot of outputs, the list and output number both get cut off and can't be clicked through unless the window is resized off the screen. Maybe it would work better as a dropdown.

Screenshot 2024-01-27 at 10 03 11 PM

Building on FEDORA issue with libpugixml

Hello, mate!

I'm trying to build this plugin using the tutorial https://github.com/occ-ai/obs-backgroundremoval/blob/main/docs/BUILDING-FEDORA.md but I'm getting this error:

[35/35] Linking CXX shared module obs-urlsource.so
FAILED: obs-urlsource.so 
: && /usr/bin/c++ -fPIC -O2 -g -DNDEBUG   -shared  -o obs-urlsource.so CMakeFiles/obs-urlsource.dir/obs-urlsource_autogen/mocs_compilation.cpp.o CMakeFiles/obs-urlsource.dir/src/plugin-main.c.o CMakeFiles/obs-urlsource.dir/src/url-source.cpp.o CMakeFiles/obs-urlsource.dir/src/ui/RequestBuilder.cpp.o CMakeFiles/obs-urlsource.dir/src/request-data.cpp.o CMakeFiles/obs-urlsource.dir/src/ui/text-render-helper.cpp.o CMakeFiles/obs-urlsource.dir/src/url-source-info.c.o CMakeFiles/obs-urlsource.dir/src/obs-source-util.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/jsonpointer.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/jsonpath.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/regex.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/xml.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/errors.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/html.cpp.o CMakeFiles/obs-urlsource.dir/src/parsers/binary-data.cpp.o  /usr/lib64/libobs-frontend-api.so.29  _deps/libcurl_fetch-src/lib/libcurl.a  libplugin-support.a  /usr/lib64/libobs.so.29  /usr/lib64/libQt6Widgets.so.6.6.0  /usr/lib64/libQt6Gui.so.6.6.0  /usr/lib64/libGLX.so  /usr/lib64/libOpenGL.so  /usr/lib64/libQt6Core.so.6.6.0  /usr/lib64/libssl.so  /usr/lib64/libcrypto.so  /usr/lib64/libz.so  pugixml_build-prefix/lib/libpugixml.a  lexbor_build-prefix/lib/liblexbor_static.a && :
/usr/bin/ld: cannot find pugixml_build-prefix/lib/libpugixml.a: No such file or directory
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Could you please help like on obs-localvocal that Is now working on FEDORA?

Output text source is not updated

I have a data source that should do requests every 30s - and outputs this to a text source (due to the mentioned CSS rendering issues). But the text source is never updated and keeps the initial values forever or until I reload the scene.

FTBFS since Lexbor inclusion in urlsource 0.2.1

URL Source 0.2.1 and 0.2.2 FTBFS.

I build OBS Studio and 50 plugins from source as a portable build for Ubuntu.

Most plugins, including urlsource, are built in the same way. Here is the generic build for a plugin:

A couple of flags are provided for URL Source to prevent compiler warnings from failing the build:

Since Lexbor was included in URL Source 0.2.1, the plugin fails to build from source. Here is the log:

+ cmake -S /root/obs-30/plugins/obs-urlsource -B /root/obs-30/plugins/obs-urlsource/build -G Ninja -DCMAKE_BUILD_TYPE=Release '-DCMAKE_CXX_FLAGS= -Wno-error=conversion -Wno-error=shadow' '-DCMAKE_C_FLAGS= -Wno-error=conversion -Wno-error=shadow' -DCMAKE_INSTALL_PREFIX=/root/obs-30/obs-portable-30.0.0-r23321-ubuntu-23.04 -DUSE_SYSTEM_CURL=ON -DUSE_SYSTEM_PUGIXML=ON --preset linux-x86_64 -Wno-dev
+ tee /root/obs-30/build/cmake-obs-urlsource.log
Preset CMake variables:

  ENABLE_FRONTEND_API:BOOL="TRUE"
  ENABLE_QT:BOOL="TRUE"
  QT_VERSION="6"

-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Threads: TRUE  
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Qt version found: 6
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libOpenGL.so   
-- Found WrapOpenGL: TRUE  
-- Found XKB: /usr/lib/x86_64-linux-gnu/libxkbcommon.so (found suitable version "1.5.0", minimum required is "0.5.0") 
-- Found WrapVulkanHeaders: /usr/include  
-- Found CURL: /usr/lib/x86_64-linux-gnu/libcurl.so (found version "7.88.1")  
-- jsoncons v0.171.0
-- Version 12.3.0
Config:
 target        = single_include/inja/inja.hpp
 working_dir   = /root/obs-30/plugins/obs-urlsource/vendor/inja
 include_paths = []
Creating amalgamation:
 - processing "inja/inja.hpp"
...done!

Files processed: ['inja/inja.hpp']
Files included: ['inja/inja.hpp', 'inja/environment.hpp', 'inja/config.hpp', 'inja/template.hpp', 'inja/node.hpp', 'inja/function_storage.hpp', 'inja/utils.hpp', 'inja/exceptions.hpp', 'inja/statistics.hpp', 'inja/parser.hpp', 'inja/lexer.hpp', 'inja/token.hpp', 'inja/renderer.hpp']

-- lexbor will be installed to /root/obs-30/plugins/obs-urlsource/build/lexbor_build-prefix
-- lexbor library expected at /root/obs-30/plugins/obs-urlsource/build/lexbor_build-prefix/lib/liblexbor_static.a
-- Configuring done
-- Generating done
-- Build files have been written to: /root/obs-30/plugins/obs-urlsource/build
+ cmake --build /root/obs-30/plugins/obs-urlsource/build
ninja: error: 'lexbor_build-prefix/lib/liblexbor_static.a', needed by 'obs-urlsource.so', missing and no known rule to make it

A few weeks ago, I experienced a similar pugixml issue in this project. I worked around it by using a system-provided pugixml.

I cannot use the same workaround for Lexbor as it is not published in Debian/Ubuntu archives.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.