Skip to content
streamneo.
Setup Guides14 min read

How to Automate YouTube Live Playlist Rotation with Python on Ubuntu in India

A practical Ubuntu guide to coordinating YouTube Live broadcasts with Python and rotating local video files through FFmpeg.

sn.
StreamNeoPublished 7 October 2026
Worth sharing?

Python can manage YouTube Live broadcasts, while FFmpeg or another encoder plays the video files and sends the live feed. To rotate local videos, build a workflow that coordinates these separate jobs; a YouTube channel playlist does not become the live stream’s media source automatically.

On Ubuntu, the practical path is to validate a fixed media list, configure YouTube API access, start FFmpeg with the channel’s current ingest details, and supervise the process. Test file transitions and recovery on your actual channel before relying on the arrangement overnight.

Separate broadcast management from media playback

Think of the setup as two connected but distinct parts. A YouTube liveBroadcast is the event viewers watch; a liveStream represents the audio-video feed sent to YouTube. The Live Streaming API can create or select these objects, associate a broadcast with a stream, and manage broadcast state. It does not read your videos or decide which file plays next.

A media process does that work. FFmpeg can read local files in sequence and encode or pass their audio and video to YouTube’s ingest service. Python can coordinate the pieces: validate a list, make API calls, launch FFmpeg, record its exit status and decide whether to restart it. Keep these responsibilities visible in your code and operational notes. An API call succeeding does not prove that the media is playing, and a running FFmpeg process does not prove that YouTube has accepted a healthy feed.

This distinction also explains why a normal channel playlist is not enough. A playlist on YouTube organises uploaded videos for viewers; it is not automatically fetched as the content source for a live broadcast. If your goal is to play multiple videos in a YouTube live stream, you must provide the media feed through an encoder or another playback system.

Google’s overview of live broadcasts and streams describes the two API concepts and their relationship. Its documentation says that a broadcast is a distinct video and that a stream can be reused for broadcasts at different times. Decide whether each rotation should be part of one continuous live event or whether you intend to schedule separate events; these are different broadcast-management choices, not playlist settings.

Prepare Ubuntu and Python

Start by choosing where the media and the long-running process will live. A local Ubuntu machine is straightforward to inspect, but it must remain powered on, connected, and available for the duration of the broadcast. A rented or managed machine can stay online when your home computer is off, but adds storage, access, and ongoing administration decisions. Neither arrangement makes the stream immune to network, process, or ingest interruptions.

Install FFmpeg from an Ubuntu-supported package source or use a deliberately pinned build that you understand how to maintain. Check the installed version and its local manual before copying commands from online examples: the FFmpeg website documents current revisions, and options may differ from a distribution package. Python should likewise be installed and maintained in a project environment rather than mixed with system packages. Record the versions you test, so a future package update is not an invisible change to a working rotation.

The Python program will need Google’s API client libraries if it is to manage broadcasts, as well as standard facilities to read files, start subprocesses and write logs. Pin and review the client version used by your implementation. Keep API code separate from the FFmpeg command construction: this makes it easier to diagnose whether a failure is authentication, broadcast state, input media or process startup.

Before spending time on automation, confirm that live streaming is enabled for the specific YouTube channel and that you can access the intended stream settings in YouTube Studio. Availability depends on the channel and YouTube’s current requirements; do not assume that location alone establishes eligibility. For a channel in India, the workflow is not a special India-only API procedure. Use UTC timestamps in API requests and confirm the channel’s current settings directly in YouTube’s official interface.

If the machine will be in India, account for practical constraints such as local power interruptions, the reliability of its network route to YouTube ingest, and where the video files are stored. These are operational checks, not a promise that a particular broadband plan or hosting location will work. If you are weighing a hosted machine against running at home, the considerations in Indian cloud services for always-on YouTube streaming may help frame the storage and administration trade-offs.

Create and validate the video rotation list

Make a dedicated directory for media and a plain text file that lists the files in the order you want them played. FFmpeg’s concat demuxer reads a list of files sequentially. In a simple list, entries use the file directive followed by a path; consult the FFmpeg concat demuxer documentation for the exact syntax and escaping rules. Paths containing unusual characters or quotes deserve particular care.

Have Python validate the list before starting playback. Check that it is not empty, that each referenced path exists and is a regular file, and that the process can read it. Reject unexpected paths rather than silently skipping them. Log the resolved file names in order, but do not put credentials in those logs. If you generate the list from a directory, use a deliberate sort order instead of assuming that filesystem order is stable. A list that changes between runs should be reviewed before it is used for a public broadcast.

Compatibility matters. The concat demuxer expects inputs with the same streams, codecs and time base for reliable stream joining. Differences in audio layout, frame characteristics, codec parameters or timing can cause transition problems, and inaccurate duration information can produce artifacts or gaps. A stream-copy approach can avoid re-encoding, but it is not a universal fit for mixed files.

