Skip to content
streamneo.
Setup Guides12 min read

How to Run an FFmpeg Playlist Script at Boot for YouTube Live in India

Set up an FFmpeg playlist as a Linux systemd service, protect your YouTube key and check what boot-time restarts can and cannot do.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

To start an FFmpeg playlist automatically after a Linux reboot, run it as a systemd service with a known user, absolute file paths and a carefully protected YouTube stream key. Enabling the service starts the process at boot; it does not guarantee that the broadcast stays healthy or becomes one uninterrupted YouTube stream.

The setup below is a template, not a universal unit: the right command depends on your files, FFmpeg build, distribution and network. YouTube says streams under 12 hours are automatically archived, so plan around its documented behaviour rather than promising that one broadcast will run indefinitely.[^1]

Check the playlist and FFmpeg command

First confirm what you mean by “playlist”. An FFconcat file lists separate media files for FFmpeg to play in sequence. A single video repeated is a different input arrangement. Do not copy a command for one case into the other without checking the options for your installed FFmpeg version and testing how it transitions.

For a concat playlist, a small text file might look like this:

ffconcat version 1.0
file '/srv/youtube/media/clip-01.mp4'
file '/srv/youtube/media/clip-02.mp4'

FFmpeg’s concat demuxer presents the files as a virtual sequence. Its inputs should have compatible stream layouts, codecs and time bases. Differences in duration metadata can produce timestamp problems, gaps or visible and audible artefacts at joins. Check the files before relying on them overnight; a clean transition in a short manual test is more useful than assuming similarly named files are encoded alike.[^2]

A representative command for video and audio sent over RTMPS has this general shape:

/usr/bin/ffmpeg -re -f concat -safe 0 -i /srv/youtube/playlist.ffconcat \
  -c:v libx264 -preset veryfast -b:v 14M -maxrate 14M -bufsize 28M \
  -g 60 -keyint_min 60 -sc_threshold 0 \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv 'RTMPS_URL_WITH_STREAM_KEY'

This is not a drop-in recipe. For example, YouTube Help's current encoder guidance recommends 14 Mbps for H.264 at 1080p/30 fps and 17 Mbps for H.264 at 1080p/60 fps, as listed on YouTube Help's site in September 2026.[^3] The example's video settings therefore need to match the target resolution and frame rate, the input media and what your upload connection can sustain. These H.264 values are not recommendations for every codec or every connection.

YouTube recommends constant bitrate (CBR) and a two-second keyframe interval, which should not exceed four seconds. Its guidance covers different codecs and output formats, so consult the current encoder settings and bitrate table for your chosen combination rather than treating one row as a general answer. Test with media that resembles the real stream in motion and sound; a static image with no audio will not reveal all the problems in a music or video loop.[^3]

Before service setup, run the command manually from the intended directory and verify that FFmpeg can read every file and publish to the correct YouTube stream. Get the publishing URL and key from Live Control Room, and use RTMPS where available. YouTube’s encoder setup instructions explain how to retrieve the stream details.[^1] Do not paste a real key into an example, a public script repository or a command that you plan to share.

Use absolute paths and a working directory

A command that works in your terminal can fail at boot because systemd does not inherit your interactive shell's current directory, aliases, environment variables or login setup. A relative input such as playlist.ffconcat may resolve somewhere other than you expect. Specify the full path to the FFmpeg executable and playlist, and set the unit's working directory explicitly.

For example, /usr/bin/ffmpeg and /srv/youtube/playlist.ffconcat are absolute paths; ffmpeg and playlist.ffconcat are not. The paths here are illustrations. Find the actual FFmpeg location on your system, then use directories that exist and are readable by the service account. The WorkingDirectory setting can make the process's starting location predictable, but it does not replace absolute paths in the command.

Decide who should run the process. A dedicated, unprivileged account such as streamer limits what a compromised process can access compared with running it as root. That account must be able to traverse the directories and read the playlist and media files. If your distribution or storage layout uses different ownership or access controls, adjust those deliberately rather than loosening permissions across the whole media directory.

This distinction matters if your files are on a mounted disk or network share: the service can start before a resource is ready, or its account may lack access even though your login can see the files. Check how your system mounts that storage and whether the service must wait for it. For background on the trade-offs of keeping playback on your own hardware, see running a 24/7 stream from a Raspberry Pi in India. A local machine may suit a small setup you already maintain; it also means you are responsible for its power, network and storage being available.

Keep the YouTube stream key out of public logs

Treat the stream key like a password: anyone who can publish with it may be able to send content to your stream. Do not put a real key in a public article, shared source file, world-readable service unit or screenshot. Also be cautious about passing it directly as a command-line argument, because process information and diagnostic output can expose command details to users with access to the machine.

A practical approach is to keep secrets in a root-owned configuration file with restrictive permissions, or use another secret mechanism supported and understood on your distribution. Have the service read the publishing URL and key through that mechanism. The exact integration is system-specific; verify who can read the secret, how it is loaded, and whether errors or debugging tools could print it. Avoid copying unredacted service output into a public support post.

Systemd's EnvironmentFile= can supply environment variables to a service, but it is not a complete secret-management solution by itself. Limit file access and understand the local security model before relying on it. Be especially careful not to put a key in a unit that is shared with other users or backed by a public repository. YouTube explains that you can reset a compromised key in Live Control Room; after rotation, update the protected configuration and restart the service.[^4]

A useful operational habit is to keep the playlist and service definition shareable, while keeping credentials separate. That makes it easier to review paths and codec settings without exposing the ability to publish. When troubleshooting, redact the RTMPS destination and key before sharing logs or configuration; a partially hidden key is still not a reason to publish the rest of a sensitive URL.

Create a systemd service unit

Create a service file only after you have tested the command and settled the paths, account and secret-handling method. The example below shows the shape of a unit, not a universal unit. The actual ExecStart needs to match your media and protected key setup; do not copy the placeholder destination and assume it will work on your machine.

[Unit]
Description=YouTube Live FFmpeg playlist
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=streamer
Group=streamer
WorkingDirectory=/srv/youtube
ExecStart=/usr/bin/ffmpeg -re -f concat -safe 0 -i /srv/youtube/playlist.ffconcat -c:v libx264 -c:a aac -f flv <protected-rtmps-destination>
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Replace the account, group, working directory, input, output and encoding options with your own. The network-online.target ordering is a request to start after the network-online target, not proof that YouTube is reachable or that your connection can sustain the selected bitrate. How that target is implemented varies by distribution. Likewise, multi-user.target is a common system target, but confirm the appropriate target and unit conventions for your Linux installation.[^5]

Restart=on-failure tells systemd to restart the service when its process exits unsuccessfully. RestartSec= adds a delay before the next attempt. These settings can help after a crash, but they are not stream monitoring: FFmpeg may remain running while the output is frozen, badly encoded or rejected by YouTube. systemd also applies start-rate limiting, so repeated immediate failures are not an endless-retry guarantee.[^5]

FFmpeg's FIFO muxer offers a separate option for recovering from network output problems, but its recovery behaviour must be configured and attempt_recovery is disabled by default. It is not automatically enabled by using systemd, and you should test any such configuration with your installed FFmpeg build before relying on it.[^2] If managing FFmpeg's recovery behaviour is not a fit for your maintenance capacity, a hosted workflow can remove the need to keep your own computer running; StreamNeo removes that specific burden by letting you upload a file and leave your computer switched off while the YouTube broadcast runs.

If you are deciding whether to maintain an FFmpeg setup or use a different playback workflow, the practical differences are the control you need, who looks after the running process and how much time you can spend diagnosing failures. The comparison of self-hosting with OBS and a 24/7 streaming service may help frame that choice without changing the systemd steps here.

Enable the service at boot

Once the unit file is saved in the location your distribution expects, reload systemd's unit definitions, enable the unit, and start it. A common lifecycle uses systemctl daemon-reload, followed by systemctl enable --now your-service.service. Check the command syntax and unit-file location for your system before using them. Enabling configures boot activation; starting requests an immediate run, so enable --now does both.

Then inspect the service with systemctl status your-service.service. If it has failed, do not keep restarting it without reading the reason. Use journalctl -u your-service.service to inspect its journal, taking care not to copy unredacted secrets into a public post. A successful status only tells you about the local service process; it does not prove that YouTube is receiving a healthy stream.

The key test is a real reboot. A manual systemctl start from an existing login may succeed because your shell has access to files or mounts that are unavailable at boot. Reboot when you can observe the machine, then check that the service starts, the intended media is being read and the stream appears in Live Control Room. If the machine is unattended, arrange a safe way to inspect it after this test rather than assuming that a service enabled once will never need attention.

