AppleCreek Livestream Switcher WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
WordPress plugin that automatically switches a YouTube embed between live stream, upcoming stream and fallback playlist.
Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/xxxcb/church-livestream-switcher/releases/download/v1.9.1/church-livestream-switcher.zipWordPress plugin that automatically switches a YouTube embed between:
- live stream
- upcoming stream
- fallback playlist
The switch is controlled by schedule windows so API checks only happen when needed.
Features
- Weekly schedule windows (
day + start + end) - One-time event windows (
date + start + end) - Timezone-aware window matching
- Supports public and unlisted embeddable streams
- Detects live and upcoming from your channel uploads
- Fallback to playlist when no live/upcoming stream is found
- Separate shortcode for YouTube live chat
- Auto-return to playlist when a live video ends
- Built-in caching to reduce quota usage
- Low Quota Mode for safer defaults
- Global plugin enable/disable switch (no API calls when disabled)
- Tabbed admin settings (General, Updates, Options, Player Appearance, Scheduling, Live Chat)
- Chat visibility toggle for upcoming streams
- Extensive player appearance and YouTube embed parameter controls
- Advanced custom embed query parameter override
- Modular file layout (bootstrap, includes, templates)
- REST status endpoint for frontend switching and diagnostics
How It Works
The frontend shortcode calls:
/wp-json/church-live/v1/status
Backend flow:
- Check if plugin is enabled.
- Check if current time is inside a weekly or one-time window.
- If outside window, return playlist mode (no YouTube API calls).
- If inside window, use cached result if available.
- If cache miss, call YouTube Data API v3:
channels.listto get uploads playlist IDplaylistItems.listto get recent video IDsvideos.listto detect live/upcoming status
- Cache result and return status JSON.
Frontend then switches iframe source:
live_videoorupcoming_video-> embed that video- everything else -> fallback playlist
Requirements
- WordPress site with this plugin activated
- YouTube channel ID (
UC..., not handle format) - YouTube Data API v3 key
- Fallback playlist ID (recommended)
GitHub Updates
This plugin can self-update from GitHub Releases.
- Open
Settings -> AC Livestream -> Updates. - Turn on
Enable GitHub updates. - Set
GitHub repoasowner/repo. - Optional:
- Add
GitHub tokenfor private repos or higher rate limits. - Enable prerelease updates if desired.
- Set
Release asset filenameif your release includes multiple ZIP files.
- Add
- Publish releases with tags like
v1.7.0(or1.7.0).
Notes:
- If no asset filename is set, updater picks the first
.zipasset, then falls back to GitHub zipball. - WordPress checks plugin updates on its normal schedule; cache TTL controls GitHub metadata refresh.
Project Structure
church-livestream-switcher.php: plugin bootstrap/header + class loaderincludes/class-church-livestream-switcher.php: core logic (settings, API calls, schedule logic, shortcode data prep)templates/admin/settings-page.php: admin settings HTML/JStemplates/shortcodes/video.php: video embed HTML/JStemplates/shortcodes/chat.php: chat embed HTML/JS
Installation
- Put the plugin folder in
wp-content/plugins/church-livestream-switcher. - Activate Church Livestream Switcher in WordPress plugins.
- Open Settings -> AC Livestream.
- Configure all required fields.
- Place shortcode on a page:
[church_livestream]- Optional:
[church_livestream height="480"] - Chat:
[church_livestream_chat] - Optional chat attrs:
[church_livestream_chat height="600" offline_message="Chat is available during live services."]
Shortcodes
Video
[church_livestream]- Optional:
height(pixels, overrides Player Appearance fixed height)
Live Chat
[church_livestream_chat]- Optional:
height(pixels, minimum240, default600)offline_message(text shown when no live/upcoming stream is active)
Chat behavior:
- Uses the same status endpoint and polling interval as the video switcher
- Always shows chat for
live_video - Optionally shows chat for
upcoming_video(controlled byShow chat for upcoming) - Shows offline message outside window / when not live / when plugin is disabled
- Makes no status fetch calls when global
Plugin enabledis off
Video appearance behavior:
- The new
Player Appearancetab controls wrapper styling + embed parameters. - A shortcode
heightattribute, when set, overrides the fixed-height setting. - Inner YouTube UI (inside iframe) is still controlled by YouTube and cannot be fully re-skinned.
Settings Reference
-
Tabs:
General: global plugin state and YouTube identifiersUpdates: GitHub release-based plugin updatesOptions: quota/performance controlsPlayer Appearance: iframe/container style + YouTube embed paramsScheduling: weekly windows, one-time events, import/exportLive Chat: chat-specific behavior
-
Plugin enabled- Global on/off switch.
- Off = no live checks, no API polling, playlist only.
-
Timezone- Used for weekly and one-time windows.
- Example:
America/Toronto.
-
YouTube Channel ID- Must be channel ID (
UC...).
- Must be channel ID (
-
Playlist ID (fallback)- Used outside windows and whenever no stream is found.
-
YouTube Data API Key- Required for live/upcoming detection.
- UI now masks saved value; leave input blank to keep current key.
- Use
Clear saved API keycheckbox to remove it.
-
Backend cache TTL (seconds)- How long status result is cached during active windows.
-
Low Quota Mode- Enforces safer runtime minimums/caps:
- Backend cache TTL >= 600s
- Front-end refresh >= 300s
- Uploads playlist cache TTL >= 604800s (7 days)
- YouTube search fallback cache TTL >= 1800s
- Lookback count <= 10
- Enforces safer runtime minimums/caps:
-
Front-end refresh (seconds)- How often browser checks status endpoint.
-
Lookback count- Number of recent uploads scanned.
-
Uploads playlist cache TTL (seconds)- How long uploads playlist ID is cached.
-
Show chat for upcoming- When enabled, chat appears for
upcoming_video. - When disabled, chat appears only for
live_video.
- When enabled, chat appears for
-
UpdatestabEnable GitHub updatesGitHub repoinowner/repoformatGitHub token(optional)- UI masks saved token; leave blank to keep existing token.
- Use
Clear saved GitHub tokencheckbox to remove it.
Include pre-releasesUpdate metadata cache TTL (seconds)Release asset filename(optional exact ZIP name)
-
Player Appearancetab- Container/frame style:
Player max widthAspect ratioFixed height (px)(0keeps responsive ratio mode)Border radius,background,box shadow- Wrapper class and iframe class hooks
- Iframe title, loading mode, referrer policy, allow permissions, allowfullscreen
- YouTube playback/embed controls:
controls,autoplay(live + playlist separately),mute(live + playlist separately)loop,rel,fs,modestbranding,disablekb,playsinlineiv_load_policy,cc_load_policy,colorstartseconds,endsecondshl,cc_lang_preforiginmode (auto,off,custom) + custom origin URLAdvanced custom query paramsfor additional/override URL params
- Container/frame style:
-
Weekly Schedule Windows- Day + start + end.
- Supports overnight windows (end earlier than start).
-
One-time Event Windows- Date + start + end.
- Supports overnight windows (end earlier than start).
Window Logic Notes
- If both weekly and one-time lists are empty, plugin treats this as "always in window."
- If any one-time event window matches now, stream checks are allowed.
- If weekly window matches now, stream checks are allowed.
- Otherwise status returns playlist mode without API calls.
Import / Export JSON
Export includes both collections:
{
"schedule": [
{ "day": 0, "start": "09:30", "end": "13:00" }
],
"one_time_events": [
{ "date": "2026-12-24", "start": "18:30", "end": "21:00" }
]
}
day mapping:
0Sunday1Monday2Tuesday3Wednesday4Thursday5Friday6Saturday
REST Endpoint
Status
GET /wp-json/church-live/v1/status
Typical response:
{
"inWindow": true,
"mode": "live_video",
"videoId": "abc123"
}
mode values:
live_videoupcoming_videoplaylist
Debug Mode
GET /wp-json/church-live/v1/status?debug=1
Debug mode includes backend error details and bypasses status cache.
Use only for short troubleshooting sessions. Repeated debug calls can increase quota usage.
YouTube API Key Setup (Important)
This plugin calls YouTube from your server (PHP), not browser JavaScript.
Use these steps:
- Open Google Cloud Console.
- Create/select a project.
- Enable YouTube Data API v3.
- Create an API key.
- Set restrictions:
API restrictions: YouTube Data API v3Application restrictions:- Production: IP addresses (your server egress IP)
- Local testing: None (temporary) is simplest
Do not use HTTP referrer restriction for this plugin.
Why
Server-side requests usually have no browser referrer header, which causes:
Requests from referer <empty> are blocked.
Quota Best Practices (10,000 units/day default)
- Keep schedule windows tight (only around service times).
- Enable Low Quota Mode.
- Keep one-time events only for real special dates.
- Avoid running
debug=1continuously. - Keep plugin disabled when not needed using
Plugin enabled.
Low Quota Mode keeps status results cached for at least 10 minutes and caches expensive YouTube search.list fallback results for at least 30 minutes. This is intentionally less immediate, but it sharply reduces repeated 100-unit search calls during long schedule windows.
Recommended values if not using Low Quota Mode:
- Backend cache TTL:
600 - Front-end refresh:
300 - Lookback count:
8-10 - Uploads playlist cache TTL:
604800
Quota Exceeded Behavior
When YouTube returns quotaExceeded, the plugin backs off by caching playlist fallback until next Pacific midnight (or current cache TTL, whichever is longer).
This prevents constant retries and additional quota waste.
Troubleshooting
Requests from referer <empty> are blocked
Cause:
- API key restricted by HTTP referrer.
Fix:
- Use server-compatible key restriction (
IP addressesor temporaryNone) and keep API restricted to YouTube Data API v3.
quotaExceeded
Cause:
- Project daily quota exhausted.
Fix:
- Wait for reset at midnight Pacific.
- Or test with a different Google Cloud project.
- Avoid repeated debug endpoint calls.
inWindow: false while service is active
Check:
- Correct timezone
- Correct day/time schedule
- One-time event date/time if using one-time windows
Playlist shows unrelated recommendations after stream ends
The plugin now listens for player ended state and switches back to playlist immediately.
If you still see unrelated content, verify fallback Playlist ID is set correctly.
Plugin not switching at all
Check:
Plugin enabledis on- API key and channel ID are set
- Stream is embeddable and public/unlisted
- Stream falls within schedule/one-time window
Version
Current plugin header version: 1.7.1
Releases
24 releases. Each count is every asset in that release; expand a row for the breakdown.