Transcode Internet radio and video streams to HTTP MP3 streams 📻
10K+
Racoder is a lightweight Node.js web server that leverages FFmpeg to transcode Internet radio and video streams into HTTP MP3 streams. It supports a variety of input stream formats, including HLS, MPEG-DASH, and RTMP – essentially, anything that FFmpeg can handle.
Racoder supports two configuration modes (since v2):
Configuration options are set using environment variables.
| Name | Description | Default value | Example |
|---|---|---|---|
| INPUT_STREAM | Required. URL for incoming stream | N/A | https://artesimulcast.akamaized.net/hls/live/2030993/artelive_de/master_v180.m3u8 |
| BITRATE | Transcoding bitrate for output MP3 stream | 128k | 320k |
| LOG_LEVEL | Level of detail for log output | INFO | DEBUG |
| OUTPUT_PATH | URL path for output MP3 stream | / | /my-station |
| TZ | Timezone for log timestamps | UTC | Europe/Berlin |
To configure multiple streams, create a streams JSON file and specify its path using the STREAMS_FILE environment variable. When STREAMS_FILE is set, single-stream environment variables (INPUT_STREAM, OUTPUT_PATH, BITRATE) are ignored.
Multi-stream mode requires Racoder v2.0 or later
{
"defaults": {
"bitrate": "128k"
},
"streams": [
{
"input": "https://example.com/stream1.m3u8",
"output": "/stream1"
},
{
"input": "https://example.com/stream2.m3u8",
"output": "/stream2",
"bitrate": "192k"
}
]
}
Streams file options:
defaults (optional): Default values applied to all streams
bitrate: Default bitrate for streams that don't specify onestreams (required): Array of stream configurations
input (required): URL for the incoming streamoutput (required): URL path for the output MP3 stream (must start with /)bitrate (optional): Transcoding bitrate for this specific stream (overrides default)Environment variables for multi-stream mode:
| Name | Description | Default value | Example |
|---|---|---|---|
| STREAMS_FILE | Required. Path to streams JSON file | N/A | /config/streams.json |
| LOG_LEVEL | Level of detail for log output | INFO | DEBUG |
| TZ | Timezone for log timestamps | UTC | Europe/Berlin |
Examples:
Pre-built Docker images for different architectures are available on Docker Hub and the GitHub Container Registry. Deploy using Docker Compose on a small home server like a Raspberry Pi or host it (for free) on fly.io.
Security Note: Examples use --read-only and --cap-drop ALL to run the container with minimal privileges. These are recommended for production deployments.
Let's use a simple example and deploy an instance on our local client machine:
docker run \
--rm \
--read-only \
--cap-drop ALL \
--name racoder \
--publish 3000:3000/tcp \
--env INPUT_STREAM="https://as-hls-ww-live.akamaized.net/pool_26173715/live/ww/bbc_radio_four_extra/bbc_radio_four_extra.isml/bbc_radio_four_extra-audio%3d96000.norewind.m3u8" \
paulgalow/racoder:latest
Racoder will serve its output stream at http://<hostname>:3000/. So for this example open http://localhost:3000/ in your browser or media player of choice (like VLC, QuickTime, …) to listen to the output stream.
Here we are using the BBC Radio 4 Extra HLS AAC stream as input, but it does not have to be an audio HLS stream. Streams using MPEG-DASH are supported as well, as are video HLS/MPEG-DASH streams.
To run multiple streams, create a streams file (e.g., streams.json) and mount it into the container:
docker run \
--rm \
--read-only \
--cap-drop ALL \
--name racoder \
--publish 3000:3000/tcp \
--env STREAMS_FILE="/config/streams.json" \
--volume "$(pwd)/streams.json:/config/streams.json:ro" \
paulgalow/racoder:latest
With a streams file like this:
{
"streams": [
{
"input": "https://as-hls-ww-live.akamaized.net/pool_26173715/live/ww/bbc_radio_four_extra/bbc_radio_four_extra.isml/bbc_radio_four_extra-audio%3d96000.norewind.m3u8",
"output": "/bbc-radio-4-extra",
"bitrate": "128k"
},
{
"input": "https://artesimulcast.akamaized.net/hls/live/2030993/artelive_de/master_v180.m3u8",
"output": "/arte-de",
"bitrate": "192k"
}
]
}
Streams will be available at:
http://localhost:3000/bbc-radio-4-extrahttp://localhost:3000/arte-deRacoder provides a /healthcheck endpoint that returns HTTP 200 when the server is running. This can be used for container health checks and load balancer configuration.
Set LOG_LEVEL=DEBUG to see detailed FFmpeg output and stream processing information.
Content type
Image
Digest
sha256:4f6584a62…
Size
101.7 MB
Last updated
9 months ago
docker pull paulgalow/racoder