Skip to content

Instantly share code, notes, and snippets.

@felipeasimos
Last active March 2, 2023 18:17
Show Gist options
  • Save felipeasimos/d7394e822faee26df1042d51e4f78691 to your computer and use it in GitHub Desktop.
Save felipeasimos/d7394e822faee26df1042d51e4f78691 to your computer and use it in GitHub Desktop.
Cheap 24/7 radio livestreaming

How to Make a 24h Music Livestream

Stream video and audio file in loop for youtube, using FFmpeg. FFmpeg will get the job done with 2 vCPUs in this scenario (I tried with 1 vCPU on lightsail, and buffering was a frequent occurance there). Since this is a 24/7 program, paying hourly would be unsustainable. In order to avoid that, a 2vCPU VPS is what you are looking for.

Contabo and OneTSolutions are good providers for this specific VPS use case.

1. Buy cheapest VPS you can

Carefully choose your plans, test your stream locally before to calculate specifically your requirements. Using the -listen option in ffmpeg and ffplay command are great for testing locally. A great place to start looking is https://www.vpsbenchmarks.com. (I discovered Contabo and OneTSolution there)

Aside from 2 vCPUs, another requirement is enough bandwidth. Our stream bit rate will determine how much internet we will use per month. In my case, a 1920x1080 1080p 30fps stream could use up to 4.5Mpbs according to youtube live encoder settings:

4.5Mbps * 60 * 60 * 24 * 30 = 11664000 Mb = 1458 GB ~ 1.5 TB per month

Some providers offers unlimited/unmetered bandwidth, while some others don't. Contabo, for example, has a 32TB cap on the VPS S plan which is more than enough. (Overall this Contabo plan is pretty overkill for this usecase in particular).

2. Alter this launch-stream.sh to use your livestream URL and stream key

Also alter some settings for fit you inputs and purposes. The script will loop the given background video and get loop the audio. The ffmpeg will restart any time it fails. This will reset the audio, but the good news is that your live won't go down.

#!/bin/sh

STREAM_KEY=""
STREAM_URL=""

RTMP_DEST="${STREAM_URL}/${STREAM_KEY}"

background="background.mp4"
audio="audio.mp3"
size=1920x1080
video_bitrate=6000k
audio_bitrate=384k
volume="0.9"

# stream video and audio to youtube
cmd="ffmpeg \
  -re -stream_loop -1 -f mp4 -i $background \
  -re -stream_loop -1 -f mp3 -i $audio -filter:a volume=$volume \
  -b:v $video_bitrate -b:a $audio_bitrate -s $size -ar 44100 -c:a aac -ac 2 \
  -c:v libx264 -preset superfast -minrate 3100k -maxrate 4400k -bufsize 3000k -threads 2 -cpu-used 0 -coder 1 -profile:v high -bf 2 -r 30 -g 15 -crf 23 -pix_fmt yuv420p -movflags +faststart -segment_list_flags +live -x264-params keyint=48:min-keyint=48:scenecut=-1 \
  -map 0:v:0 -map 1:a:0 \
  -flvflags no_duration_filesize \
  -f flv ${RTMP_DEST}"

until ${cmd}; do
  echo "restarting ffmpeg command..."
  sleep 2
done

3. Copy background.mp4, audio.mp3 and launch-stream.sh

Copy your media files and script to the VPS.

4. Install ffmpeg on the instance

Or just use static builds:

https://johnvansickle.com/ffmpeg/

5. Run launch-stream uninterrupted

nohup ./launch-stream.sh &

This will launch the script without attaching it to your terminal. You can then safely close your ssh connection. To end the stream later you will have to kill it.

Report

Provider: OneTSolutions
VPS plan: GP-2
Monthly Price: 4.99 €
vCPUs: 2
RAM: 2GB
Disk: 20G NVMe (you can also choose a 40GB SSD)
Connection: 150Mpbs (more than enough, we will only use up to 5Mpbs for a 1920x1080 1080p 30 fps stream)
Bandwidth: Unlimited
OS: Debian 11

Disk usage (with 532MB of video + audio files):

# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            449M     0  449M   0% /dev
tmpfs           194M  440K  194M   1% /run
/dev/sda1        20G  2.8G   16G  15% /
tmpfs           970M     0  970M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/sda15      124M  5.9M  118M   5% /boot/efi
tmpfs           194M     0  194M   0% /run/user/0

RAM (in all my evaluations it never got to 0.4 GB of use):

# free -h
               total        used        free      shared  buff/cache   available
Mem:           1.9Gi       320Mi       116Mi       0.0Ki       1.5Gi       1.4Gi
Swap:             0B          0B          0B
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment