Hello,
To start things off, my end goal is to create an way to display various song metadata into OBS for use with our churches live stream. Basically, I'd like to take the Song Author/Title/Verses/CCLI Song # and dump them to text files for which OBS can read from.
I have been toying with the API on and off for a couple weeks now. I've been relatively turned off from it's usage due to it causing instability/crashes with OpenSong. I've found simply polling the status/slide endpoints at the wrong time (e.g. around times of starting/exiting a presentation)
I ended up writing a proxy application which only "allows requests" to the OpenSong endpoint after the presentation mode is running. This works nicely in practice, however we've still observed crashes when exiting presentation mode, as there is no way to "know" from a REST point of view, when the presentation mode will end.
Moving on to today's research, I looked into the external rendering and LilyPond python code supplied here. This seemed to be a good alternative to what I wanted (basically just using it as a Push service and returning the XML back effectively un-modified) however I soon discovered that the external rendering did not update / send a packet when the presentation hit the last slide. I also observed weirdness when using multiple songs in a single presentation. With that said, I'm faced with a similar problem as the API: When using External Rendering, I have no way to know when the presentation is "finished" or otherwise preparing to move on to the next song.
I saw the ticket https://sourceforge.net/p/opensong/support-requests/221/ and assume I am having similar issues with regards to the REST API, but was unsure if there was any root cause analysis. Happy to help if I can.
Anonymous
You are correct that this issue is similar to support request 221 - in fact, I think it is the same. I am the author of the API and I investigated it after that support request. Within available time back then, I was not able to find the root cause. I found that:
The external rendering feature was never developed with your objective in mind. It for this reason has no knowledge of preceding or following slides; its purpose is to render 'this' and send the result back to OpenSong.
Context is available via the API e.g. via the various endpoints: '/presentation/slide/list' gets the full set, '/presentation/status' will get you the current presentation status, to tell whether a presentation is active or not. It won't tell you whether a certain slide is the 'last'. One of the reasons is 'because OpenSong itself does not know'. A slide, or verse, might be the last in the set, but that does not mean it is the last item that is shown before ending the presentation, since the order depends on the actions by the person in control of the presentation helper window.
A good way to get instant notifications of whatever is going on, is to use the websocket interface. When you subscribe to presentation changes on the endpoint '/ws/subscribe/presentation', Opensong will send a notification, so you don't have to poll. This is demonstrated in e.g. http://vwout.github.io/os-secondscreen/
Lastly, you could use the snapshot export feature of OpenSong. When activated, OpenSong will export an image of the currently showing slide, with an xml containing the contents of the currently active slide. That however won't tell you when the presentation ended.
The best integration can probably be achieved by writing an OBS plugin (or a script) using the websocket interface.
Appreciate the quick response, especially around the holidays. I whipped up a quick script and can confirm that WebSocket subscription is the way to go for my use case. I basically set up a REST API call (one session per presentation, torn down once the presentation ends) which calls the
/presentation/slide/{slide_id}endpoint.I should mention that I didn't mean to say that ' I have no way to know when the presentation is "finished"' but rather I need to know when to "clear" information from OBS. The API (when grabbing the slide by the identifier) helpfully gives an empty body for empty slides; thus I was inferring we could clear text files loaded by OBS when we see this slide. However the external render only rendered slides when it needed to (e.g. not when it's empty); Makes sense in hindsight.
Anyways, I did get a very small amount of cases where OpenSong still crashed (only during exiting of presentation mode) with my new implementation. I spent about an hour trying to get it to reproduce myself (using old code, sending requests faster, etc) with WinDbg spawning OpenSong and debugging it and it's child processes but faced similar non-reproducable problems as you stated earlier. Assuming one of the following things is going on as I never actually got a crash exception (application just hung / became "Not Responsive")
Also had DebugView open on the side, but nothing particularly interesting showed up, which would be expected if you aren't using OutputDebugString-like calls; figured I'd give it a try nonetheless