Skip to content

decode-detroit/apollo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Apollo

Realtime Remote-Controlled Multimedia Player

This media player is designed for realtime playback of audio and video in theatrical and interactive applications. Configure the display locations and cue new media over http, either on the same computer or from the web.

Getting Started

If you're on a 64-bit GNU/Linux system, you can use the the binary release here. Note: The Wayland display server is not yet supported. Try the Wayland branch at your own risk.

Binary releases for other systems are a work in progress. In the meantime, you'll need a few things to compile and run Apollo:

Prerequisites

You'll need Rust, GTK+, and GStreamer to compile and run Apollo.

  • Installation of Rust: https://www.rust-lang.org/
  • Installation of GTK+: https://www.gtk.org/ (This is usually installed already on GNU/Linux systems. Search for package libgtk-3-0, and libgtk-3-dev if you'd like to compile Apollo.)

Follow the directions on both websites to download and install these tools before you proceed.

To install GStreamer on a Debian-like system,

sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav libgstrtspserver-1.0-dev libges-1.0-dev

If you're on a different system, you'll need to follow the platform-specific instructions for GStreamer-rs: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs

Compiling

Once you have installed the prerequities above, clone or download this repository. Then compile and run the program using Cargo (included with Rust):

cargo run

This will take several minutes to download all the components. You'll be left with a running Apollo instance in the background. You can use

cargo run

to run Apollo again (it will not recompile this time). This is a debug version (larger file, but otherwise perfectly functional).

To compile a finished copy for deployment, use

cargo build --release

The completed binary will be located in the automatically generated "target/release" folder with the name "apollo".

Issues Compiling

If you run into issues with glib-2.0 or gdk-3.0, you can run these commands on a Debian-like system:

glib2.0 issue:

sudo apt install libgtk2.0-dev

gdk-3.0 issue:

sudo apt install build-essential libgtk-3-dev

Usage

To play media on Apollo, you need to

  1. Define the media channel, and
  2. Tell Apollo what media to play on that channel.

You can have as many channels as you like (currrently tested with eleven simultaneous channels), but only one piece of media playing on each channel at a time.

Application Window Options

Before you specify a media channel, you have the option to specify the properties of the application window where it will be displayed. Remember that these settings only take effect if applied before adding a media channel to the window.

Here are the application window options:

  • windowNumber: a unique number for the application window. Channels with the same window number will appear on the same application window and will be stacked from first-defined to last-defined on the top.
  • fullscreen: a true or false value to indicate whether the window should be set to fullscreen.
  • windowDimensions: a two element tuple that specifies the minimum size of the application window that holds the video screen. If the application window is set to fullscreen, you can use this tool to stretch the application window across multiple monitors.

Media Channel Options

When you define a channel, you have the option to specify where the audio is played and where the video is played. If you leave these options empty, Apollo with use the system default for audio and open a new window (sized to the content) to play video.

Here are the media channel options:

  • channel: the channel number
  • videoFrame: a structure that defines the location and size of the video screen. Defaults to a new window generated by gstreamer.
  • audioDevice: the audio device for playing any sound. Defaults to the system default.
  • loopMedia: the media (video or audio) to loop when no other media is playing on this channel. Defaults to nothing if left blank.

A video frame has several parameters:

  • windowNumber: a number for the application window. Channels with the same window number will appear on the same application window and will be stacked from first-defined to last-defined on the top.
  • top: distance (in pixels) from the top of the application window to the top of the video.
  • left: distance (in pixels) from the left side of the application window to the left side of the video.
  • height: height (in pixels) of the video screen
  • width: (in pixels) of the video screen

An audio device has several options as well:

  • a Pulse audio device (with deviceName parameter): a high-level toolkit which is recommended for most purposes. Multiple chanels can share a device and will automatically be mixed together.
  • an Alsa device (with deviceName parameter): a lower-level toolkit usefull when trying to pick a specific display on a graphics card. WARNING: Only one channel can use an Alsa device at a time - Alsa does not have the capability to mixdown multiple audio sources.

Cue Media Options

When you cue a specific file for Apollo to play, it will begin instantly (or nearly instantly, depending on the capabilities of the computer). You have the option to play any type of media on any channel, though in practice you will typically have separate audio channels and video channels.

Here are the cue media options:

  • uri: the location of the video or audio file to play. The uri format must follow the URI syntax rules. This means local files must be specified like "file:///absolute/path/to/file.mp4".
  • channel: the media channel to play the video or audio. New media sent to the same channel will replace the old media, starting instantly.
  • loopMedia: the location of media to loop after this media is complete. If a file is specified in the loop media field, it takes priority over the channel loop media field.

RESTful API

You can define media channels and cue media using the two available POST commands on localhost port 27655 (A-P-O-L-L). An example interaction might look like this:

curl -H "Content-Type: application/json" -X POST -d '{ "channel": 1, "videoFrame": { "windowNumber": 1, "top": 100, "left": 100, "height": 300, "width": 400}}' http://localhost:27655/defineChannel
curl -H "Content-Type: application/json" -X POST -d '{ "uri": "https://archive.org/download/never-gonna-give-you-up-4-k/Never%20Gonna%20Give%20You%20Up%204K.ia.mp4", "channel": 1}' http://localhost:27655/cueMedia

