bitfocus / companion

Bitfocus Companion enables the reasonably priced Elgato Streamdeck and other controllers to be a professional shotbox surface for an increasing amount of different presentation switchers, video playback software and broadcast equipment.
http://bitfocus.io/companion
Other
1.47k stars 489 forks source link

API Expansion Request #2575

Open Oattsplease opened 9 months ago

Oattsplease commented 9 months ago

Is this a feature relevant to companion itself, and not a module?

Is there an existing issue for this?

Describe the feature

Preface: While there are requests for this sort of implementation, I think this one merges a couple of them together into a clear path of what operation could look like, enough to distinguish them from the other requests.
I'm also very new to programming/github, so sorry in advacne for any faux pas.

Goal: increase the options for Remote Control via the API so that other utilities can take advantage of Companion's variables/action execution features

Connection Functions

GET-CONNECTIONS

EXPOSE-'connection-Label/internal'-VARIABLES

HIDE-'connection-Label/internal'-VARIABLES

GET-'connecition-Label/internal/custom'-VARIABLE-VALUE

Less crucial but still useful:

Button Info Requests

GET-'PAGE,BANK'-(args)

Ideally, these can be concatenated into the same request via && or another symbol.

Additional Button Info Requests

Surface Info Requests

GET-SURACE-LIST (includes emulators) GET-'SURFACE'-PAGE

Return Message Requests

bank_bg_change:

Usecases

I would like to create a satellite-like app for interfacing with Midi controllers as a native companion, as mentioned in #1709:

It [midi for companion] feels like something that would be simple enough to do as a separate application and use one of the osc/tcp/udp api in companion to do things.

