Skip to content
Snippets Groups Projects
README.md 10.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • # AURA Engine Core
    
    David Trattnig's avatar
    David Trattnig committed
    
    
    David Trattnig's avatar
    David Trattnig committed
    [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) [![Latest Release](https://gitlab.servus.at/aura/engine-core/-/badges/release.svg)](https://gitlab.servus.at/aura/engine-core/-/releases) [![pipeline status](https://gitlab.servus.at/aura/engine-core/badges/main/pipeline.svg)](https://gitlab.servus.at/aura/engine-core/-/commits/main)
    
    
    David Trattnig's avatar
    David Trattnig committed
    <img src="https://gitlab.servus.at/aura/aura/-/raw/main/assets/images/aura-engine.png" width="120" align="right" />
    
    David Trattnig's avatar
    David Trattnig committed
    
    
    Engine Core is a multi-channel playout server for radio stations based on [Liquidsoap](https://www.liquidsoap.info/).
    It is able to broadcast via audio device outputs or connect to Icecast streams.
    
    This documentation is primarily meant for developers. For using the AURA Community Radio Suite
    check out the documentation at [docs.aura.radio](https://docs.aura.radio/)
    
    To learn more about Automated Radio go to [aura.radio](https://aura.radio).
    
    ## Channel Routing
    
    Playout channels are routed this way:
    
    ```mermaid
    graph TD
        iq0[Queue A] -->|in_queue_0| mix
        iq1[Queue B] -->|in_queue_1| mix
        is0[Stream A] -->|in_stream_0| mix
        is1[Stream B] -->|in_stream_1| mix
        il0[Line In 1-5] -->|in_line_0..4| mix
        ff[Fallback Folder] -->|fallback_folder| which_fallback
        fpls[Fallback Playlist] -->|fallback_playlist| which_fallback
        mix["  Mixer  "] --> silence_detector
        which_fallback{or} -->| | silence_detector{Silence Detector}
        silence_detector -->| | output[Output]
        output --> |output.alsa| C[fa:fa-play Audio Interface]
        output --> |output.icecast| D[fa:fa-play Icecast]
    ```
    
    ## Prerequisites
    
    David Trattnig's avatar
    David Trattnig committed
    
    
    Before you begin, ensure you have met the following requirements:
    
    David Trattnig's avatar
    David Trattnig committed
    
    
    - Operating system: Debian 11, Ubuntu 20.04 or newer
    
    - Audio device which has good [ALSA](https://alsa-project.org/wiki/Main_Page) support
    
    - [Liquidsoap 2.2.4](https://www.liquidsoap.info/) installed using [OPAM (OCaml Package Manager)](https://opam.ocaml.org/)
    
    - [PipeWire](https://pipewire.org/) installed
    - [WirePlumber](https://pipewire.pages.freedesktop.org/wireplumber/) installed as a session / policy manager for PipeWire
    - [qpwgraph](https://gitlab.freedesktop.org/rncbc/qpwgraph), optional as an UI to manage audio devices
    
    - [Docker](https://www.docker.com/), optional if you want to run in a container
    - `git`, `make`
    
    David Trattnig's avatar
    David Trattnig committed
    
    
    ## Installing Engine Core
    
    Install system dependencies:
    
    ```bash
    apt install curl alsa-utils libasound2-dev libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libflac-dev libjack-dev libpulse-dev libswresample-dev libswscale-dev libssl-dev ffmpeg opam
    ```
    
    Build Liquidsoap with additional libraries:
    
    ```bash
    opam depext alsa pulseaudio bjack ffmpeg samplerate flac taglib mad lame vorbis flac opus cry ocurl liquidsoap -y
    opam install alsa pulseaudio bjack ffmpeg samplerate flac taglib mad lame vorbis flac opus cry ocurl liquidsoap -y
    ```
    
    Now initialize the project environment for development
    
    ```bash
    make init.dev
    ```
    
    This command also creates a default configuration file `config/engine-core.ini`.
    
    ## Configuring Engine Core
    
    ### Configure the audio interface
    
    You get the most glitch-free experience when using [PipeWire](https://pipewire.org/) as your media server. To avoid any play-out malfunctions ensure that no other media server is running. PipeWire is capable of replacing PulseAudio while still having the full functionality of PulseAudio if you want to keep PulseAudio. To check if PipeWire has replaced PulseAudio, run `make audio.pa.status`. This command should return a line like
    
    ```
    Server Name: PulseAudio (on PipeWire 0.3.80)
    ```
    
    To check if PipeWire is up and running you can use 
    
    ```bash
    systemctl --user status pipewire
    ```
    
    ### Choose your audio system ALSA / JACK
    
    At the moment we recommend running engine-core with [JACK](https://jackaudio.org/). [ALSA](https://alsa.opensrc.org/) support for the complete AURA system was dropped in favour of JACK but might be added back in. In either case PipeWire takes care of your devices and connections.
    
    ### Configure JACK/ALSA
    
    Have a look at `config/sample.engine-core.ini`. Here you can set things like the log level and much more. For JACK no adaptations are necessary. 
    
    For ALSA you might want to set a different audio device or even configure your own. An example can be found in `config/sample.asoundrc`. Very important is the `alsa_buffer`, if you experience jitter, cracklings or other audio artifacts you should increase this number. If the buffer is to large you will experience bad latency, to reduce the latency you have to reduce the buffer size.
    
    When you are finished copy the configuration `config/sample.engine-core.ini` to `config/engine-core.ini`. 
    
    cp config/sample.engine-core.ini config/engine-core.ini
    
    ## Configure the audio source locations
    
    Engine Core is requires different audio sources in order to perform the playout.
    
    ### Configure the location for fallback music
    
    By default fallback audio is retrieved from the `fallback` folder. A local folder for any
    emergency playback, also called _Station Fallback_.
    
    ```bash
    audio/fallback/
    ```
    
    All audio files inside are played in a randomized order, in situations where nothing is scheduled.
    The folder is being watched for changes. So you can add/remove audio on the fly.
    
    
    This fallback feature is enabled by default, but can be turned off in via the configuration.
    
    
    Instead of the fallback folder you can use a playlist in the `playlist` folder for fallback
    scenarios. Its default file location is:
    
    ```bash
    audio/playlist/station-fallback-playlist.m3u
    
    Also this playlist is being watched for changes. You'll need to set the configuration option
    `fallback_type="playlist"` to enable this instead of the fallback folder.
    
    ### Configure the audio source folder
    
    This is the location for actually scheduled audio files. They are provided by Tank.
    
    ```bash
    audio/source
    ```
    
    If you are running all AURA services on a single instance you should be fine with just creating a
    
    David Trattnig's avatar
    David Trattnig committed
    symbolic link to the relevant Tank folder (`ln -s $TANK_STORE_PATH audio/source`). But in some
    
    [distributed and redundant production scenario](https://docs.aura.radio/en/latest/administration/deployment-scenarios.html)
    you might think about more advanced options on how to sync your audio files between machines.
    
    
    David Trattnig's avatar
    David Trattnig committed
    You can find some ideas in the doc "[Setting up the Audio Store](https://docs.aura.radio/en/latest/administration/setup-audio-store.html)".
    
    ### Configure via environment variables
    
    
    David Trattnig's avatar
    David Trattnig committed
    Many settings of Engine Core can also be set via environment variables. They are primarily used
    
    for Docker deployments. Check the `Makefile` and `sample.env` for hints on environment variables.
    
    
    ## Running Engine Core
    
    
    To make the playout server play some music first create the folder `audio/fallback/` if it doesn't exist and drop some music files. This folder is picked up as a so-called _Station Fallback_ in case no other music is scheduled or if silence is detected.
    
    
    To start the server execute
    
    ```bash
    make run
    ```
    
    
    Ole Binder's avatar
    Ole Binder committed
    ### Connect Audio Device
    
    
    Now connect your audio device(s) with engine-core. There are two ways to achieve this:
    
    
    - use an UI like [qpwgraph](https://gitlab.freedesktop.org/rncbc/qpwgraph), simply draw connections between the desired devices
    
    - use the PipeWire cli tool `pw-link`
    
    ```bash
    # List the input ports
    pw-link -i
    # List the output ports
    pw-link -o
    
    # An example for connecting an output port with an input port
    
    pw-link "lineout_0:out_1" "alsa_output.usb-BEHRINGER_UMC202HD_192k_12345678-00.stereo-fallback:playback_FR"
    
    # An example for connecting an input port with an output port
    pw-link "alsa_input.usb-Yamaha_Corporation_Yamaha_AG06MK2-00.pro-input-0:capture_AUX0" "in_line_0:in_0"
    
    Voilá, you should hear some music!
    
    
    ## Running Engine Core with docker compose
    
    When running engine-core with docker compose you need a different configuration file to start with. Have a look at `config/sample.engine-core.docker.ini` and copy it to `config/engine-core.ini` (FIXME: this uses the overwrite in /etc/aura/ and is not the best of options). Do not change the paths here, rather change them in `sample.env` and copy this file to `.env`. Make sure the directories in `.env` are read and writable for the user used in the container, mainly `aura(2872:2872)`.
    
    
    Ole Binder's avatar
    Ole Binder committed
    It is important to set the `PIPEWIRE_USER_ID` to the uid of the user running pipewire. To check which user is running the pipewire server run the following:
    
    ```bash
    ps -fp $(pgrep -d, -x pipewire)
    
    # UID          PID    PPID  C STIME TTY          TIME CMD
    # loxbie      2034    2025  0 09:19 ?        00:00:00 /usr/bin/pipewire
    ```
    
    ```bash
    id -u loxbie
    
    # 1000
    ```
    
    
    You can now build the container with
    
    ```bash
    docker compose build
    ```
    
    And start it with
    
    ```bash
    docker compose up
    ```
    
    
    Martina Müller's avatar
    Martina Müller committed
    Connect your audio device(s) with engine-core as mentioned [above](#connect-audio-device). If you want engine-core to automatically connect your device every time you start it, you can also pass a device via the `.env` file to engine-core. For this you need the device alias and the channel names of your device. To get these run
    
    Ole Binder's avatar
    Ole Binder committed
    
    ```bash
    docker compose run engine-core wpexec /etc/wireplumber/scripts/ls-ports.lua
    ```
    
    This dumps details on every connected audio device. Grab the `port.alias` of your device and enter it in the `.env`. Press `CTRL + C` to exit the script.
    
    <details>
        <summary>Example Configuration</summary>
    
    ### Device Dump
    
    ```
    { ["audio.channel"] = AUX0,
    ["port.physical"] = true,
    ["port.alias"] = Yamaha AG06MK2:capture_AUX0,
    ["node.id"] = 61,
    ["format.dsp"] = 32 bit float mono audio,
    ["port.direction"] = out,
    ["port.name"] = capture_AUX0,
    ["port.terminal"] = true,
    ["object.serial"] = 324,
    ["object.id"] = 66,
    ["object.path"] = alsa:pcm:1:hw:1,0:capture:capture_0,
    ["port.id"] = 0,
    } 
    ```
    
    ### .env Settings
    
    ```bash
    # Audio Device Settings
    
    AURA_ENGINE_OUTPUT_DEVICE=Yamaha AG06MK2:playback
    
    Ole Binder's avatar
    Ole Binder committed
    AURA_ENGINE_OUTPUT_CHANNEL_LEFT=AUX0
    AURA_ENGINE_OUTPUT_CHANNEL_RIGHT=AUX1
    
    AURA_ENGINE_INPUT_DEVICE=Yamaha AG06MK2:capture
    
    Ole Binder's avatar
    Ole Binder committed
    AURA_ENGINE_INPUT_CHANNEL_LEFT=AUX0
    AURA_ENGINE_INPUT_CHANNEL_RIGHT=AUX1
    ```
    
    </details>
    
    Voilá, you should hear some music!
    
    ## Advanced tips for development
    
    ### Control playout via telnet
    
    Connect to Liquidsoap via [Telnet](https://en.wikipedia.org/wiki/Telnet)
    
    `make tns`
    
    List available commands
    
    `help`
    
    List all available channels
    
    `list`
    
    List all input channels connected to the mixer
    
    `mixer.inputs`
    
    Set the volume of mixer `input 0` to `100%`
    
    `mixer.volume 0 100`
    
    Push some audio file to the filesystem `in_queue_0`
    
    `in_queue_0.push /path/to/your/file.mp3`
    
    
    Select line in as your input where 4 is the number from `mixer.inputs`
    
    ```
    mixer.select 4 true
    ```