Choice What it changes When it may fit What to check
Concatenate compatible files without re-encoding Lower processing work, but inputs must match closely A prepared set exported with consistent settings Stream layout, codecs, time bases and reported durations
Normalise or transcode files first More preparation and processing, with a consistent output format A rotation assembled from varied source files Test the chosen output against the channel’s current ingest configuration
Fixed list for one run Predictable order; changes usually require a planned restart or new process A stable daily or devotional sequence How the running FFmpeg process handles the list and where restart gaps occur
Supervisor-controlled list changes More control over when new media enters rotation A schedule that changes at known times Explicitly test how the supervisor stops, updates and restarts playback

Do not treat editing a text file as a live playlist update. The documentation establishes sequential reading of a list, not that an already-running process will reload arbitrary edits. For a predictable first version, prepare a fixed list, start a new run from it, and test the time and behaviour of any planned restart. If you need files to change during the day, implement and test that control as an explicit supervisor feature.

For an example of the media-side trade-offs in a different format, see the guide to a scheduled looping video stream. It is useful context, but your actual file compatibility and transition behaviour still need to be checked locally.

Configure YouTube API access and broadcast workflow

Use OAuth for an account authorised to manage the intended channel. Google’s liveBroadcasts.insert reference lists the OAuth scopes accepted for write operations, including YouTube scopes; use the scope appropriate to the actions your program performs. A client ID is not a substitute for an authorised user session. Store downloaded credentials and refresh tokens in a protected location, restrict access to them, and exclude them from source control and routine diagnostic output.

The common workflow is to select an existing liveStream or create one, create a liveBroadcast with its title, scheduled start time and privacy status, and bind that broadcast to the stream. Google’s implementation guide lays out this sequence. You can also manage an existing or scheduled broadcast rather than creating a new one each time; first inspect its state and stream association rather than making assumptions about what is active.

A scheduled start time must be in the future, so generate it deliberately and send a UTC ISO 8601 timestamp. Keep the request’s privacy setting and title explicit. The API can return errors if required fields are absent, authorization is insufficient, or live streaming is not enabled for the channel. Record the API error details safely and use them to diagnose the failing request; do not respond to an error by repeatedly inserting new broadcasts without checking what was already created.

After binding, verify that the broadcast is associated with the intended stream. Then start the media feed and inspect the stream’s status and health. Google’s Python client reference calls out checking that the bound stream is active before attempting a transition to testing. Transitioning to testing or live is a broadcast-state action, not a way to start FFmpeg. Perform it only when you have confirmed the correct event and an active incoming feed.

A single stream may be reused for broadcasts at different times. Google documents that one stream can be bound to up to three broadcasts; this is a contextual API limit, not a reason to bind unrelated events casually. Keep an inventory of which broadcast is bound to which stream and unbind or manage events according to the intended schedule. For a simple always-on channel, distinguish carefully between one long-running event and multiple scheduled events before writing automation around transitions.

Keep the stream key separate from the source code, API credentials and playlist. Pass it to the media process through a protected runtime configuration, and avoid printing the full command if it contains the key. Anyone who obtains a stream key may be able to send a feed to that stream, so rotate it through the channel’s controls if it has been exposed. A valid API token and a stream key solve different problems: one authorises API requests, the other authenticates the encoder’s feed.

Run FFmpeg as the media feed

Build the FFmpeg command from the verified file list and the channel’s current ingest endpoint and stream key. Do not copy a universal resolution, bitrate, transport protocol or ingest address from a tutorial: these depend on the media and the channel’s current ingest configuration. Follow YouTube’s current official live encoder settings guidance and verify the settings shown for your own stream.

A concat input is one way to tell FFmpeg to read files sequentially. Whether you use stream copy or re-encode, test the exact command with representative files. Stream copy can fail to produce the intended result when inputs are not compatible; re-encoding adds processing work and requires suitable settings for the machine and ingest. Check that both audio and video are present, that transitions occur as expected, and that the output remains stable for longer than a brief launch check.

Use Python’s subprocess facilities to start FFmpeg as a child process and capture its standard output and error in a rotating or otherwise bounded log. Avoid shell-string construction from untrusted file names; pass arguments as a structured list and validate paths first. Capture the process identifier and exit code, and send a graceful stop signal as part of planned shutdown. Leave enough information in logs to identify the last file and time of failure without exposing the key or OAuth secrets.

Storage choice affects how playback behaves. Local files avoid dependence on a remote mount during each read, but require enough local capacity and a process for replacing media safely. Network-mounted media can simplify central updates, yet the stream then depends on that mount remaining reachable and fast enough when files are read. No general performance or reliability figure applies to every local disk, network or Ubuntu machine, so test the arrangement you will operate.

If your operational pain is keeping a home computer available solely to feed a prerecorded channel, StreamNeo can take away that particular need by running an uploaded video as a YouTube live stream while your computer is off. It is a separate managed workflow, not a replacement for the Python/API design described here, and it is YouTube-only.