However, I think in addition to midi controllers, this API would allow people to create middleware that interfaces with Companion (like #1695 suggests) that could eventually be implemented into Companion's source code. Sucessful/commonly used middleware could be converted into Companion via a new iteration of companion satellite etc.

It allows other users to accelerate Companion in a way that produces more results the sooner it's implemented.

I also understand that the modules might not be currently built for dealing with certain inputs/responses (#1508), but I also think that with this being an API instead of a native device, the ownership is on the end user of this API to either fix their own code or the module owners to respond to asks to catch up with the implementation. Something successful being implemented but not available for the other modules will push those modules to integrate to include the new features.

Again, though, I am new to software development in general, so I don't know if the precedent is to safeguard user error to this extent.

P.S. I would like to help as much as possible, but I'm still becoming familiar with software development in general, and so I'm trying to learn all I can as quickly as I can, but I am still very new and am not sure how to approach this properly. ty
Julusian commented 9 months ago

I have nothing against adding this to the apis. But some issues I see:

I'm not keen on your proposed syntax, but that is a minor detail that can be worked out. eg rather than GET-'connection-Label'-VARIABLES, it will be much easier to parse as GET-VARIABLES 'connection-Label', or perhaps GET-VARIABLES CONNECTION='connection-Label' so that it can be extended later (perhaps GET-VARIABLES LABEL='connection-Label' INCLUDES='something', could be nice to do later on?)

Some of this probably falls under https://github.com/bitfocus/companion/issues/2079, as general cleanup of the apis.


However, I think in addition to midi controllers, this API would allow people to create middleware that interfaces with Companion (like https://github.com/bitfocus/companion/issues/1695 suggests) that could eventually be implemented into Companion's source code. Sucessful/commonly used middleware could be converted into Companion via a new iteration of companion satellite etc.

Would it not make more sense for these midi controllers to use the satellite api? It doesnt give everything you are asking for here, but to me is a much nicer way of integrating them, as it will give you the page changing behaviour of companion surfaces, as well as various styling information

Oattsplease commented 9 months ago

Thank you for your feedback! It's super helpful and helps me understand stuff a lot more.

EXPOSE/HIDE - The purpose of this was to keep down the available number of variables you can query. My current understanding was that the fewer variables being available reduces network bloat, but I could be very off-base. GET-'connection-Label'-IP - Totally ok! Ideally, whoever is using this API has access to the main companion interface anyway, so I don't see it as being too important GET-'PAGE,BANK'-(args) - That makes sense! Whatever's clever : )

Also very happy to use cleaner syntax!


Would it not make more sense for these midi controllers to use the satellite API?

So I think it actually makes sense to build on the satellite API for this, and it is the easiest path to having this working; however, I think expanding the HTTP/TCP/OSC etc API to include the features necessary for this will save on some potential double-work if other controller types are to be added down the line or people want to experiment with other protocols. It's been much quicker for me as a novice to start interacting with the TCP API as opposed to setting up an entire dev environment :sweat_smile:

I would LOVE it if this were supported officially in some manner, so maybe there's some "official" way/guide to build satellite off-shoots through this API to get them integrated as official apps. Ty!

tomhillmeyer commented 5 months ago

I would support the addition of GET commands for variables, as I can see various use-cases for wanting to display the live information that Companion variables have access to. At the moment I have Companion triggers send variables to a Firebase Realtime Database, then I use the Firebase API to update a live dashboard that displays several variables among other information.

GET options would be helpful for giving the ability of displaying cue times of video playback or current stream status in a format that isn't just a little StreamDeck button (or a StreamDeck button-shaped image in the emulator/web buttons). Maybe a dashboard designer is a future Companion feature, but for now the ability to use Companion as an easy way to get at live information about connected devices would be nice. Thanks!

bost-ty commented 5 months ago

+1ing here -- the ideal is a way to GET information on module and internal variables, maybe in the same syntactical way the Companion HTTP API (from the Settings tab, anyway) supports using ip:port/set/custom-variable?

This is particularly precious for modules like the Blackmagic Hyperdeck, where the hardware only supports one connection, but I imagine folks could find even more value from it than I can.

tomhillmeyer commented 5 months ago

I've actually done quite a bit of tinkering with the idea of displaying variables in a better way, and have a functioning mockup of a "Companion Dashboard" for various bits of information I typically ask for as a Director when I'm calling a show or as an operator when I have several things in front of me.

Screenshot 2024-02-04 at 11 05 44 AM 1

I have several Companion triggers set up to simply pass variables to a Firebase realtime database, which then this page displays. Surprisingly, there's only about a 1 second delay. Ideally I wouldn't need to pass through Firebase, which then would mean I could get this dashboard up and running by simply dropping in the IP of a Companion instance.

So in short, supporting GET in the HTTP API to pull variables would be awesome! I'm also very much a novice at programming, so if there's a better path here I'm all ears. Thank you!

bost-ty commented 5 months ago

@tomhillmeyer This is the exact use case. Thanks for sharing! I would really like to see how you're doing it if you're open to sharing.

This feature as part of Companion would -- I think -- make Satellite viable for some of the live workflows I've built in the past.

tomhillmeyer commented 5 months ago

@bost-ty Happy to share!

Firebase

Screenshot 2024-02-04 at 12 03 51 PM

Companion

Screenshot 2024-02-04 at 12 06 33 PM Screenshot 2024-02-04 at 12 09 03 PM

HTML/Javascript

const firebaseConfig = {
            apiKey: "XXXXXXX",
            authDomain: "XXXXXXXXXXXXXXXXX",
            databaseURL: "XXXXXXXXXXXXXXXXXXXXX",
            projectId: "XXXXXXXXXXXXXXXX",
            storageBucket: "XXXXXXXXXXXXXXXXX",
            messagingSenderId: "XXXXXXXX",
            appId: "XXXXXXXXXX"
        };

        // Initialize Firebase
        firebase.initializeApp(firebaseConfig);
        // Reference to the variable in the database
        const playbackMain = firebase.database().ref('/playback/main');

        // Update the web page content when the variable changes
        playbackMain.on('value', (snapshot) => {
            const playbackMainValue = snapshot.val();
            console.log('Playback Main:', playbackMainValue);

            // Update your web page content with the variable value
            document.getElementById('playbackMainLabel').innerText = playbackMainValue;
        });

Conclusion

I have zero idea if this is the best way to do this, but it's the way I know how!