A Docker container can run FFmpeg to send an ordered sequence of video files to a YouTube live ingest. That describes a possible workflow, not a validated deployment recipe: compatibility, credentials, network access and recovery all need to be checked for your setup.
For an always-on channel, a looping option alone is not enough. You also need an eligible YouTube channel, media that behaves correctly when concatenated, a suitable output protocol, and a way to notice when the feed or the process stops behaving as expected.
What this setup does—and does not guarantee
Think of the system as several separate pieces. Docker provides an environment in which an FFmpeg process can run; the process reads your media and sends an encoded feed to YouTube. YouTube receives that feed and associates it with a live stream and, where applicable, a broadcast event. Each piece has its own configuration and failure modes.
A container being in a running state does not prove that YouTube is receiving usable video. FFmpeg may have stopped advancing through the playlist, the output connection may have failed, the stream key may be wrong, or the input files may have incompatible timestamps. Likewise, a healthy preview at launch does not establish that the feed will stay healthy overnight.
Docker can make the runtime environment more repeatable, but it does not make a playlist compatible or remove the need to monitor the host and network. A restart policy may restart a process after it exits; it cannot correct a revoked credential, a malformed playlist, or an encoder configuration that YouTube rejects. Keep process recovery and stream health checks as distinct jobs.
Google’s documentation distinguishes the liveStream resource, which holds feed configuration, from a liveBroadcast, which represents the event viewers watch. Its guide to broadcasts and streams describes a 24/7 feed as a case where a stream resource can be reused. Do not assume that every encoder restart requires a newly created stream resource; follow the state and instructions shown in your YouTube workflow.
Plan for ordinary failures: host or power loss, a network interruption, a stopped process, a missing source file, or a YouTube-side issue. Decide who will notice, how they will check the state, and what they should do next. If you are choosing between running the process yourself and handing off continuous playback, the trade-offs in cloud hosting for a YouTube replay channel may help frame that decision.
Configure YouTube Live and obtain ingest details
Before configuring FFmpeg, check whether the channel is currently eligible to stream live. YouTube Help says the channel must be verified and must not have had live-streaming restrictions in the preceding 90 days. Requirements and account status can change, so check the current status in YouTube Studio’s Live Control Room rather than treating an old checklist as proof of eligibility. See YouTube’s live streaming encoder guidance for its current account and setup notes.
In Studio, create or select the stream workflow you intend to use and locate the encoder’s ingest URL and stream key. The exact fields and choices depend on the workflow presented to your channel. YouTube describes a stream key as functioning like a password and address: treat it as a credential, not as ordinary configuration text.
Do not bake the key into an image, commit it in a Compose file or source repository, paste it into a public issue, or leave it in a command transcript that others can read. Restrict access to wherever your runtime configuration is stored, and rotate or replace the key if you believe it has been exposed. A custom key may be reusable, but reuse does not make it public or remove the need to protect it.
The encoder feed and the viewer-facing event are related but not identical. A persistent stream resource can receive a feed while a broadcast has its own testing and live states. In practice, use the Live Control Room to check which stream and broadcast are selected and what state YouTube reports. Do not infer that a successful network connection alone means the public event is live.
Keep a private record of which channel, stream selection, and media playlist belong together. This is useful when several channels are operated from the same host, but the record should identify the credential location rather than reproduce the key. Before a launch, confirm the selected ingest details against the current Studio screen; copied values from a previous setup can point to the wrong stream.
Choose a Docker and FFmpeg workflow
At a high level, the container needs access to the FFmpeg executable, the playlist text file, and every media file named by that playlist. It also needs permission to read those files and outbound network access to the chosen YouTube ingest. A mounted directory or volume is a common way to make host files available inside a container, but confirm the path mapping and permissions for your own Docker arrangement rather than assuming a sample path will work unchanged.
Treat the image, FFmpeg build and runtime configuration as a set you must verify. The build needs the demuxer, encoders and output protocol you plan to use. FFmpeg options can vary by build, and exact option ordering and output URL syntax depend on the input and selected output path. Consult the documentation for the installed build and inspect its available options; the FFmpeg command-line documentation is a starting point, not evidence that a particular container image contains a particular feature.
The FFmpeg -stream_loop -1 option is documented as looping one input indefinitely. That fact does not make it a complete playlist solution, nor does it prove that a Docker command will publish successfully. Decide whether your input is one file to loop, a concat-demuxer list, or another playlist mechanism, and verify that the chosen method actually advances through your intended sequence.
Keep the runtime configuration legible. Separate media location, playlist location, output protocol and secret handling so an operator can identify which part needs attention without exposing the key. If you change the image or FFmpeg version, recheck the build’s capabilities and do a controlled test before relying on it for an unattended channel.
A process supervisor or Docker restart policy can be part of recovery, but neither is a health monitor by itself. Define what counts as a healthy feed: a live process, fresh frames in YouTube’s preview, acceptable audio and video, and a connection that remains active. Arrange an alert or a scheduled human check if nobody is watching the Live Control Room continuously. For playlist operations, ways to diagnose a schedule that misses a video offer useful questions to ask when the sequence is not what you expected.
Prepare media files before building the sequence
The concat demuxer is a packet-level joining method, not a universal media converter. FFmpeg documents that its inputs need matching streams, codecs and time bases for this method. Files exported from different devices or editing projects can differ in resolution, frame rate, audio arrangement, codec or timing even when they all have familiar file extensions.
Inspect each candidate file before putting it into a long unattended sequence. Compare the streams and their relevant properties, and play the files through their beginning and end. An input that plays normally by itself can still create a discontinuity when joined to a differently encoded file. Look for unexpected silence, an image-size change, a frozen ending frame, or a sharp audio transition.
When inputs do not meet the concat demuxer’s constraints, do not assume FFmpeg will silently make them equivalent. You may need to re-encode them into a common format or use a filter-based concat workflow. Which route is suitable depends on your source files and the output you intend to produce; the reviewed concat-demuxer documentation does not establish one universal normalization command.
Duration and timestamp behaviour deserve particular attention. The demuxer adjusts timestamps so that each input follows the preceding one, but unequal audio and video lengths can leave gaps. Incorrect or unavailable duration estimates can create timestamp errors or visible and audible artefacts. If you know a file’s accurate duration and the demuxer needs it, the concat list supports a duration directive; verify the value rather than inserting a guess.
Use a short test sequence containing the transitions most likely to expose trouble: a file from a different source, a clip with a different audio layout, and the transition from the final item back to the first. Review the result in YouTube’s preview as well as locally. If it is important to preserve a smooth opening, also check whether the first file begins with black or silence. Advice on black gaps between promotional videos can help you think through transition symptoms, even though your Docker workflow is not OBS.
Build and order the playlist
The concat demuxer reads a text list containing one file directive for each input, then presents those inputs successively as though their packets had been muxed together. If you use a format header, FFmpeg requires the first line to be exactly ffconcat version 1.0. Paths must resolve from the process’s point of view inside its runtime environment, not merely from the host’s file browser.
Write the sequence in the order you want viewers to see it, and check every entry for spelling, case and path. A file that is present on the host but absent at the path visible inside the container is still unavailable to FFmpeg. Keep a copy of the intended playlist with the media set, and record when you change its order so an operator can distinguish a content change from a playback fault.
A simple list does not itself guarantee a seamless loop. First establish that each adjacent pair is compatible for packet-level concatenation. Then test the end-to-start transition if the sequence is intended to repeat. The final clip may finish with a different timestamp pattern, audio duration or picture state from the first clip, so listen and watch across the join rather than checking only the individual files.
If the files have missing or inaccurate durations, the concat demuxer’s timestamp adjustment can produce gaps or artefacts. Use a duration directive only when you have a reliable duration for the corresponding file and understand how that information affects the sequence. A guessed duration can trade one timing problem for another. Record any correction and retest the transitions it affects.
For a long-running channel, make playlist changes in a controlled way. Prepare and inspect a revised list, confirm the referenced media is available, and decide how the running process will pick up the change. Do not assume that editing a text file will alter a sequence already being read by a running FFmpeg process. A restart to load a new list may interrupt the feed, so choose a suitable change window and verify the return to the expected preview. If files need replacing while a stream continues, the operational questions in replacing videos in a live church playlist are relevant to planning, though the exact behaviour depends on your own playback method.
Choose an ingest protocol
Choose the output protocol based on what your FFmpeg build supports and what the YouTube workflow presents for the stream. YouTube’s Live API lists RTMP, RTMPS, HLS and DASH ingestion types. Their address structures and requirements are not interchangeable; do not assume that one URL or output configuration works for every protocol. The Live Streams API reference describes ingest types and stream configuration.
For ordinary creator content where lower latency matters, YouTube describes RTMPS as a suitable choice. RTMPS is RTMP carried over SSL; YouTube’s encoder guidance specifies the rtmps protocol, a valid YouTube endpoint and connection over port 443. Confirm the actual endpoint and key in your stream setup rather than copying a URL from an unrelated example. Lower latency does not remove the need to monitor connection and media quality.
HLS is a more specialised segment-based option, not a synonym for a local .m3u8 input playlist. The source playlist format and the protocol used to send output to YouTube are separate decisions. YouTube’s HLS ingest requirements include muxed audio and video, H.264 or HEVC video, AAC audio, closed GOP, and media segments no longer than five seconds. The guide recommends segments from one to four seconds and notes trade-offs: smaller segments can reduce latency while increasing rebuffering risk and reducing encoding efficiency.
HLS generally has more latency than RTMP and WebRTC according to YouTube’s guide. That may be acceptable for a channel where viewers mainly watch a continuous loop, but it can matter when you need near-real-time interaction. DASH is also documented as an ingest type, but choose it only if your encoder and the selected YouTube workflow support the relevant output details. Check the current primary documentation for the protocol-specific rules before building around it.
Avoid choosing a protocol solely because an input file or playlist uses a familiar extension. Confirm both ends: the local FFmpeg build can produce the intended output, and YouTube’s configured ingest accepts it. If the two sides disagree, a process that appears to start may not create the preview you expect.
Start the encoder and inspect stream health
Begin with a controlled test, not a promise of continuous service. Use a short private or unlisted broadcast where appropriate, inspect the YouTube preview, and verify that the expected file appears with both picture and sound. Check transitions between files and the loop point if you intend the list to repeat. Resolve warnings or unexpected gaps before treating the playlist as ready for unattended use.
While the feed runs, check YouTube’s Live Control Room for its status and preview. YouTube advises checking the preview and continuing to monitor audio and video quality. Look for fresh frames, stable audio, missing segments, frozen pictures, black gaps and any mismatch between the intended playlist and what viewers receive. A running container is only one observation; it is not a substitute for the platform-side check.
Also monitor the process and its host. Decide how you will detect an exited FFmpeg process, a lost network connection, insufficient file access or a host that has stopped. A restart policy may help recover from a stopped process, but it cannot determine whether the restarted feed has the correct key or is producing valid frames. After a restart, check the preview and confirm that playback resumes from an acceptable point in the sequence.
For a channel operating through the night, make the checks actionable: name the person or system responsible for noticing a failure, define where they will look first, and keep a concise recovery note that does not expose credentials. Include the selected stream, media directory, playlist version, expected protocol, and steps for checking YouTube’s reported state. Do not call the arrangement uninterrupted; make clear what is monitored and what still requires intervention.
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
Can I run FFmpeg in Docker with my computer switched off?
Yes, if the container runs on a host that remains powered on and connected to the network. Docker on a laptop that you shut down cannot continue sending the feed; the host is part of the operating plan.
Does -stream_loop -1 loop a whole playlist?
FFmpeg documents this option as looping one input indefinitely. Do not treat that as proof that it loops a concat list in the way you intend; choose the playlist method deliberately and test the sequence and its end-to-start transition.
Why are there gaps between concatenated files?
The concat demuxer expects matching streams, codecs and time bases, and timing problems can arise when audio and video lengths differ or durations are wrong. Inspect and normalise incompatible sources, check duration information, and review the transitions in a test feed.
Does a container restart mean the YouTube stream is healthy again?
No. A restart can bring the process back, but it does not establish that YouTube accepts the feed or that fresh audio and video are arriving. Confirm recovery in the Live Control Room preview and check the process and network separately.