A useful health check for a 24/7 YouTube FFmpeg stream needs to inspect both the machine running FFmpeg and the stream YouTube receives. A process that still exists is not proof that data is reaching YouTube, so keep local and remote checks separate.
Your monitor should report what it knows, what failed and what it could not check. That distinction helps you avoid restarting a healthy encoder because an API request failed, or assuming viewers have a working stream because FFmpeg is still running.
Decide what “healthy” means
Think of stream health as several observations, not one green light. Locally, you want to know whether the expected FFmpeg process is present and whether its output or media pipeline is making progress. Remotely, you want to know whether YouTube is receiving data and what its health checker says about the incoming feed. The viewer-facing broadcast has its own lifecycle as well.
These checks answer different questions. A process check sees the encoder on your host. A local progress check can reveal a process that is present but stalled. The YouTube Live Streaming API reports platform-side state for the incoming stream and broadcast. None of those individual observations proves every other layer is working.
| Check | What it can tell you | What it cannot establish alone |
|---|---|---|
| FFmpeg process | Whether the expected process appears to be running | Whether it is producing usable output or YouTube is receiving it |
| Local progress or output | Whether the invocation appears to be advancing locally | Whether YouTube accepted the feed or viewers can watch the broadcast |
YouTube liveStream |
Whether YouTube reports receiving data and what its health status says | Whether the local process is healthy or the broadcast is in the intended lifecycle state |
YouTube liveBroadcast |
Whether the viewer-facing event is in a lifecycle state such as live | Whether the source process will continue running |
Build separate states into the check result. For example: process_missing, no_local_progress, api_unavailable, stream_inactive, health_bad, health_unknown, and remote_receiving. A small report with distinct conditions is more useful than a single boolean that prompts the same response to unrelated problems.
If you are still setting up the encoder, the guides to streaming a continuous YouTube playlist with FFmpeg and looping multiple prerecorded videos from a VPS cover the upstream setup. Monitoring starts after that stream has been configured; it does not repair a bad source playlist or incorrect key.
Check that FFmpeg is present and progressing
Start with the process that should be serving the channel. On a Linux host, a service manager such as systemd can supervise a named FFmpeg service and record exit status and logs. If you launch FFmpeg another way, use an equivalent supervisor that can identify the intended process, rather than searching for any process named ffmpeg and treating it as the right one.
Process presence is a narrow signal. FFmpeg can remain present while the input is stalled, the output is blocked, or the connection to the ingest endpoint has failed. Capture evidence of progress from the actual invocation: for instance, inspect its logs or a local output/progress signal that advances as media is processed. The specific method depends on how you run FFmpeg and which build and options you use, so validate it on the host rather than assuming a generic command fits.
Keep the process identity and its logs together. If the check reports that FFmpeg is absent, include the service name, last exit status and a short log excerpt or log location. If FFmpeg is present but no progress signal has changed, report that as a different condition. A human can then distinguish a crash from a stall, and a restart policy can be tied to the failure it is designed to address.
Avoid declaring failure from a single brief gap unless your use case supports that decision. Your source may legitimately pause or take time to initialise, and logs may be buffered. Choose a persistence window appropriate to the way your invocation behaves, document the reason for it, and tune it by observing normal runs. YouTube does not prescribe an FFmpeg process threshold or restart interval.
A useful baseline is to verify the monitor itself while the channel is running normally: confirm that it identifies the intended service, sees progress, records logs and can report a deliberate stop as missing. Do not infer that local success means the public stream is healthy. It is simply the first layer of evidence.
Verify local output continues
A progress check should reflect work in the FFmpeg pipeline, not merely the age of a PID file or the fact that a log file exists. Depending on the setup, that could be a changing progress record, a changing output file where appropriate, or regular, meaningful status output from the process. The check should be designed around the actual command and media path.
For a live output sent directly to YouTube, there may not be a convenient growing local video file. In that case, use a signal from the encoder invocation or a local diagnostic appropriate to your setup. Confirm that it changes during a normal run and stops changing when you intentionally interrupt or stall the relevant part of the pipeline. This is a test of your monitor design, not a claim that one universal FFmpeg metric proves successful delivery.
The local check can also flag obvious source problems: missing media, repeated decode errors, or an input that has stopped advancing. Read enough of the logs to retain the relevant error text and timestamp. A counter alone is less useful if it cannot tell you whether the issue concerns the source, encoder or output connection.
There is a trade-off between a simple monitor and a detailed one. A basic service supervisor is easy to maintain, but may only act when FFmpeg exits. A progress-aware check can detect a process that is alive but stalled, but needs a signal that is reliable for your chosen FFmpeg invocation. Start with the smallest signal you can validate, and make its limitations explicit in the alert.
If your channel plays a playlist, test the boundary between files as well as a steady segment. A source may appear healthy while the current item plays, then fail when the next file is missing or unreadable. The advice on recovering a stream when a playlist source file is missing is relevant to that separate failure mode.
Query YouTube’s incoming stream resource
The remote check uses YouTube’s liveStream resource. YouTube documents this resource as the incoming feed, with status fields for stream state and health. Read the API’s current LiveStream resource reference before implementing the query, since your code needs valid credentials and the right resource identifier.
The key distinction is status.streamStatus. The documented values are active, created, error, inactive and ready. In this context, active means YouTube is receiving data via the stream. ready is not the same thing: it means the stream has valid CDN settings, not that data is currently arriving. Likewise, created and inactive are not interchangeable with an active incoming feed.
Retain the entire relevant status response, not just a translated label. In particular, keep status.healthStatus, its update time and configuration issues. A monitor that stores the raw or structured fields gives you enough context to revisit an alert after YouTube changes state, and helps explain why a remote result differed from the local one.
This query is about the stream, not necessarily the event the audience sees. YouTube represents the viewer-facing event separately as a liveBroadcast. A broadcast can have lifecycle states such as ready, liveStarting, live or complete, among others. See the LiveBroadcast resource reference for the documented lifecycle. Add a broadcast query if you need to know whether the event is in the intended state; do not substitute it for the incoming stream check.
For a read-only monitor, keep the API work to retrieving status and reporting it. YouTube documents the liveBroadcasts.list method, including the status part and owner filtering, in its method reference. The reference lists youtube.readonly among accepted scopes. Confirm the scope and account permissions for the resources you are querying, and treat authorisation or eligibility errors as API-check failures rather than as stream-health results.
Interpret receiving state and health issues
streamStatus and healthStatus describe related but distinct things. The first helps answer whether YouTube says it is receiving data. The second reports what YouTube knows about the stream’s configuration health. Preserve both in your output so a good-looking configuration does not conceal an inactive feed, and an active feed does not conceal a reported configuration problem.
YouTube documents health status values of good, ok, bad and noData. good means there are no issues at warning severity or worse; ok means there are no error-severity issues; bad means at least one issue has error severity. noData means the backend has no information about the stream’s health status. Treat noData as unknown, not as a healthy result.
The health object can include lastUpdateTimeSeconds and a configurationIssues list. An issue can carry a type, severity, reason and description. Include the individual issue details in logs or alerts; “bad” alone does not tell you what to investigate. Check the resource reference for the meaning and fields of these values, and use YouTube’s descriptions as diagnostic clues rather than as a guarantee that a particular fix applies to your encoder.
The timestamp matters. A previously good health value may be old, so your monitor should report its age and decide whether it is fresh enough for your own operational needs. The API documents the timestamp field but does not define a universal freshness window. Choose and label a deployment-specific threshold; do not present it as a YouTube requirement.
If an API request fails, the result is not inactive, bad or good. It is an unavailable or failed check. Network trouble, expired credentials, insufficient permissions and an actual ingest issue need different responses. Keep the response code or error message where safe to do so, and alert on persistent API failures as monitoring visibility problems rather than restarting FFmpeg automatically.
Keep broadcast state in its own lane
A channel operator often cares about both ingestion and what viewers can see. YouTube’s liveBroadcast resource covers the event lifecycle; liveStream describes the feed. The distinction is useful when a feed is active but the event is not in the state you intended, or when the broadcast lifecycle is changing while the encoder is running.
For example, a transition to testing or live requires the bound stream to be active, according to YouTube’s transition documentation. See the liveBroadcasts.transition method for prerequisites and error conditions. A monitor that only reads state does not need to perform transitions. If you later automate state changes, treat that as a separate, authorised operation with its own safeguards.
Do not turn a broadcast state into a proxy for process health. A live broadcast does not tell you whether FFmpeg will remain up, and an FFmpeg process does not establish that YouTube has the event in the expected lifecycle state. Report the local, stream and broadcast observations side by side when all three matter.
Alert first, then choose recovery
Separate detection from remediation. A missing FFmpeg process may be a reasonable candidate for supervisor restart, subject to your chosen retry policy. A process that is present without progress needs investigation or a carefully bounded response. YouTube reporting an inactive or error stream should prompt inspection of encoder logs and ingest connectivity. A bad health status should carry the issue description and severity. noData or a failed API request should be labelled unknown, not treated as proof that the stream is down.
An automatic restart can interrupt a stream that was recovering or cause repeated reconnects if the underlying source, network or configuration problem persists. Before enabling it, define what qualifies as a failure, how long that condition must persist, how many attempts are allowed in a period, what delay or backoff applies, what gets logged, and when a person is alerted. These are operator choices: YouTube does not prescribe a restart policy or monitoring threshold.
Do not make every failed API call trigger a restart. A credential problem does not improve when FFmpeg is restarted, and an API outage can make the remote state unknown while the encoder continues normally. Keep API alerts separate from local process recovery. If the check cannot distinguish a real ingest failure from an unavailable query, stop short of automated remediation and notify an operator.
Test the response path deliberately. Stop the service in a controlled window, confirm the local check reports the right condition and verify that any allowed restart is logged. Separately, simulate or inspect an API failure without stopping FFmpeg and ensure the monitor reports the API issue rather than calling the stream inactive. Do not test disruptive broadcast transitions on a live audience merely to exercise a read-only monitor.
If the main operational burden is keeping a computer awake, the encoder and its local checks are still another thing you must supervise. StreamNeo addresses that specific burden by letting you upload a video and run it as a YouTube live stream without keeping your own computer on; for an FFmpeg host you control, the layered monitor above remains the relevant way to distinguish local and YouTube-side status.
Put the checks into a useful operating routine
Choose a polling cadence based on how quickly you need to know about a failure and the cost of repeated API requests. The official references describe resources and methods, not a universal polling interval for this use. Make the cadence visible in configuration, avoid overlapping requests if a previous query has not completed, and handle rate or authorisation errors as their own conditions.
Each report should include a timestamp, channel or resource identity, local process state, local progress result, API request result, streamStatus, health status, health update time, and relevant issue details. If you also inspect the broadcast, include its lifecycle state separately. This record lets you see whether a fault began locally or remotely and whether an alert was based on fresh data.
Use a small state model that prevents a single failure from erasing other evidence. For instance, if the API is unavailable but local progress continues, report “local progressing; YouTube state unknown”. If FFmpeg is missing while the last API result is active, report the local failure and label the remote result with its observation time. A remote status is a snapshot, not a guarantee about what is happening now.
Review alerts after normal operations and after actual interruptions. Remove checks that produce noise without guiding an action, and add detail where the operator cannot tell whether to inspect the source, encoder, credentials or broadcast configuration. For channels run by a small team, include enough context in the alert that the person on call can act without first finding the script author.
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 an FFmpeg process check prove YouTube is receiving my stream?
No. It only tells you about the process on the machine you are checking, and a present process can be stalled or disconnected. Query the YouTube liveStream status separately; YouTube documents active as receiving data via the stream.
What is the difference between ready and active?
ready means the stream has valid CDN settings, while active means YouTube is receiving data via it. Do not report ready as proof that an encoder is currently sending a feed.
Should noData health status trigger a restart?
Not by itself. YouTube defines noData as having no health-status information, so report the remote health as unknown and inspect the other signals. A failed API request is also not the same as a confirmed inactive stream.
Should the script restart FFmpeg automatically?
Only after you have defined a bounded policy for a specific failure, such as the supervised process exiting. Keep API failures and unknown remote states separate from local process recovery, and log attempts and alert a person when the policy reaches its limit.