Supervise playback and handle failures

A supervisor should have a clear, limited job: start the media process, observe whether it exits, record what happened and apply a documented recovery decision. It should not assume that a successful process launch means the audience sees healthy video. Check both FFmpeg’s output and YouTube’s stream status or health before deciding that the feed is ready for a broadcast transition.

For an unexpected exit, log the timestamp, exit status, last useful diagnostic lines and the current broadcast state. Decide whether a restart is safe and appropriate. Add a retry limit or a back-off policy, and alert a person when repeated failures need inspection. An endless tight restart loop can obscure the original problem and may repeatedly send a broken feed. If the input list changed, confirm whether the next process should use the old validated snapshot or a newly validated version.

The failure cases are different enough to keep separate in logs and runbooks:

  • API request rejected: check OAuth authorisation and scope, required fields, the requested schedule and whether live streaming is enabled.
  • Feed not active: inspect FFmpeg diagnostics, ingest settings, stream key handling and YouTube’s stream status before transitioning the broadcast.
  • Artifacts at file boundaries: compare input stream layouts, codecs, time bases and durations; prepare a normalised set if needed.
  • Unexpected process exit: record the exit code and relevant error output, then use a bounded restart policy and alerting.
  • New media does not appear: confirm whether the running process reads a static list and whether your supervisor has actually performed a tested restart.

Do not claim uninterrupted playback merely because a process manager is present. A supervisor can notice some failures and attempt recovery, but it cannot prevent all machine, network, file, API or YouTube-side interruptions. Document what it detects, what it restarts, what requires human attention, and what viewers may experience during a restart. The guide on audio continuing after a video freezes is relevant when diagnosing a mismatch between the feed you intended and what appears in the player.

For a long-running channel, write down a maintenance routine as well as a launch command. Include where the current media list lives, how to stage replacement files, how to validate a new set, where non-secret logs are kept, and how to stop the process cleanly. Keep a known-good list and a way to revert to it. A rotation that works only when its original author remembers undocumented steps is difficult to operate safely after a failure.

Test the live rotation

Test in stages rather than discovering every problem in a public overnight run. First validate the list and play the files locally through the intended FFmpeg input path. Check that each transition has the expected picture and sound, then confirm the process exits or loops as designed. Try a representative file with a different duration or audio layout if your real library contains that variation; the point is to expose compatibility differences before the feed is relied on.

Next, check the API workflow without making an unintended public event. Confirm the authorised channel, stream selection, broadcast details, scheduled UTC time and binding. Use the available testing state when appropriate, and verify the active stream before a live transition. Confirm that the event selected in YouTube is the one your automation expects. Remove or reschedule test events deliberately rather than leaving ambiguous upcoming broadcasts behind.

Then exercise supervision. Stop FFmpeg deliberately during a controlled test and observe what the Python process records and does. Confirm that a restart uses the intended list, that credentials do not appear in logs, and that repeated failure produces an alert rather than an unbounded loop. Test a list update using the exact restart or rotation procedure you intend to use; do not infer live reload behaviour from the fact that a text file changed.

Finally, leave a controlled stream running long enough to observe real file boundaries and the machine’s behaviour. Check YouTube’s preview and stream health, not just local FFmpeg output. Record the exact Ubuntu, Python and FFmpeg versions, command options, file set and observed symptoms. This is not a guarantee of later uptime: it is a reproducible baseline that helps you recognise what changed after an upgrade or media replacement.

If the channel publishes devotional or regional-language programming, make the order understandable to the person who will maintain it. A dated list or a small schedule document can explain when aarti, bhajan, announcements or ambience segments should appear without embedding that editorial meaning in fragile code. For more channel-level planning, see building a 24/7 Malayalam lofi radio channel; the operational lesson is to keep the programme order and the technical feed process understandable as separate things.

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

Does the YouTube API play videos from my channel playlist?

No. The API manages broadcast and stream objects; it does not fetch playlist items and supply them as the live media feed. An encoder such as FFmpeg must read and send the media, or you need another playback workflow that produces the feed.

Can I edit the concat list while FFmpeg is running?

Do not assume that changing the text file changes a process already reading it. Treat the list as the input for a run, then implement and test a deliberate stop, validation and restart procedure if you need to rotate new files.

Do I need a different workflow because my channel is in India?

The reviewed API workflow is not India-specific. Confirm live-streaming access and current settings on the actual channel, use the channel’s ingest configuration, and send scheduled API times in UTC rather than assuming a local-time interpretation.

Will a Python supervisor keep the stream uninterrupted?

No. It can detect process exits, log them and attempt a bounded recovery, but it cannot guarantee that the machine, network, ingest or YouTube remains available. Test the exact media, process and recovery procedure and plan for alerts and manual intervention.

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 ↗