CasparCG / server

CasparCG Server is a Windows and Linux software used to play out professional graphics, audio and video to multiple outputs. It has been in 24/7 broadcast production since 2006. Ready-to-use downloads are available under the Releases tab https://casparcg.com.
GNU General Public License v3.0
905 stars 268 forks source link

POC: nodejs control plane (Feedback wanted) #1533

Open Julusian opened 5 months ago

Julusian commented 5 months ago

I am very interested in feedback from others on whether they think this is a good idea or not. The code is far from complete or ready, this is still very much at the proof of concept stage.

If anyone has any questions or concerns please share them here. Or you can PM me on the forum if you have something you would prefer not to say/share publicly.


I've had this idea for a while now, which is to replace the C++ AMCP implementation with nodejs. This spawned from thinking about #826 where the scope grew quite a lot, and frustration with the current AMCP parsing, particularly for producers/consumers which have many properties. Additionally I was thinking about adding a http api as an alternative to AMCP, but didn't find a http server that looked decent and wouldn't be a burden as a dependency which also had an openapi generator.

This nodejs control plane would provide a few key benefits:

Also some downsides:

A key thing to note is that no frames go near the nodejs portion. When loading a producer we do pass the pointer to nodejs, but not in a way that it can be inspected or operated on. So this should have no impact on the ability of caspar to do playout well. This only impacts the amcp part, and producer/consumer creation up until they are added to the channel.

This does run if compiled from source (on linux), and existing clients can connect and work as expected. If we go ahead with this, more work is needed to:

jpc0 commented 3 months ago

Is it wise to directly depend on nodejs? This effective create a node addon and has the casparcg server depend on that. I haven't spent a lot of time looking at this and definitely will want to but is it at all feasible to rather export a C API that then get called from the node side. That way any future implementation isn't restricted to nodejs and can be done in golang/C++/swift/zig/rust or whatever language has compatibility with C.

I'm not against this at all. I find the current AMCP parsing impossible to reason about so any change is probably for the better.

Julusian commented 3 months ago

Is it wise to directly depend on nodejs? This effective create a node addon and has the casparcg server depend on that.

Yes, this does effectively change casparcg to be a nodejs library requiring the use of that to run it.
That is a large part of my hesitation to continue with this, but also the purpose of this.

I chose nodejs as that it the main language I am using these days and my hope is that as many users will need to know some js to be able to make html graphics, they can reuse the same knowledge to understand this new layer of the server. Of course if there is a good reason to avoid nodejs and consider a different language, I am open to that.

I haven't spent a lot of time looking at this and definitely will want to but is it at all feasible to rather export a C API that then get called from the node side. That way any future implementation isn't restricted to nodejs and can be done in golang/C++/swift/zig/rust or whatever language has compatibility with C.

The nice thing about this api exposed to nodejs, is that because it is being wrapped in nodejs types, it should be impossible (assuming no bugs in that translation layer) to cause any memory issues/crashes in the c++ portion.
Doing this as a c api, will mean that the caller has to consider memory safety of pointers and things, which I think will make the control plane be a lot less approachable.
In theory nodejs might be able to use a c api like this, through some ffi library, but then there will be a layer of c level programming written inside js which feels horrible.

jpc0 commented 3 months ago

I chose nodejs as that it the main language I am using these days and my hope is that as many users will need to know some js to be able to make html graphics, they can reuse the same knowledge to understand this new layer of the server.

I find, at least for me, there is a large enough API difference between node and the browser that I need to relearn a lot, however I can agree with the sentiment that JS is significantly more popular than C++ and more people are likely to know the language in general.

The nice thing about this api exposed to nodejs, is that because it is being wrapped in nodejs types, it should be impossible (assuming no bugs in that translation layer) to cause any memory issues/crashes in the c++ portion.

I can see that, I agree with finding out what the users want and to my knowledge the largest users are probably using Superconductor or Sofie which are both in JS which means it makes a lot of sense to stick to JS there.


I've looked around some more in this branch and I like a lot of it. If I'm understanding correctly this is effectively the entire "external" interface into casparcg server. It's really nice to see a it all in one place that is very easy to trace. It also makes it much easier to understand what would be needed if I wanted to for instance fork and do a C API version...

Consider combining the scanner into this nodejs layer, probably as a worker_thread. That will simplify setup and deployment, and being in a thread will minimise risk of impact.

Another thing I would love is to have the documentation ( read wiki but doesn't need to be a wiki, could be a website served by node ) pulled into this repo as well. There are so many undocumented capabilities that when trying to work in the codebase you need to keep in mind. Being able to check that any changes are also document at pull request time would likely be an amazing benefit.

Two easy examples is the key + fill streams (https://github.com/CasparCG/server/blob/e4e9ed299e1a0f9c87c8709d19b0585a5703102a/src/modules/ffmpeg/producer/av_producer.cpp#L411-L425) in the ffmpeg producer and the low bandwith mode(https://github.com/CasparCG/server/blob/e4e9ed299e1a0f9c87c8709d19b0585a5703102a/src/modules/newtek/producer/newtek_ndi_producer.cpp#L304) in the NDI producer which are both undocumented. The ffmpeg producer example actually adds a decent amount of complexity to the code whereas the ndi producer doesn't but I'm sure there are other examples.

Likewise in the wiki there is the ability to do batched commands which I can't find any reference to in the current codebase or this branch of yours so the wiki is just blatantly wrong on that front, at least for 2.4.0.