If you are working with a remote host, keep access to its console or recovery route in mind before changing boot behaviour. A broken unit can repeatedly fail without taking down the operating system, but a locked-down or remote-only machine can still be awkward to troubleshoot. For a Hindi music channel specifically, compare the file-sequence approach with the workflow in how to loop Hindi songs from a VPS in India; use it as a point of comparison, not as a substitute for testing your own files and service.

Check reconnects and YouTube stream status

After startup, check two different things: whether systemd has a running process, and whether YouTube reports a healthy incoming stream. In Live Control Room, review stream health and confirm that the video and audio look as intended. If the process is active but YouTube receives nothing, examine the journal, permissions, input paths, FFmpeg options, URL and key. A valid systemd status is not an end-to-end test.

A restart policy handles some process exits; it cannot diagnose every stall or repair every publishing problem. If FFmpeg exits with a network error, a restart may reconnect, but repeated failures may also run into systemd's rate limits. An open process with no useful output needs a different check. Consider how you will notice a bad stream and what you can do about it while away from the machine, rather than treating automatic restart as proof of unattended reliability.

YouTube documents that streams under 12 hours are automatically archived.[^1] This does not mean that a service restart will create one uninterrupted broadcast, nor does it establish a guaranteed hand-off or archive outcome for every longer-running arrangement. If a channel needs regular new broadcasts, plan and test the transition in Live Control Room instead of inferring that a boot service controls YouTube's archive behaviour.

The local network is another variable, not an India-specific encoder setting. Select a bitrate for your actual codec, resolution and frame rate, then assess whether the available upload link can sustain it reliably. YouTube recommends testing upload bitrate and its encoder page gives the settings to match the target.[^3] If the stream disconnects from a VPS, the VPS RTMP troubleshooting guide is a relevant next step; a local Linux host may have different routing and access issues.

Choose a playlist shape and operating host

The word “playlist” can hide two separate jobs: joining multiple files and repeating a single asset. The concat demuxer is for an ordered set of files. Repeating one file uses a different FFmpeg input pattern, whose exact option should be verified against your installed build and tested at the transition. Neither arrangement should be assumed to run as an endlessly uninterrupted YouTube broadcast.

Approach Suits Check before relying on it
FFconcat list of local files Playing several prepared clips in order Compatible streams, codecs and time bases; duration metadata and transitions
One file repeated A channel built around a single source asset The installed FFmpeg loop option, audio/video join and observed YouTube stream status

For either approach, inspect the actual media rather than judging it only by filenames. A playlist with mismatched audio sample rates or video parameters can behave differently at joins than a continuous encoded file. Listen across a transition and watch it long enough to see whether timestamps remain sensible. If the content is a devotional programme or local news loop, check that the sequence returns to its start as you expect and that an editorially important segment is not accidentally omitted.

Your host choice is also a maintenance choice. An existing Linux computer may be convenient if it has reliable power, storage access and outbound capacity, but it remains dependent on that machine and connection. A remote VPS shifts where the process runs; it does not remove the need to check bandwidth, routing, provider policy, storage and service behaviour. A hosted file-to-live workflow is another fit when you do not want to maintain a running computer. Compare the options against who will respond to an outage and what control you need over the encoder.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

Linux reboot ke baad FFmpeg live stream apne aap kaise start ho?

Create a systemd service with the correct user, absolute paths and a protected way to provide the publishing credentials, then enable it for the appropriate boot target. Test it after a real reboot and check both the service journal and YouTube Live Control Room; boot activation alone does not confirm a healthy stream.

FFmpeg playlist ko YouTube par 24/7 kaise chalayein?

Use the right input pattern for your content: an FFconcat list for separate files, or a separately verified loop setup for one file. Build in monitoring and a recovery plan, and remember that YouTube says streams under 12 hours are automatically archived; do not promise that one broadcast will continue uninterrupted beyond documented behaviour.

Why does the service work manually but fail at boot?

A login shell may have a different working directory, permissions, environment or mounted storage than the system service. Set absolute paths and a working directory, check that the service account can read the media, and inspect the unit journal for the actual failure.

Does Restart=on-failure guarantee that YouTube will reconnect?

No. It can ask systemd to restart a process after certain failures, but it cannot establish that the stream is healthy while FFmpeg remains running, and retry attempts are subject to systemd limits. Check YouTube's stream health and test your recovery behaviour under realistic conditions.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