A CSV playlist cannot be passed straight to FFmpeg as a sequence of sermons. First parse its rows into the text format used by FFmpeg’s concat demuxer, check every path and media file, then send the resulting input to a YouTube Live event using the event’s own ingest details.
The commands and examples below are starting points, not tested against your church’s files or computer. File formats, path syntax, installed FFmpeg builds and YouTube event settings vary, so validate each stage and check the Live Control Room preview before relying on the stream.
Check the CSV fields and media paths
Start by opening the CSV in a spreadsheet or text editor and identifying what each column means. A church’s file might contain columns such as title, file, and order, but treat those as illustrative names: your actual headers, delimiter and quoting rules may be different. Confirm whether the file is comma-separated or uses another delimiter, whether paths are relative to the CSV’s folder, and how rows with blank fields should be handled.
Decide which field holds the media path and how the intended playing order is represented. If the CSV is sorted by a service date or a numeric order field, write down the rule and check the resulting sequence manually. Spreadsheet display order is not necessarily the same as the order a script will read rows in, particularly if someone has sorted the sheet or inserted a header or notes row.
For each usable row, check that the referenced file exists, can be read, and is the sermon you expect. A path that is technically valid but points to a different recording is still a playlist error. Keep the CSV and its media in a stable location while the event runs; moving or renaming a file after creating the concat list can make its entry fail.
Also confirm that the church has permission to stream the recording, including any music, images or other material within it. This is an editorial and rights check for your organisation, not something a file-path check can settle. Keep a copy of the original CSV unchanged and work from a separate generated playlist so that corrections are reversible.
Why CSV is not concat syntax
FFmpeg’s concat demuxer accepts a text playlist in its own format. A CSV is a table with delimiters, rows, headers and potentially quoted fields. Those conventions do not automatically become concat instructions just because a column contains filenames. FFmpeg’s documentation describes the concat demuxer and its expected file-list syntax in the concat demuxer reference.
In a concat list, a basic entry looks like file 'media/sermon-01.mp4'. The demuxer reads entries consecutively; it does not look at a CSV’s header and infer which column to use, how to sort rows, or whether a cell is a valid path. The conversion step is therefore where you apply the church’s chosen column and ordering rules, reject incomplete rows and produce a separate plain-text file.
This distinction matters for safety as well as correctness. Do not paste raw CSV cell contents into a shell command or treat the CSV as trusted script text. A path can include spaces or punctuation, and badly handled quotes can change how a generated list is read. Use a CSV-aware parser, validate its values, and then escape each accepted path according to concat-list syntax.
The demuxer’s safe-path mode is enabled by default and rejects some paths considered unsafe. FFmpeg documents those restrictions in its safe option reference. Keeping the default is preferable when your directory layout permits it. -safe 0 accepts any filename, so it broadens what the playlist can open; it is not a fix to apply blindly to unreviewed CSV contents.
Convert rows into an FFmpeg concat list
After deciding the field and order rules, generate a new text file from the validated rows. For example, if a parser has confirmed two files and both are inside a media folder beside the playlist, the output could look like this:
ffconcat version 1.0
file 'media/sermon-01.mp4'
file 'media/sermon-02.mp4'
The first line must be exactly ffconcat version 1.0 and be the first line when relying on automatic format recognition. Do not include a spreadsheet header, commas, row numbers or explanatory comments copied from the CSV. Keep this as a generated text file, for example sermons.ffconcat, and retain the source CSV separately for editing.
The example only illustrates the target syntax. It does not show a complete CSV parser, and it should not be used as a substitute for one if your data includes paths with apostrophes, backslashes, embedded newlines or other unusual characters. CSV quoting rules and concat-list quoting rules are different. A parser must first decode the CSV cell correctly; a second step must then encode the path correctly for FFmpeg’s list format.
Relative paths are usually easier to review when the list and media folder have a predictable relationship. If you choose absolute paths, test how your FFmpeg build handles them under safe mode before preparing the live run. Do not turn off safe mode simply to make a generated list work without understanding why it failed and constraining the accepted input paths.
The concat demuxer is a finite sequence: it reads the entries and reaches the end. It does not automatically loop the playlist or watch the CSV for new rows. If you need a repeating channel, that requires an explicitly designed and tested wrapper or another workflow. For an FFmpeg loop setup, see this guide to looping a YouTube Live stream from a VPS; a loop around an input is a separate operating decision from converting a CSV.
Validate filenames, quoting and ordering
Before connecting to YouTube, inspect the generated list as plain text. Compare every file entry against the CSV rows you intended to include. Check that the first and last sermons are right, that no row is duplicated or omitted, and that each path resolves from the working directory you will use to launch FFmpeg. If an entry contains whitespace or quotes, test it with a small local playback attempt rather than assuming the visible text is valid.
A useful validation pass has two levels. First, check the list syntax and paths: the header, one entry per intended file, correct escaping, and no unexpected lines. Then inspect representative media files with FFmpeg’s probing tools or another media inspector. Compare stream count and types, codecs, time bases, dimensions, frame rates and durations. The concat demuxer expects compatible streams across files; the fact that two files both end in .mp4 does not establish that compatibility.
The demuxer uses file durations when placing later timestamps. If durations are inaccurate, gaps or audio/video artefacts can result. Keep the source files unchanged during the stream, and do a local test long enough to cross at least one transition between files. Listen for audio continuing cleanly and check that the next sermon starts at the intended point.
When the sources have matching streams, codecs and time bases, stream-copy may be possible, which avoids re-encoding. If they differ, do not assume that forcing them into a single concat list will make them compatible. FFmpeg’s concat FAQ explains the distinction between the concat demuxer and the concat filter: the filter can be used when re-encoding is needed. That path requires choosing consistent output parameters and testing the result, because it adds processing time and can affect image or sound quality.
If files have different audio layouts, frame rates or dimensions, make a normalised test output before the live event. Decide on a common frame size, frame rate, video and audio codec, and audio layout appropriate to the material and YouTube’s current requirements. Keep an untouched copy of each original. The right settings depend on your source and event; there is no single stream-copy command that can be declared correct for every church archive.
Create the YouTube Live event and retrieve ingest details
In YouTube Studio, create or schedule the Live event and open its Live Control Room settings. Retrieve the stream URL and stream key shown for that event. YouTube describes these details in its encoder setup instructions. Use the actual endpoint provided to you rather than copying an example address from a tutorial; event and account settings determine what you should send to.
Treat the stream key as a password. YouTube’s live stream settings guidance describes stream keys as the password and address for a stream. Do not place a real key in a public script, repository, screenshot, shared document or article. Limit access to the people who need to operate the event, and regenerate the key through YouTube if it has been exposed.
Check that the channel is currently eligible before the day of the service. YouTube’s live streaming eligibility page says channels need verification and must not have a live-streaming restriction in the preceding 90 days; it also states a minimum age of 16 to live stream. Account rules can change, so check the official page and the channel’s own Studio status rather than treating an old successful stream as proof of current eligibility.
Where the event offers RTMPS, use the endpoint YouTube supplies. RTMPS is RTMP protected by TLS/SSL, and YouTube recommends it in its ingestion protocol guidance. Confirm whether the URL shown includes a path or other details that belong with the key. Do not guess how to append or separate values: follow YouTube’s event settings and test the exact combination you will use.
Configure FFmpeg for the playlist
There are two broad choices after creating the input list. If the files are compatible, you may be able to copy their streams without re-encoding. If they are not, you may need to decode and encode a normalised output, using a concat-filter workflow or preparing a single compatible file before streaming. These approaches have different CPU, setup and quality trade-offs. Probe and test before selecting one.
The command below is a shape for an illustrative stream-copy case, not a verified command for your files or FFmpeg build. It uses shell variables so that the endpoint and key are not printed directly into the example. The way an installed FFmpeg build accepts or combines those values depends on the exact URL provided by YouTube and the build, so verify the form against your event settings before use.
export YT_INGEST_URL='paste the event endpoint from YouTube here'
export YT_STREAM_KEY='paste the event key here'
ffmpeg -re -f concat -safe 1 -i sermons.ffconcat \
-c copy -f flv "${YT_INGEST_URL}/${YT_STREAM_KEY}"
Do not assume the placeholder URL construction is appropriate for every event. In particular, inspect whether your event endpoint already contains a path or expects the key in a particular part of the URL. Keep the resulting command private, avoid shell history or shared logs that could reveal the key, and unset the variables when finished. A secured environment or local configuration mechanism can be preferable to typing a secret into a command line, depending on the operating system and tools available.
The example’s -c copy only makes sense if the files are compatible with each other and with the output protocol and YouTube’s requirements. If the sources do not match, replace it with a tested encoding configuration rather than layering arbitrary flags onto the command. YouTube’s current encoder settings guidance recommends constant bitrate and a two-second keyframe interval, and says not to exceed four seconds. It lists H.264 and AAC or MP3 for RTMP/RTMPS, with up to 60 fps; check its resolution-specific bitrate table and current requirements for your source instead of treating one bitrate as universal.
For a straightforward SDR sermon feed, H.264 video and AAC audio are a reasonable example to test, not a guarantee of compatibility or quality. Match the output to the source material and YouTube’s current format guidance. A re-encoding workflow must explicitly set compatible video and audio parameters and be tested for CPU load, sync and image quality before a service.
Allow upload capacity beyond the total stream bitrate, as YouTube recommends, since other traffic on the same connection can reduce usable headroom. Consider a wired network connection where practical and avoid large uploads or backups competing with the stream. You still need a person responsible for observing the broadcast; leaving an FFmpeg process running is not the same as confirming that viewers are receiving useful audio and video.
Test playback and troubleshoot failures
Run a local test of the playlist before sending it to YouTube. Confirm that every sermon opens and that transitions do not introduce silence, black video, unexpected pauses or out-of-sync sound. A playlist can parse successfully yet fail later because a file is missing, a codec differs, or a duration is incorrect. Test more than the first file, especially the transition into a later recording.
For the live test, start the event as directed in Live Control Room and check its preview before making it public or announcing it. Confirm both audio and picture, check the event title and visibility, and make sure the feed is not stuck on a slate or the first frame. YouTube’s stream health tips cover checking the preview and monitoring stream quality. Arrange for an operator to watch the event and know how to stop FFmpeg, correct a failed input, and restart or reschedule if needed.
If FFmpeg reports that it cannot open a file, verify the exact path, working directory, filename case and permissions. If it reports a safe-path issue, review why the path is being rejected and whether a relative path inside a controlled media folder will work; do not immediately use -safe 0 against data that has not been checked. If the generated list has incorrect quoting, correct the parser’s output and retest locally.
If the connection is rejected, check that the endpoint and key correspond to the active event and were copied accurately. Keep the key private while troubleshooting. If the key was exposed in logs or a screenshot, replace it in YouTube Studio rather than sharing it again for diagnosis. For a separate example of a rejected-key problem, this stream key troubleshooting guide discusses the key-and-ingest side of the issue; the network and encoder in your setup may differ.
If playback reaches the end of the list, that is expected behaviour for a finite concat playlist. It will not advance to new CSV rows or restart by itself. Decide in advance whether the event is meant to end there or whether an operator or tested scheduling method will begin another sequence. For continuity planning when a connection drops, see this guide to keeping a church stream running through an internet drop; it does not remove the need to test your own connection and recovery steps.
YouTube says streams under 12 hours are automatically archived in its encoder setup guidance, but do not rely on that statement as a promise for every account or event. Check current account and event settings and confirm the archive afterwards. Your own process should also account for what happens if the stream stops, stalls or reaches the playlist’s end; neither the concat demuxer nor an untested command guarantees uninterrupted streaming or automatic archive behaviour in every circumstance.
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
How do I make FFmpeg read a CSV playlist?
FFmpeg’s concat demuxer does not directly interpret arbitrary CSV columns. Parse the CSV with a CSV-aware tool, validate the rows and paths, and write a separate concat-format text list with one file entry per item. Then test the generated list locally before streaming.
Can I use absolute paths or turn off safe mode?
Absolute paths may work, but test them with your installed FFmpeg and keep the inputs constrained to files you have checked. Safe mode is enabled by default; -safe 0 accepts any filename, so only consider it where your workflow genuinely requires it and you understand the broader access it permits.
Do all the sermons need to have the same format?
For concat-demuxer stream-copy workflows, the files need compatible streams, codecs and time bases. If they differ, test a normalisation or re-encoding workflow using FFmpeg’s concat filter or prepare a common-format file first. Different formats are not made compatible merely by listing them in the same text file.
Will the playlist repeat or recover if FFmpeg stops?
No: a concat list is finite and does not itself loop, add new CSV rows or restart a stopped process. Repetition and recovery need a separate, explicit workflow and an operator who can check that the event is actually healthy. Test that plan before using it for a service.