keepcalculator

06 Numbers and Powers

24/7 Devotional Stream: Docker & FFmpeg Setup

Card No. 06·63822 · Updated · Standard formula, shown below

This guide walks you through setting up a continuous 24/7 livestream of devotional content (scripture, worship music, or sermon loops) using Docker and FFmpeg. You’ll create a container that runs FFmpeg to combine a video loop with an audio playlist, encode it, and push it to a streaming platform like YouTube or Twitch. By the end, you’ll have a reliable, always-on stream that restarts automatically if it crashes.

What You’ll Need

  • A server or PC that stays on 24/7 (a cheap VPS or an old laptop works).
  • Docker and Docker Compose installed (see Docker’s official docs).
  • FFmpeg installed locally for testing (optional but helpful).
  • A streaming platform account (YouTube, Twitch, Facebook Live) with a stream key and stream URL.
  • Media files: a video loop (MP4) and an audio playlist (MP3 or M4A). You can use royalty-free sources like Pixabay or the Bible Project’s open content.

Step-by-Step

  1. Prepare your media files. Create a folder on your server, e.g., /opt/devotional-stream, and inside it create subfolders: video/ and audio/. Place your video loop (e.g., background.mp4) and your audio files (e.g., song1.mp3, song2.mp3) in the respective folders. Ensure the video loop is long enough (at least 30 seconds) and loops seamlessly (no abrupt cuts).
  2. Create a playlist file for audio. In the audio/ folder, create a text file named playlist.txt with the following content (one file per line, using relative paths):
    file 'song1.mp3'
    file 'song2.mp3'

    FFmpeg will loop this playlist indefinitely.

  3. Write a Dockerfile. In the root folder (/opt/devotional-stream), create a file named Dockerfile with this content:
    FROM alpine:latest
    RUN apk add --no-cache ffmpeg
    WORKDIR /media
    COPY video/ video/
    COPY audio/ audio/
    CMD ["/bin/sh", "/media/stream.sh"]

    This uses a minimal Alpine Linux image with FFmpeg installed. The CMD will run a script we’ll create next.

  4. Create the streaming script. In the same folder, create a file named stream.sh with the following content:
    #!/bin/sh
    while true; do
      ffmpeg -re -stream_loop -1 -i video/background.mp4 -f concat -safe 0 -i audio/playlist.txt -c:v libx264 -preset veryfast -b:v 2500k -maxrate 2500k -bufsize 5000k -pix_fmt yuv420p -g 60 -c:a aac -b:a 128k -ar 44100 -f flv rtmp://a.rtmp.youtube.com/live2/STREAM_KEY
      echo "Stream ended, restarting in 5 seconds..."
      sleep 5
    done

    Replace STREAM_KEY with your actual stream key (or the full RTMP URL if your platform uses a different format). The -re flag reads input at native speed, -stream_loop -1 loops the video forever, and the concat demuxer reads the playlist. The output is encoded in H.264/AAC and sent via RTMP.

  5. Make the script executable. Run chmod +x stream.sh in the folder.
  6. Create a docker-compose.yml. In the same folder, create docker-compose.yml with:
    services:
      stream:
        build: .
        container_name: devotional-stream
        restart: unless-stopped
        environment:
          - STREAM_KEY=your_key_here
        volumes:
          - ./media:/media

    This sets the container to restart automatically unless it’s manually stopped, which is crucial for 24/7 operation. The STREAM_KEY environment variable is passed to the script, but note that the script currently hardcodes the key; you can modify it to use $STREAM_KEY instead.

  7. Build and start the container. Run docker-compose up -d --build in the folder. This builds the image and starts the container in detached mode.
  8. Verify the stream. Check the logs with docker logs -f devotional-stream. You should see FFmpeg output showing the encoding process. If there are errors, see the Troubleshooting section below. Then check your streaming platform’s dashboard to confirm the stream is live.

Common Mistakes

  • Using absolute paths in the playlist. The concat demuxer requires relative paths (or -safe 0 for absolute). Use relative paths to avoid issues.
  • Forgetting to loop the video. Without -stream_loop -1, the video will end and the stream will stop. Make sure to include it.
  • Incorrect stream key or URL. Double-check your streaming platform’s RTMP URL and key. They are often long and easy to mistype.
  • Not making the script executable. If you get a permission denied error, run chmod +x stream.sh.
  • Using a video that is too short. A very short video (e.g., 2 seconds) may cause buffering or stuttering. Use a loop of at least 30 seconds.

Tips

  • Test locally first. Run the FFmpeg command on your local machine (without Docker) to verify your media files and stream key work. Replace the RTMP URL with a local test server if needed.
  • Use a higher bitrate for better quality. If your internet upload speed allows, increase -b:v to 4500k or higher for 1080p. For 720p, 2500k is fine.
  • Add a fallback image. If your video fails, you can use -loop 1 -i image.jpg as a fallback. But the while true loop already restarts the stream, so this is optional.
  • Monitor your stream. Use a service like UptimeRobot to ping your stream’s URL and alert you if it goes down.
  • Keep your media files organized. Use a separate volume for media so you can update songs without rebuilding the container.

Troubleshooting

  • Stream won’t start: “Connection refused” or “Invalid key”. Check your RTMP URL and stream key. For YouTube, the URL is rtmp://a.rtmp.youtube.com/live2 and the key is in your live dashboard. For Twitch, use rtmp://live.twitch.tv/app.
  • FFmpeg errors about codec or pixel format. Ensure your video is H.264 encoded (or let FFmpeg re-encode with -c:v libx264). The -pix_fmt yuv420p flag ensures compatibility.
  • Stream drops after a few minutes. This is often due to network instability or the platform kicking the connection. Check your server’s bandwidth and try lowering the bitrate. Also, the while true loop will restart it, but you may see gaps.
  • Audio not playing. Make sure the playlist file uses relative paths and that the audio files exist. Also, ensure the audio codec is AAC (-c:a aac).
  • Container exits immediately. Check the logs with docker logs devotional-stream. It might be a missing file or a permission issue. Ensure the media folder is mounted correctly.
  • High CPU usage. The veryfast preset is a good balance. If you have a weak CPU, use ultrafast but lower the bitrate to avoid quality loss.

Frequently Asked Questions

Can I use this for a radio-style stream with just audio?

Yes. Remove the video input and use a still image or a black background video. For audio-only, you can use -f lavfi -i anullsrc as a placeholder, but a simple video loop is easier.

How do I update the playlist without restarting the container?

You can edit the playlist.txt file on the host, and the next time the stream loops (every 5 seconds after a crash), it will pick up the changes. To force an immediate restart, run docker restart devotional-stream.

What if my streaming platform requires a different protocol, like SRT?

FFmpeg supports SRT via -c copy -f mpegts 'srt://...'. You’ll need to adjust the output URL and possibly the codec settings. Consult your platform’s documentation.

Can I run multiple streams with this setup?

Yes, by creating multiple containers with different names and stream keys. Use separate folders for each stream’s media.

How do I schedule different content for different times of day?

You can use a cron job to swap the playlist file or video file at specific times. For example, a script that replaces playlist.txt with a morning or evening version.

Is it legal to stream copyrighted worship music?

You need proper licenses. Many churches use CCLI or similar licenses. For royalty-free music, use sources like the Free Music Archive or create your own. Always check the terms.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →