This guide shows you how to run a 24/7 live stream of a recorded language course using FFmpeg on an Ubuntu server. You’ll set up a loop that plays your video files continuously, with a stable stream that viewers can join anytime. You need a basic Ubuntu installation, the video files you want to stream, and a streaming platform (like YouTube or Twitch) that provides a stream URL and key.
What You’ll Need
- An Ubuntu machine (18.04 or later) with internet access. It can be a VPS or an old desktop; it just needs to stay on.
- FFmpeg installed. If it’s not, run
sudo apt update && sudo apt install ffmpeg. - Your recorded language course as video files (MP4, MKV, etc.) stored in a folder, e.g.,
/home/user/course/. - A streaming account (YouTube, Twitch, Facebook, etc.) that gives you a stream URL (like
rtmp://a.rtmp.youtube.com/live2) and a stream key (a long alphanumeric string). - A text editor (nano or vim) and basic command-line comfort.
Step-by-Step
- Prepare your video files. Place all the course videos in one folder. Name them in the order you want them to play, for example
01-intro.mp4,02-alphabet.mp4, etc. FFmpeg will play them alphabetically, so consistent naming is important. - Create a playlist file. In that folder, create a text file named
playlist.txtwith one line per video, using the formatfile '01-intro.mp4'. For example:file '01-intro.mp4' file '02-alphabet.mp4' file '03-vocabulary.mp4'
Save the file.
- Test the playlist locally. Run this command to verify the playlist works and your videos are readable:
ffmpeg -f concat -safe 0 -i playlist.txt -t 10 -f null -
It should run for 10 seconds without errors. If you see errors, check the file names and paths.
- Find your stream URL and key. Log into your streaming platform, go to the live streaming dashboard, and copy the stream URL and stream key. Keep them handy. Usually, the full RTMP URL is the stream URL plus the key, like
rtmp://a.rtmp.youtube.com/live2/xxxx-xxxx-xxxx. - Test a short stream. Run a test stream for a few seconds to confirm your setup works:
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.txt -c:v libx264 -preset veryfast -b:v 2500k -maxrate 2500k -bufsize 5000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 128k -f flv rtmp://your.stream.url/your_stream_key
Watch it for a minute. If it doesn’t error out, you’re good.
- Run the stream in the background. Once the test works, stop it (Ctrl+C) and run the final command in a way that keeps running even if you log out. Use
nohupor a systemd service. For a quick start, use:nohup ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.txt -c:v libx264 -preset veryfast -b:v 2500k -maxrate 2500k -bufsize 5000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 128k -f flv rtmp://your.stream.url/your_stream_key > ffmpeg.log 2>&1 &
This runs FFmpeg in the background, logging output to
ffmpeg.log. - Set up a systemd service (recommended for reliability). For a robust 24/7 stream, create a service file. Use
sudo nano /etc/systemd/system/course-stream.servicewith:[Unit] Description=24/7 Language Course Stream After=network.target [Service] WorkingDirectory=/home/user/course ExecStart=/usr/bin/ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.txt -c:v libx264 -preset veryfast -b:v 2500k -maxrate 2500k -bufsize 5000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 128k -f flv rtmp://your.stream.url/your_stream_key Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Then enable and start it:
sudo systemctl enable course-stream.service sudo systemctl start course-stream.service
Check status with
sudo systemctl status course-stream.service. - Monitor the stream. Check the log file (
tail -f ffmpeg.log) or usejournalctl -u course-streamto see FFmpeg’s output. Look for errors like connection drops or encoding issues.
Common Mistakes
- Forgetting
-re. Without it, FFmpeg reads and sends the video as fast as possible, causing buffering and disconnects. Always include-reto read at real-time speed. - Wrong playlist syntax. The file must have
file 'name.mp4'lines. If you have spaces or special characters, use proper escaping. - Using the wrong stream key. Double-check that you copied the full RTMP URL. A typo will cause immediate connection errors.
- Not setting
-stream_loop -1. This makes FFmpeg loop the playlist forever. Without it, the stream stops after the last video. - Ignoring the bitrate. If your upload bandwidth is lower than the bitrate you set, the stream will lag or drop. Test your upload speed and adjust
-b:vaccordingly.
Tips
- Use a lower resolution for stability. If your course videos are 1080p, consider scaling to 720p to reduce CPU load and bandwidth. Add
-vf scale=1280:720before the output. - Add a fallback image. If a video fails to decode, FFmpeg might stop. You can add
-f lavfi -i color=c=black:s=1280x720:r=30as a fallback, but it’s complex. Simpler: ensure all videos are in the same format and codec. - Keep your videos in one folder. Avoid mixing formats; convert them all to MP4 (H.264/AAC) for maximum compatibility.
- Set a keyframe interval. The
-g 50option sets a keyframe every 2 seconds (at 25fps). This helps viewers join mid-stream without long buffering. - Use a named pipe for live updates. If you want to change the playlist without restarting, you can use a named pipe, but that’s advanced. For most, restarting the service with updated files is fine.
Troubleshooting
- Stream shows “No signal” or black screen. Check the FFmpeg log for errors. If it says “Connection refused”, your stream URL/key is wrong. If it says “Broken pipe”, the server disconnected you, often due to bitrate spikes. Lower the bitrate and try again.
- Stream stops after a few minutes. This is usually a network issue. Check your upload speed and ensure it’s stable. Also, check if your VPS provider has bandwidth limits. Try reducing the bitrate or using a smaller resolution.
- FFmpeg says “No such file or directory” for playlist. Make sure the working directory is correct and the path in
-iis right. Use absolute paths like-i /home/user/course/playlist.txt. - Video and audio out of sync. This can happen with
-reif the source files have variable frame rates. Re-encode your videos to a constant frame rate first, or add-vsync cfrto the command. - CPU usage is too high. Use a faster preset like
-preset ultrafast(at the cost of quality) or reduce the resolution. Also, consider using hardware encoding if your CPU supports it (e.g.,-c:v h264_vaapion Intel). - Stream works but has frequent buffering for viewers. Increase the keyframe interval (
-gto 100) and ensure your bitrate is not too high for your viewers’ connections. Also, check that your upload speed is consistent.
Frequently Asked Questions
- Can I run this on a Raspberry Pi? Yes, but encoding 1080p may be too heavy. Use 720p and the
ultrafastpreset, or use hardware encoding if available. - How do I update the course videos? Stop the service (
sudo systemctl stop course-stream), replace the files, update the playlist, then start it again. The stream will go offline briefly. - What if my platform requires a specific resolution or bitrate? Check your platform’s recommended settings. For YouTube, 1080p at 4500kbps is common. Adjust the
-b:vand add-vf scale=1920:1080if needed. - Can I stream audio only? Yes, remove the
-c:voptions and just encode audio. But most language courses benefit from video. - How do I add a live intro or outro? You can concatenate an intro video before the playlist by adding it as the first line in the playlist, or use a complex filter. Simpler: create a combined video with your intro and the course.
- Will this work if my server restarts? If you use the systemd service, it will start automatically on boot. If you used
nohup, you’ll need to run it again manually.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- Fix Device Manager Not Opening in Windows 11
- How to Pause Snapchat Location
- System Restore Points Missing in Windows? Fixes
- Loop Nature Ambience Videos with FFmpeg on Ubuntu
- Install League of Legends on Linux: Full Guide
- Fix Error 0x80070001: Causes & Solutions