Skip to content
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Created by https://www.toptal.com/developers/gitignore/api/visualstudio,windows,aspnetcore
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio,windows,aspnetcore

# Background-music file looped by the `music` service (large, provide locally)
combined.mp4

### ASPNETCore ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ just do the below command and the website is acessible at http://localhost:8000
```
docker-compose up
```

This also starts a `music` container that loops the audio track of
`./combined.mp4` and publishes it to the puppeteer-screen-recorder RTMP `sound`
channel (`rtmp://host.docker.internal:1935/live/weather/sound`), which the
weather streamer muxes into its live output. Put your background-music file at
`./combined.mp4` in this repo root (any file with an audio track works; it loops
forever and is gitignored). The streamer's node-media-server must be reachable
on host port 1935.
---
# WeatherStar 4000+

Expand Down
19 changes: 19 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,22 @@ services:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- '8000:80'
music:
container_name: music
build:
context: ./music
dockerfile: Dockerfile
volumes:
- ./combined.mp4:/media/combined.mp4:ro
environment:
- MUSIC_FILE=/media/combined.mp4
# Publishes to the node-media-server "sound" channel, which lives in the
# puppeteer-screen-recorder compose. We reach it over the host loopback
# via nms's published 1935 port, so the two compose projects stay
# independent (no shared docker network required).
- RTMP_MUSIC_STREAM_URL=rtmp://host.docker.internal:1935/live/weather/sound
# Docker Desktop resolves host.docker.internal automatically; this line
# makes it resolve on Linux hosts too.
extra_hosts:
- 'host.docker.internal:host-gateway'
restart: unless-stopped
11 changes: 11 additions & 0 deletions music/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Streams looping background music (the audio track of combined.mp4) to the
# node-media-server "sound" RTMP endpoint. The weather streamer then muxes
# this audio into its live video output.
FROM alpine:3.20

RUN apk add --no-cache ffmpeg

COPY stream-music.sh /usr/local/bin/stream-music.sh
RUN chmod +x /usr/local/bin/stream-music.sh

ENTRYPOINT ["/usr/local/bin/stream-music.sh"]
23 changes: 23 additions & 0 deletions music/stream-music.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh
# Continuously stream the audio track of a local video file to an RTMP
# endpoint (the node-media-server "sound" channel), looping forever so the
# weather stream always has background music.
set -u

MUSIC_FILE="${MUSIC_FILE:-/media/combined.mp4}"
: "${RTMP_MUSIC_STREAM_URL:?RTMP_MUSIC_STREAM_URL must be set}"

echo "streaming music: ${MUSIC_FILE} -> ${RTMP_MUSIC_STREAM_URL}"

# Outer loop so we reconnect if the media server restarts or the connection
# drops. -stream_loop -1 loops the file itself; -re paces it at real time.
while true; do
ffmpeg -hide_banner -loglevel warning \
-re -stream_loop -1 -i "${MUSIC_FILE}" \
-vn \
-c:a aac -b:a 128k -ar 44100 -ac 2 \
-f flv "${RTMP_MUSIC_STREAM_URL}"

echo "music ffmpeg exited with code $?; retrying in 5s..."
sleep 5
done