8000 feat(playout): high availablility playout by dakriy · Pull Request #3149 · libretime/libretime · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(playout): high availablility playout #3149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8000 Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions docs/admin-manual/tutorials/setup-high-availability-playout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: How to setup high availability playout
---

This tutorial walks you through the steps required to setup playout for high availability.

:::info

We assume you have a way to consume multiple audio inputs (for example icecast). For terrestrial HA you might consider
having an audio processor with switching and silence detection capabilities.

:::

## 1. Initial LibreTime setup

When initially setting up LibreTime, first setup the components in
the [Create the schedule block](../../contributor-manual/design/architecture.md#create-the-schedule) along with
the message queue.

If you are going provide multiple icecast or shoutcast streams, please make sure to set all streams you want visible
from the LibreTime widget to enabled in this blocks config file.

## 2. Setup your playout blocks

Create your [Play the schedule blocks](../../contributor-manual/design/architecture.md#play-the-schedule).

You will need one for each replication you want, and any additional playout blocks you may want. For example, if you
are running a terrestrial radio station, you may have two playout blocks for your radio processor, and an additional
one for a non-HA icecast instance.

The playout blocks should each contain the LibreTime playout service as well as a liquidsoap service. They should be
able to talk to the message queue and the LibreTime API.

## 3. Configure each playout block

Create a config file for each playout block. Only enable the output you want from this block. For example, you may
configure two blocks for system output to an audio card, and another block for streaming to icecast.

The sections that need configured are

- [General](../configuration.md#general)
- Only `public_url` and `api_key` are needed. `cache_ahead_hours` currently has
no effect as playout is hardcoded to cache ahead 1 day.
- [RabbitMQ](../configuration.md#rabbitmq)
- [Playout](../configuration.md#playout)
- Make sure to configure the associated liquidsoap host for this block.
- [Liquidsoap](../configuration.md#liquidsoap)
- [Stream](../configuration.md#stream)
- Configure the stream outputs you want this playout block to provide and disable the rest.

## 4. Testing

Start all the playout blocks and confirm they get the schedule from the LibreTime web server. Additionally and verify
their outputs are correct.
4 changes: 2 additions & 2 deletions legacy/application/models/RabbitMq.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function SendMessageToPypo($event_type, $md)

$exchange = 'airtime-pypo';
$data = json_encode($md, JSON_FORCE_OBJECT);
self::sendMessage($exchange, 'direct', true, $data);
self::sendMessage($exchange, 'fanout', true, $data);
}

public static function SendMessageToMediaMonitor($event_type, $md)
Expand Down Expand Up @@ -88,7 +88,7 @@ public static function SendMessageToShowRecorder($event_type)
}
$data = json_encode($temp);

self::sendMessage($exchange, 'direct', true, $data);
self::sendMessage($exchange, 'fanout', true, $data);
}

public static function SendMessageToAnalyzer(
Expand Down
9 changes: 7 additions & 2 deletions playout/libretime_playout/message_handler.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ def __init__(
self.fetch_queue = fetch_queue

def get_consumers(self, Consumer, channel):
exchange = Exchange("airtime-pypo", "direct", durable=True, auto_delete=True)
queues = [Queue("pypo-fetch", exchange=exchange, key="foo")]
exchange = Exchange("airtime-pypo", "fanout", durable=True, auto_delete=True)
# RabbitMQ says to avoid temporary queues with well-known names
# https://www.rabbitmq.com/docs/queues#shared-temporary-queues
# A server named queue that expires is used so that if the service
# gets temporarily disconnected, no events are lost, but the queue is
# automatically cleaned up on shutdown.
queues = [Queue("", exchange=exchange, expires=30.0)]

return [
Consumer(queues, callbacks=[self.on_message], accept=["text/plain"]),
Expand Down
1 change: 0 additions & 1 deletion playout/libretime_playout/player/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ def set_bootstrap_variables(self) -> None:
except OSError as exception:
logger.exception(exception)

self.liquidsoap.clear_all_queues()
self.liquidsoap.clear_queue_tracker()

def update_liquidsoap_stream_format(
Expand Down
Loading
0