Skip to main content

Radio Bern Now Playing

This repo contains the tool we use to grab, aggregate and publish show, artist and track metadata from various sources.

The nowplaying project grabs info from RaBes playout solution and publishes them to broadcast vectors like DAB+ and Webstreams.

It also takes care of generating our live ticker at songticker.rabe.ch.

Overview

The nowplaying daemon takes various sources into account:

It then make an informed decision as to what should be our leading PAD data and pushes this to it's track handlers for the following sinks:

  • DAB+ (via the ODR-EncoderManager API)
  • Webstream by pushing to our Icecast instances
  • Statically hosted XML output for browsers on songticker.rabe.ch

The sources are currently individually implemented and are being replaced with generic RaBe CloudEvents based sources. In many places the legacy system is underdocumented and this documentation documents the new system.

Usage

TBD

RaBe CloudEvents

The nowplaying projects receives httpd RaBe CloudEvents on a dedicated web service. It reacts to them depending on the event type and source

It supports the following event types:

  • ch.rabe.api.events.track.v1.trackStarted
  • ch.rabe.api.events.track.v1.trackFinished

An example trackStarted event looks like this:

{
  "specversion": "1.0",
  "type": "ch.rabe.api.events.track.v1.trackStarted",
  "source": "<source>",
  "subject": null,
  "id": "<id>",
  "time": "2021-12-28T19:31:00Z",
  "datacontenttype": "application/json",
  "data": {
    "item.artist": "hairmare fusion sounds collective",
    "item.title": "C L O U D E V E N T W A V E",
    "item.length": 36000
  }
}

It can be sent to the nowplaying service using cURL as follows:

curl -vvv -u rabe:rabe -H 'Content-Type: application/cloudevents+json' -X POST -d '@event.json'  localhost:8080/webhook

In most cases the use of a cloudevents-sdk is recommended. The following example is based on the same python-sdk nowplaying uses.

import requests

from cloudevents.http import CloudEvent, to_structured

def send_event(url, username, password):
    # This data defines a cloudevent
    attributes = {
        "specversion": "1.0",
        # as defined by the events-spec repo
        "type": "ch.rabe.api.events.track.v1.trackStarted",
        # for klangbecken the github link is always used as source (as per events-spec)
        "source": "https://github.com/radiorabe/klangbecken",
        # this should be generated and could/should point to a real
        # URL on either https://klangbecken.service.int.example.org
        # using a `crid://` URL based on the upcoming crid-spec.
        "id": "uri:demo:12345",
    }
    data = {
        "item.title": "Track Title",
        "item.artist": "Artist",
        # length in seconds, optional if you also implement sending the
        # not "completely specced yet" trackFinished event
        "item.length": 60,
    }

    event = CloudEvent(attributes, data)
    headers, body = to_structured(event)

    # send and print event
    requests.post(url, headers=headers, data=body, auth=(username, password))
    print(f"Sent {event['id']} from {event['source']} with {event.data}")

if __name__ == "__main__":
    # local config
    url = "https://nowplaying.service.int.example.org/webhook"
    username = "rabe"
    password = "rabe"

    # do work
    send_event(url, username, password)

Contributing

pre-commit hook

pip install pre-commit
pip install -r requirements-dev.txt -U
pre-commit install

testing

pytest

Release Management

The CI/CD setup uses semantic commit messages following the conventional commits standard. There is a GitHub Action in .github/workflows/semantic-release.yaml that uses go-semantic-commit to create new releases.

The commit message should be structured as follows:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

The commit contains the following structural elements, to communicate intent to the consumers of your library:

  1. fix: a commit of the type fix patches gets released with a PATCH version bump
  2. feat: a commit of the type feat gets released as a MINOR version bump
  3. BREAKING CHANGE: a commit that has a footer BREAKING CHANGE: gets released as a MAJOR version bump
  4. types other than fix: and feat: are allowed and don't trigger a release

If a commit does not contain a conventional commit style message you can fix it during the squash and merge operation on the PR.

Once a commit has landed on the main branch a release will be created and automatically published to pypi using the GitHub Action in .github/workflows/pypi.yaml which uses twine to publish the package to pypi. Additionaly a container image based on the RaBe Python Minimal Base Image is built and published using Docker build-push Action. This is managed in .github/workflows/release.yaml.

License

This application is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.

Copyright (c) 2022 Radio Bern RaBe

Metadata

Release files for rabe-nowplaying 2.17.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rabe-nowplaying 2.17.0
File Size Uploaded Provenance Actions
rabe_nowplaying-2.17.0.tar.gz 35.1 kB Without provenance Details for rabe_nowplaying-2.17.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for rabe-nowplaying 2.17.0
File Interpreter ABI Platform Actions
rabe_nowplaying-2.17.0-py3-none-any.whl Python 3 none any Details for rabe_nowplaying-2.17.0-py3-none-any.whl

Total release size: 75.8 kB

Release files / rabe_nowplaying-2.17.0.tar.gz

Download URL rabe_nowplaying-2.17.0.tar.gz
Size 35.1 kB
Tags Source
SHA-256 checksum
How to use checksums
08d05c81671013c69ca86c2bb33dd7bd14a9639d8721bb9be8b7a02a0e7d6bab
BLAKE2b-256 checksum
How to use checksums
f122d65db2037530270aac3da04fe31e9e42f96c229fa0ccbf6fec411c8fa9ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.6.1 CPython/3.10.12 Linux/6.2.0-1015-azure

Release files / rabe_nowplaying-2.17.0-py3-none-any.whl

Download URL rabe_nowplaying-2.17.0-py3-none-any.whl
Size 40.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ea294e0c768984ada7faaaf68b96d61b94b3b7961e82f679944ec3e33ee2ba8e
BLAKE2b-256 checksum
How to use checksums
580a2562ec1a972942e981e7d7b854855f2f750a7ecd1ac65004d7bf41273365
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.6.1 CPython/3.10.12 Linux/6.2.0-1015-azure

Security for rabe-nowplaying 2.17.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.17.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page