Then, perhaps:

curl -H "Content-Type: application/json" -X POST -d '{ "channel": 1, "videoFrame": { "top": 0, "left": 0, "height": 600, "width": 800}}' http://localhost:27655/resizeChannel
curl -H "Content-Type: application/json" -X POST -d '{ "channel": 1, "direction": "down"}' http://localhost:27655/alignChannel
curl -H "Content-Type: application/json" -X POST -d '{ "channel": 1, "position": 2000}' http://localhost:27655/seek

And mercifully

curl -H "Content-Type: application/json" -X POST -d '{ "channel": 1, "state": "paused"}' http://localhost:27655/changeState
curl -H "Content-Type: application/json" -X POST http://localhost:27655/quit

The port number (and listening location) can be adjusted with the '-a' or '--address' commandline option, and log level can be set via the '-l' or '--logLevel' option. Log levels are Trace, Info, Debug, Warn, Error (listed in decreasing level of verbosity).

If you need to make Apollo available to the open internet, we recommend Caddy. Follow the instructions for setting up a reverse proxy (it will take less than 60 seconds).

In the future, additional options such as changing media to a different channel, swapping channel position, etc., will be added based on our own needs. If you are using Apollo and have a specific feature you need, feel free to send us an email and we'll do our best to make it a priority.

Raspberry Pi-like Systems (ARM)

It's possible to run Apollo on less-capible systems! For example, a Raspberry Pi 4 can manage audio very well, and plays video acceptably (with a small delay at the start of each).

Take careful notes of the steps to

  • cross-compile Apollo, and
  • setup your Raspberry Pi host to run Apollo

Note: These instructions are written for compiling the software on Ubuntu 22.04.

Cross-Compiling for Raspberry Pi (armhf, 32bit)

Note: These settings are largely analogous for arm64, but the 64-bit version hasn't been tested.

To cross-compile, install the correct rust target and install the linker.

rustup target add armv7-unknown-linux-gnueabihf
sudo apt install gcc-arm-linux-gnueabihf

You'll also need to add the armhf architecture to dpkg.

sudo dpkg --add-architecture armhf

And add these sources to the end of /etc/apt/sources.list.

deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted+
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy universe
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates universe
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy multiverse
deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates multiverse

Make sure to add [arch=amd64] to the other sources while you're at it.

Install the gtk dev packages for the new architecture.

sudo apt update
sudo apt install libgtk-3-dev:armhf libzmq3-dev:armhf libgstreamer1.0-dev:armhf libgstreamer-plugins-base1.0-dev:armhf gstreamer1.0-plugins-base:armhf gstreamer1.0-plugins-good:armhf gstreamer1.0-plugins-bad:armhf gstreamer1.0-plugins-ugly:armhf gstreamer1.0-libav:armhf libgstrtspserver-1.0-dev:armhf libges-1.0-dev:armhf libges-1.0-0:armhf

When you compile, pass several environment variables to the compilation.

env PKG_CONFIG_ALLOW_CROSS=1 PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/ cargo build_armhf

Cross-Compiling for Raspberry Pi (aarch64/arm64, 64bit)

To cross-compile, install the correct rust target and install the linker.

rustup target add aarch64-unknown-linux-gnu
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu 

You'll also need to add the arm64 architecture to dpkg.

sudo dpkg --add-architecture arm64

And add these sources to the end of /etc/apt/sources.list (or if also using 32 bit, combine the two like [arch=armhf,arm64]).

deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy universe
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates universe
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates multiverse

Make sure to add [arch=amd64] to the other sources while you're at it.

Install the dev packages for the new architecture.

sudo apt update
sudo apt install libgtk-3-dev:arm64 libzmq3-dev:arm64 libgstreamer1.0-dev:arm64 libgstreamer-plugins-base1.0-dev:arm64 gstreamer1.0-plugins-base:arm64 gstreamer1.0-plugins-good:arm64 gstreamer1.0-plugins-bad:arm64 gstreamer1.0-plugins-ugly:arm64 gstreamer1.0-libav:arm64 libgstrtspserver-1.0-dev:arm64 libges-1.0-dev:arm64 libges-1.0-0:arm64

When you compile, pass several environment variables to the compilation.

env PKG_CONFIG_ALLOW_CROSS=1 PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/ cargo build_arm64

Prepare Your Raspberry Pi

All that is needed is installing the packages above (i.e. GStreamer). If you're displaying video, you probably want to disable screen blanking in the Raspberry Pi Config settings.

Hardware decoding works well for videos up to 1080p at 30 fps. There is a short delay when switching between playing videos, but there is no delay when playing a new video after the first has stopped.

License

This project is licensed under the GNU GPL Version 3 - see the LICENSE file for details. This project is closely connected to Minerva.

Thanks to all the wonderful free and open source people out there who have made this project possible, especially Mozilla et al. for a beautiful language and the folks at Gnome, GTK, and GStreamer for their ongoing efforts advance multimedia in open source software.