Server: Suggestion - an alternative to OSC...?

Created on 29 Aug 2016  Â·  47Comments  Â·  Source: CasparCG/server

Didi Kunz backed by Mcdikki suggested that I post this here. Here is what I wrote on the Forum -

Having extended my Livecode lower thirds client to include a clip player and multiple outputs (I'm very proud of this, having only started with Livecode a few weeks ago) - I thought it would be really good to have a countdown clock on the running clip, just like the stock client only bigger.

Like lots of others here, I read that there's an OSC output and thought it would be easy. But as it turns out OSC isn't exactly friendly for the amateur coder who's really a TV person in disguise . Like others, I thought OSC would be text.

I couldn't even make the stuff show up! It took me a while to work out, thanks to someone called Ultravibe, that you have to listen on 6250. Port 5253 gets a mention on the docs, but I don't know what it does. Is that where you send the RegisterMethod command? If only people would write clear documentation. Anyway - now I can see the OSC bundles and that leads to a suggestion....

I wonder if it would be possible for the people who kindly write CasparcG to maybe provide a different output for simple stuff, like the countdown clock, or any kind of clip timer, for people who can't manage taking apart a varying length binary string. It could be straight text, once every frame. I could work with that. I would have thought it would be fairly straightforward for someone who knows what they are doing, as the info is there being encoded into OSC, and the code is there for making sockets happen. Maybe there's other simple stuff that people need that can be sent in the large gaps.

I've spent more time than almost anyone in the world of tv - just over fifty years now - most at the BBC, and as a producer /director the only things I ever cared about in a clip are "how long on this?" "what are the out words?" "how does it end?" Perhaps someone out there might want all the other OSC stuff, but I can't imagine who.

CasparCG can't supply me with the out words etc, but it could easily tell me when the piece will end, and it would be really useful to have that accessible to simple people like me, writing code for free.

Here's hoping

Bernard Newnham

typfeature

Most helpful comment

It sounds like the best is for somebody to upgrade that existing library for LiveCode to support the newer version (since you say that it is written for an older version of LiveCode). I know nothing about LiveCode but I think that would be the best approach, and would also benefit others in the LiveCode community regardless of their interest in CasparCG.

Otherwise, could you specify how you would like the "simpler" protocol to look like? Should it be transported over TCP or UDP?

and OSC is also far too complex to do such a simple job

I disagree. It is a matter of your client disregarding information it does not need, and only caring about the numbers you want.

All 47 comments

If you look at CasparCG source code – you would even notice lines like:

void send_osc()
{
    monitor_subject_    << core::monitor::message("/profiler/time")     % frame_timer_.elapsed() % (1.0/format_desc_.fps);                                  
    monitor_subject_    << core::monitor::message("/file/time")         % (file_frame_number()/fps_) 

So first message "key" would be "/profiler/time" and the value – some float value. Same for "/file/time" key here.

So basically to use OSC in your client you need:

  1. Add a predefined OSC client IP and PORT to casparcg.config – that is your data reciever machine IP address and port
  2. Start UDP listener on that IP and PORT
  3. Use some OSC library to parse received UDP packets. CasparCG uses oscpack. After this step – "OSC is just text".
  4. Filter received OSC messages with regexp to get the messages you need

I'm sorry - I'm a TV producer stumbling through making a LIvecode client that does what a university needs. Fiddling with source code is well beyond my capabilities

B

Well, I actually hear first time about Livecode from you now, but little googling brought me to the this old Livecode forum thread and it seems to me this thread contains exactly what you ask for – a libOSC for Livecode

Good luck

I mentioned Livecode at the top.
I know that thread - the code was written in 2008 on a very old version of Livecode and I haven't been able to make it work. Also - I can sort of make this work using INFO, but its a lot less of a solution to just making CasparCG do what you average tv person would like it to do.

B

OSC is as simple as you can get it while being realtime.

I recommend you check if there is any libraries for LiveCode that supports OSC.

If I knew enough about this stuff I'd regard that as a challenge. And I've already spent a lot of time hunting for libraries and failing.

I've managed to get the INFO command to give me a seconds countdown so that might do the trick, but it's massive overkill for just two numbers - and OSC is also far too complex to do such a simple job.

It may be that others out there need all that obscure stuff that OSC provides, but I think I can reasonably guarantee that tv production people just need what I need - it's my skill area and I've been doing it for a very long time. I repeat my request.

B

It sounds like the best is for somebody to upgrade that existing library for LiveCode to support the newer version (since you say that it is written for an older version of LiveCode). I know nothing about LiveCode but I think that would be the best approach, and would also benefit others in the LiveCode community regardless of their interest in CasparCG.

Otherwise, could you specify how you would like the "simpler" protocol to look like? Should it be transported over TCP or UDP?

and OSC is also far too complex to do such a simple job

I disagree. It is a matter of your client disregarding information it does not need, and only caring about the numbers you want.

Yes, upgrading the Livecode library so that I could use it would help me, but it wouldn't be any use to anyone trying to do the same job who isn't using Livecode.

I have no idea how the simpler protocol should look, as I'm just a visitor - a tv producer trying to write some free software for a university in a system that I only started using a few weeks ago. If you look at the CasparCG forum you'll see that I'm far from the only one of my kind trying to do a similar task. If you are working for free for a charity or whatever, CasparCG is a godsend. But whoever decided that OSC was the only way to go hadn't fully checked out their target audience. We aren't engineers or full time software writers, we are people who need to get a tv task done, and for me this is much like picking up a soldering iron to repair a cable when no experienced wireman is around. I can do it, but I'm not and never will be an expert. I'm an expert TV producer, director, cameraman, editor etc.

Imagine - you are the director of a tv show live on air. A clip is playing out of a CasparCG server. Do you need to know all those OSC things, like the current codec, or the video width? Of course not, you sorted all that weeks ago in the edit. What you need to know is -

"How long have I got on this clip??"

Loudly.

So you are that same person a few weeks beforehand writing the software that plays the clips because you don't have a software writer any more than you have a soldering iron person. That'll be me. I've managed to write enough to get lower-third supers on and off, and then extended that to playing clips. Now It'd like to put in a countdown clock. The actual clock I can do, but getting the data has proven a far too complex job. So, since I am a typical "customer" - something easily checked by looking or asking on the forum - I thought I'd just ask - please can we have a simple way to see -

"How long have I got on this clip??"

Say - once every frame a different socket sends three numbers. The frame number, the total frames and the frame rate (to make the calculation easy). Perhaps each block could be preceded by a "hey, here are your numbers" token, so that "200 OK" etc can be filtered out. I have no idea how that can be provided, but I do know that CasparCG has the data because it sends it to OSC. And I do know that a lot of "customers" will be extremely grateful.

B

Yes, upgrading the Livecode library so that I could use it would help me, but it wouldn't be any use to anyone trying to do the same job who isn't using Livecode.

All other programming languages that I know of have one or more OSC libraries to choose from. I think you might be overestimating how useful this would be to other people using a programming language that supports OSC in some manner.

But whoever decided that OSC was the only way to go hadn't fully checked out their target audience.

I consider "programmers/software engineers" to be a big part of the target audience of the CasparCG Server, and for them OSC is simple. The "programmers/software engineers" then makes clients like for example the CasparCG Client, which in turn exposes the functionality to the "TV production people". Many persons are both "programmers" and "TV production people" though. That is how I humbly view our target audience.

One way of supporting your request would be to implement an AMCP conversation something like this:

>> ASYNC_FRAME_SUBSCRIBE 1-10
<< 202 ASYNC_FRAME_SUBSCRIBE OK
>> PLAY 1-10 clip
<< 202 PLAY OK
<< 101 FRAME
<< 1-10 50/1 1/57
<< 101 FRAME
<< 1-10 50/1 2/57
<< 101 FRAME
<< 1-10 50/1 3/57
...
<< 1-10 50/1 57/57
>> ASYNC_FRAME_UNSUBSCRIBE 1-10

...but it adds a lot of complexity to the server and AMCP itself. I don't like to consider AMCP asynchronous by nature but rather synchronous with a series half duplex 1 request followed by 1 response pairs.

A client library supporting the asynchronous nature will have to be written in a more complex way as well.

One way of supporting your request would be to implement an AMCP conversation something like this:

I think that would be a much better solution then OSC (even for languages without OSC library like VB6 etc.) for many cases as it allows for single TCP (or serial) connections from client(s) to server. It would even make running multiple clients on single machine easier.

But I would prefer to have the status feedbacks in a single (for each subscribed content) line like this:

>> ASYNC_FRAME_SUBSCRIBE 1-10
<< 202 ASYNC_FRAME_SUBSCRIBE OK
>> ASYNC_FRAME_SUBSCRIBE 1-11
<< 202 ASYNC_FRAME_SUBSCRIBE OK
>> PLAY 1-10 clip
<< 202 PLAY OK
>> PLAY 1-11 clip
<< 202 PLAY OK
<< 101 FRAME 1-10 50/1 1/57
<< 101 FRAME 1-11 50/1 1/57
<< 101 FRAME 1-10 50/1 2/57
<< 101 FRAME 1-11 50/1 2/57
<< 101 FRAME 1-10 50/1 3/57
<< 101 FRAME 1-11 50/1 3/57
...
>> ASYNC_FRAME_UNSUBSCRIBE 1-10
<< 202 ASYNC_FRAME_UNSUBSCRIBE OK
>> ASYNC_FRAME_UNSUBSCRIBE 1-11
<< 202 ASYNC_FRAME_UNSUBSCRIBE OK

This would make parsing at client side a lot easier and allows for simple filtering out the status messages from other responses.
Of course it would be even possible to open an extra AMCP connection just for status feedback messages...
If client does not want or support status feedback it just does not send the subscribe command. So there would be never a problem with "legacy" clients which does not support async messages.

By the way this is very similar to how it is implemented in MVCP protocol (SGI / melted):
[https://www.mltframework.org/bin/view/MLT/MVCP]
This is very nice for all kind of TV automation.

I think that would be a much better solution then OSC (even for languages without OSC library like VB6 etc.) for many cases as it allows for single TCP (or serial) connections from client(s) to server. It would even make running multiple clients on single machine easier.

If it is a matter of running multiple clients on the same machine perhaps OSC_SUBSCRIBE <port> as suggested in https://github.com/CasparCG/Server/issues/307 is best. Then AMCP is used for managing the subscription and OSC is used for the data. Furthermore a client uninterested in OSC would not have to be bombarded with it (as it is today).

Instead of polluting the AMCP protocol with 101 responses a dedicated TCP server could of course be created, only dealing with OSC-like data but in plaintext. Similar to the new LOG-server built into 2.1. Only one way communication where interested parties could filter out the lines they are interested in.

The main problem I have with using TCP (regardless of via AMCP or dedicated socket) for this kind of continuous stateless information is that this is where OSC and UDP really shines.

UDP packages can get lost for example, which I think is a good thing, because it does not give the user a false sense of _"this information can be utilized to achieve frame accurate and seamless playout"_, but rather _"this information is useful to give an indication of where we are in a clip"_.

The only tools in AMCP (today) that can be used for frame accuracy purposes are LOADBG ... AUTO and MIXER ... DEFER/MIXER ... COMMIT.

For what I'm doing - studio gallery stuff - seconds accuracy is all that's required. I haven't the faintest idea what you're saying people, but I'm very grateful that you are putting your minds to it

B

I would realy like to have async messages _inside_ AMCP protocol. This way you can even use it multiplexed with commands from clients like automation systems e. g. over a single serial line.

If you like instead a separate connection for this kind of feedback you can easily open up another TCP connection where you do only AMCP commands or only send a single subscribe command.

Of course OSC (over UDP) may and can be used for better timing but there are even many usecases where frame accurate feedback is not requiered but simple and clear implementation is recommended.

+1
having a time/position/countdown mechanism inside the AMCP connection is nice
to have!
in my opinion it is even better if it is send out in a low interval like 0.5s
to show it's low accurate behaviour.
next to that i think it would be nice that you ask the server to give this info for a certain layer ONCE.
to minimize info you don't need!

grt
Maurice

AMCP should stay synchronous, but another info/feedback TCP-feed that you could subscribe to, like events, would be the bomb. Events for:

  • Layer got new content (producer loaded)
  • Layer changed state (empty, loaded, playing, mixer-effect applied/remvoed)
  • Clip started playing, finished playing, paused, resumed
  • Clip progress (interval ≈ 1 second or configurable)
  • Clip-near-end (threshold in progress % or seconds to go)

A tonne of regular things that happen in the server all the time, that you in other cases need to parse AMCP responses, INFO-commands and/or OSC to calculate.

Though it would be helpful if only requested info was sent - INFO commands have lots of info that takes time to strip "200 OK" etc and decode.

Personally I can't do OSC in Livecode, hence this thread, but it does seem to be sending lots of stuff that's probably irrelevant once a clip is running. Also irrelevant to me, I read about a RegisterMethod command in the docs, but they don't tell you where to send it.

My Livecode attempt at a countdown clock, which sends an INFO request every half second, tends to ignore subsequent STOP commands, presumably because its overloaded.

A tonne of regular things that happen in the server all the time, that you in other cases need to parse AMCP responses, INFO-commands and/or OSC to calculate.

I think mostly all those events you listed only requires "parsing OSC to calculate". Here is how that is done today (or could be able to be be done, after adding some missing OSC values to the server):

  • Layer got new content (producer loaded)

Needs a small addition to OSC, something like:
/channel/<channel>/stage/<layer>/current_producer changing value (I acknowledge that PLAY of the same clip twice cannot be captured by this method).

  • Layer changed state (empty, loaded, playing, mixer-effect applied/removed)

"empty": layer silence (absence of /channel/<channel>/stage/<layer> paths)
"loaded": going from "empty" state to /channel/<channel>/stage/<layer>/paused = true
"playing": going to /channel/<channel>/stage/<layer>/paused = false either directly from "empty" state or via "loaded" state

"mixer-effect applied/removed" needs some kind of addition to OSC.

  • Clip started playing, finished playing, paused, resumed

"started playing" is pretty much like "playing" in the previous point.
"finished playing" /channel/<channel>/stage/<layer>/file/frame reached destination (I know that there is a bug where this does not occur. I'm working on that)
"paused" going from state "playing" to /channel/<channel>/stage/<layer>/paused = true
"resumed" going from state "paused" to /channel/<channel>/stage/<layer>/paused = false

  • Clip progress (interval ≈ 1 second or configurable)

/channel/<channel>/stage/<layer>/file/frame every frame, but the client is free to ignore in its own pace.

  • Clip-near-end (threshold in progress % or seconds to go)

Calculated from /channel/<channel>/stage/<layer>/file/frame in combination with /channel/<channel>/stage/<layer>/file/fps

I recognize that:

  • State changes can be missed because of:

    • UDP.

    • How the server "collects" path values while sending previous values, effectively ignoring all but the newest value for each OSC path.

  • This could be considered hard to implement in a client.

If the fact that _"State changes can be missed"_ is acceptable then this convenience protocol could be implemented outside of the CasparCG Server as a bridge between OSC and simpler clients.

If it is not acceptable these things would have to be implemented in the server and the monitor::subject facility would need to be extended with support for "events" instead of just "changing values".

I personally think OSC is simpler to use in a client because it gives the server's "full state". Using the event approach would mean that the client will never know whether it has the "full state" or not, INFO would have to be used initially to populate the client and then go on from there with the events.

Thank you @HellGore! Really good explanation, and great inspiration as I aim to do such a library for node.js. Open Source, of course.

@Bernie333 I am sorry that this issue has been hijacked by a very interesting conversation not directly related to your problem. I can however promise you that the conversation is indirectly related and may result in something useful for you.

Thank you!

@HellGore I am only vaguely aware of the internal structure of CasparCG but how hard would it be to implement a WebSocket server into CasparCG?

WebSockets are real time, event based communication and I think most languages have an implementation for websockets. certainly more than OSC.

225

Slightly off-topic:

There is another downside to OSC. Anybody ever tried running two instances of the Client on the same pc? Or the Client and another app that needs OSC?

When a client opens AMCP connection to the Server, the Server starts spitting back OSC messages at the client's IP address and port 6250 (I think). If you run 2 apps on the same pc, only one of them can receive the OSC messages.

I know there is a workaround with predefined-client on the Server, but that's just mildly annoying, as you need to know the IP address of the client (ie, can't use DHCP) and use non-standard port.

No, this is correct.

The connected Client is the OSC Server. The Server is the OSC client. You need to tell the Server instance which OSC Server to connect to. This happens in two ways:

  • Every new AMCP socket connection triggers a new OSC connection to that Client on the default port.
  • In addition to this, one or more pre-defined OSC Servers can be automatically connected from the config.

Just as you need to separate your AMCP sockets by port if you run multiple instances (why would you, btw?), you need to separate your OSC sockets. It's not a workaround, it's just how it works.

@jesperstarkar that's yet another downside os OSC -- their terminology is backwards. ;)
Jokes aside, the problem is this:

First, when I refer to _the Server_ and _the Client_ I mean _the CasparCG Server_ and _the CasparCG Client_.

So, the problem is: I can run multiple instances of the Client on the same pc and open multiple AMCP connections to the same of different Servers. However, only the first instance of the Client will be able to receive the OSC messages. All other will not be able to.

No, it's not backwards if you think of the data flow ;)

Can't you just add multiple pre-defined clients in the config and give every client an unique incoming OSC port?

@jesperstarkar I can, but that's a workaround. What if my pc is on DHCP and gets a different IP address? Or what if I need to run it from a different pc? I would have to add/change it in the config each time and restart the server. Don't need to do any of that with AMCP. It's a bit of a design issue IMHO.

What you want then is an AMCP command for adding OSC clients

That or perhaps instead of using a fixed port to send OSC messages to, the Server could use AMCP port +1 and the Client would expect them on that port. Then multiple clients can dynamically connect from the same pc and receive their OSC messages

No, this is not a good solution for fixing something that is not a problem, yet inconvenient.

Regarding predefined clients: If you run Server + Client on the same machine, you can use 127.0.0.1 for IPs. Since you mention the DHCP problem, I think you have separate machines. You should solve this locally with DHCP address reservation etc.

The only implementation I can see that fixes your use case is to add AMCP support for handling OSC clients.

I am running 2 Servers (one in shadow mode) and the Client is on the 3rd machine.
Sure, I can solve it locally, but why should I? I don't have to do any of that for the AMCP connections.

Sorry for completely hijacking this thread :)

And just to remind you.... My request was for a simple counter - seconds will do - so that I can countdown to the end of a clip. Quite an important thing in a TV studio. I'm not a good enough programmer to get into C++ libraries or whatever. I would just like a simple system I can use in Livecode which doesn't do OSC or Websockets or anything else fancy.

B

@Bernie333 if you are running Linux and don't mind it being in a separate window, I've done this some time ago using socat, grep and/or sed commands.

It beginning to become quite a big topic ;)

I did not know the LOG port existed.
such a easy solution would definitely work for early event warnings /countdowns
for low to medium experienced programmers / client builders like bernie and me

grt
Maurice

The university is running Windows and the client has to fit into their systems. I'm currently having a go at a kludge I found elsewhere that someone suggested - ask for INFO once, then free run the timer. I don't know how accurate it will be.

I think this is becoming a big topic because a lot of people have asked for a time output and haven't got anywhere. Lots of people like myself aren't programming professionals, we just pop in to do a job, and then get back to being a producer of whatever. OSC is too complex, and in any case Livecode has no suitable library - even if I knew how to use libraries

I knocked together a quick demo of what I've done so far for my uni colleagues
http://www.tech-ops.co.uk/bern/caspar.html

B

The university is running Windows and the client has to fit into their systems. I'm currently having a go at a kludge I found elsewhere that someone suggested - ask for INFO once, then free run the timer. I don't know how accurate it will be.

Definitely accurate enough for your purposes @Bernie333, since you only needed second precision.

@dimitry-ishenko and @jesperstarkar: Your discussion about multiple clients on the same machine would be possible without a workaround if we implemented OSC_SUBSCRIBE <port> as I mentioned in an earlier comment. #307 covers that,

@HellGore Cool, didn't know that.

@Bernie333 Sounds like a good solution to you.

Definitely accurate enough for your purposes @Bernie333, since you only needed second precision.

Well, I've worked my way down from something I thought was important and also obvious to "How can I make something - anything - work?"

When it's running I'll report back

B

Well that’s the one that had a typo in it

From: Bernie333 [mailto:[email protected]]
Sent: Monday, September 05, 2016 10:38 AM
To: CasparCG/Server
Subject: Re: [CasparCG/Server] Suggestion - an alternative to OSC...? (#470)

Definitely accurate enough for your purposes @Bernie333https://github.com/Bernie333, since you only needed second precision.

Well, I've worked my way down from something I thought was important and also obvious to "How can I make something - anything - work?"

When it's running I'll report back

B

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHubhttps://github.com/CasparCG/Server/issues/470#issuecomment-244791022, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABLMyRzc2tRoiyWbYIV2hMJlPdqT3teMks5qnFNbgaJpZM4Jv0r-.

Well sadly that doesn't work. By the end of a 7.44 clip - which I'm now very bored with - it's about 10 seconds out.

As I know the clip runs 7.44 - measured on a stopwatch - it must be Livecode. I get the INFO once then free run the countdown. I first ran the loop every 100 milliseconds then every 500 milliseconds but it didn't seem to make any difference. I assume that Livecode gets its time from the host computer, which gets its time from time.windows.com so it ought to know the time. I don't know what wrong and I'm stuck now - back to original request.

B

@Bernie333 I will try to help you on the forum as this issue isn't the right place for a discussion unrelated to an enhancement of CasparCG's OSC implementation.

Indeed, and I've moved the Livecode discussion to a Livecode forum.

Of course I wouldn't be having the problem at all if CasparCG could send simple time info, maybe down a different socket, maybe every 25th second (in PAL related video). I started this thread because other more experienced people than me thought I should, as they agreed with the idea.

Bernie

Did the ideas of OSC alternatives or additions ever go anywhere? I'd love to see some of them but I'm not now in a position to dive in to the server code.

Having not got very far on that front I gave up and
    changed direction somewhat. TV studio work doesn't need frame accurate timing, and after
        wrestling somewhat
          with the Livecode timer system - highly inaccurate - I found a solution that used
                  Unix time in the loop, which does a very good job.

                  B


On 09/11/17 01:07, The real zbang
  wrote:


  Did the ideas of OSC alternatives or additions ever go
    anywhere? I'd love to see some of them but I'm not now in a
    position to dive in to the server code.
  —
    You are receiving this because you were mentioned.
    Reply to this email directly, view it on GitHub, or mute the thread.







  {"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/CasparCG/Server","title":"CasparCG/Server","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/CasparCG/Server"}},"updates":{"snippets":[{"icon":"PERSON","message":"@z-bang in #470: Did the ideas of OSC alternatives or additions ever go anywhere? I'd love to see some of them but I'm not now in a position to dive in to the server code."}],"action":{"name":"View Issue","url":"https://github.com/CasparCG/Server/issues/470#issuecomment-343014350"}}}

I’m closing this. If anyone wants to summarize the information here feel free to open a new issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesperstarkar picture jesperstarkar  Â·  53Comments

TomKaltz picture TomKaltz  Â·  75Comments

TKooijmans picture TKooijmans  Â·  61Comments

premultiply picture premultiply  Â·  25Comments

dotarmin picture dotarmin  Â·  28Comments