=== iReplay TV Channel and Radio Station ===
Contributors: ireplaytv
Tags: tv channel, radio station, live streaming, linear tv, FAST
Requires at least: 5.9
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 1.0.14
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Turn your WordPress site into a 24/7 TV channel or radio station. Upload your videos, we turn them into a live linear broadcast.

== Description ==

iReplay TV Channel and Radio Station lets you create live, linear TV and radio channels from your video and audio content. Upload your media, and the plugin turns it into a 24/7 broadcast-style stream that viewers can tune into at any time.

**How it works:**

1. Create a channel (WebTV or WebRadio)
2. Upload video or audio files
3. Files are transcoded into HLS format
4. A 24/7 schedule is generated automatically
5. Embed the player on any page with a shortcode

**Key features:**

* Create WebTV (video) and WebRadio (audio-only) channels
* Weighted random scheduling for varied programming
* HLS adaptive bitrate streaming (1080p, 540p, audio-only)
* Now-playing display with live program info
* Chunked file upload for large media files
* Dashboard with channel stats and viewer counts

**Shortcodes:**

* `[irptvcr_tv_player channel="my-channel"]` - Embed a 24/7 channel video player
* `[irptvcr_radio_player channel="my-radio"]` - Embed a 24/7 channel audio player
* `[irptvcr_vod_player asset_id="42"]` - Embed a single asset for on-demand playback (with seek)

= Third-Party Service: iReplay.TV =

**This plugin relies on the iReplay.TV external service for core functionality.** The following data is transmitted to iReplay.TV servers:

**Connections made to iReplay.TV (`https://ireplay.tv/api/wp/`):**

* **Site registration** - Your site URL, WordPress version, and plugin version are sent when you first configure API credentials.
* **Heartbeat** - Every 5 minutes, the plugin sends a heartbeat with your plugin and WordPress versions to confirm the site is active.
* **Channel management** - When you create, update, or delete channels, channel metadata (name, handle, description, language) is synced to iReplay.TV.
* **Transcoding** - When you upload media, the source file URL is sent to iReplay.TV for transcoding. Transcoded segments are pushed back to your WordPress server.
* **Schedule sync** - Every hour, the plugin fetches the current program schedule from iReplay.TV for EPG display.
* **Stream tokens** - When a viewer loads the player, a stream token request is proxied through your WordPress server to iReplay.TV. The viewer's IP address and user agent are forwarded for concurrent viewer enforcement.
* **Usage stats** - Daily, the plugin fetches aggregated usage statistics (viewer counts, peak concurrent) from iReplay.TV.

**What is NOT sent through iReplay.TV:**

* Actual video/audio segment data is served directly from your WordPress server to viewers. iReplay.TV only hosts the HLS playlist files (.m3u8), not the media segments.
* No payment or billing information is handled by the plugin.

**iReplay.TV service links:**

* Service website: [https://ireplay.tv](https://ireplay.tv)
* Terms of Service: [https://ireplay.tv/terms](https://ireplay.tv/terms)
* Privacy Policy: [https://ireplay.tv/privacy](https://ireplay.tv/privacy)

An iReplay.TV account and API credentials are required to use this plugin. A free tier is available (1 channel, 5 concurrent viewers).

== Installation ==

1. Upload the `webtv-webradio` folder to `/wp-content/plugins/`
2. Activate the plugin through the 'Plugins' menu
3. Go to **WebTV & Radio > Settings** and enter your iReplay.TV API credentials
4. Click **Test Connection** to verify
5. Create your first channel under **WebTV & Radio > Channels**
6. Upload media files to the channel
7. Use `[irptvcr_tv_player channel="your-handle"]` in any post or page

= Nginx configuration =

If your WordPress site uses Nginx, add this to your server block for proper HLS segment serving:

`location ~* /wp-content/uploads/ireplay/.*\.(m4s|ts|mp4|m3u8)$ {
    add_header Access-Control-Allow-Origin "*";
    add_header Cache-Control "public, max-age=31536000";
}`

== Frequently Asked Questions ==

= Do I need an iReplay.TV account? =

Yes. The plugin requires API credentials from iReplay.TV to function. A free tier is available with 1 channel and up to 5 concurrent viewers.

= Where are my video files stored? =

Your original uploads and transcoded HLS segments are stored on your own WordPress server in `wp-content/uploads/ireplay/`. Only the playlist files (.m3u8) are hosted by iReplay.TV.

= What video formats are supported? =

Any format supported by FFmpeg can be uploaded. Files are transcoded to HLS with H.264 video and AAC audio at multiple quality levels (1080p, 540p, and audio-only).

= Can I have multiple channels? =

Yes. The number of channels depends on your subscription tier: Free (1), Starter (3), Pro (10), Business (unlimited).

= How does billing work? =

Billing is based on concurrent viewer limits, not storage or bandwidth. The free tier allows up to 5 simultaneous viewers. All billing is handled by iReplay.TV.

== Changelog ==

= 1.0.14 =
* Audio assets (radio stations, podcasts) now transcode correctly. Previously an audio-only upload was sent through the video encoding ladder and always failed, leaving the asset stuck on "Transcoding".
* Assets no longer show "Transcoding" forever when the job has failed. The 5-minute heartbeat now reconciles each pending asset against its real job status and surfaces the error.
* New "Retry" action on the asset list for failed or stalled assets. The original file is reused, so there is no need to delete and upload it again.
* Audio-only encoding is now chosen from the asset's own media type rather than the channel type, so an MP3 uploaded to a channel that was not created as a radio station is still handled as audio.
* Segment upload tokens now last a week instead of a day. A job that failed and retried over several days used to come back to an expired token and fail on upload, hiding the original error.

= 1.0.13 =
* New VOD player shortcode: `[irptvcr_vod_player asset_id="42"]` plays a single ready asset end-to-end with native HTML5 seek controls. Useful for blog posts where you want to embed a specific video rather than the 24/7 channel rotation.
* Asset list admin: each ready asset now displays its VOD shortcode + master.m3u8 URL (copyable) for use in any HTML player or external embed.
* Per-asset playlists and segments are served entirely from the WordPress server via the existing REST proxy (`/wp-json/ireplay/v1/segment?f=…`) — no iReplay.TV dependency at playback time.

= 1.0.12 =
* Schema self-heal: plugin now checks on every load that its tables exist. If a previous uninstall dropped them, an update or page load auto-recreates them. Prevents the "Table doesn't exist" wedge that occurred when reinstalling after a delete.
* CORS fix for assets: per-asset segment_url_prefix now uses the REST proxy URL (`/wp-json/ireplay/v1/segment?f=…`) instead of the direct uploads path. Eliminates hls.js fragLoadError when the playlist is served cross-origin (which is the normal case for cloud-hosted plugins).
* Schedule auto-retry on heartbeat: if a channel has 4+ ready assets but the schedule hasn't activated (e.g. initial trigger fired during a race condition with HLS metadata insertion), the next 5-min heartbeat retries generation. Channels self-heal without manual intervention.
* Migration on upgrade: existing channels created on prior versions have their asset segment URLs rewritten in place to the proxy form. Existing deployments fix automatically when they update to 1.0.12.
* Retry-sync code path now also uses the proxy URL (the 1.0.11 fix only updated create_channel; clicking "Retry Sync" silently reverted to the direct URL).
* Daily cleanup cron: orphaned chunked-upload temp directories older than 24h are removed automatically, preventing failed uploads from filling the WP host's uploads quota.
* Better diagnostics: when a local INSERT fails, the actual MySQL error is now surfaced in the admin alert message instead of a generic "Failed to create…".

= 1.0.11 =
* Register new channels with the REST proxy URL (`/wp-json/ireplay/v1/segment?f=`) as segment base, so HLS fragments carry CORS headers and play correctly when the playlist is served cross-origin (from iReplay.tv).
* Better "Public channel" label: now reads "Allow public visitors to play this channel" with a description explaining what it does (was wrongly described as "visible in My TV Channel app"). Default is now checked for new channels.
* uninstall.php now preserves data by default. Channels/assets/credentials are kept on plugin delete unless the admin explicitly opts in via Settings → "Delete all plugin data on uninstall". Prevents accidental data loss during plugin replacement flows.

= 1.0.10 =
* Extend admin (edit_posts) bypass to /now-playing and /schedule REST endpoints. Channel admins can now preview Now Playing info and EPG for non-public channels (only /stream/token had the bypass before).

= 1.0.9 =
* Harden /stream/token permission check: public visitors must now pass both a wp_rest nonce AND request a public (is_public=1) channel; authenticated editors (edit_posts) bypass the public check so admin/block-editor previews still work for non-public channels (WordPress.org review compliance)

= 1.0.8 =
* Rename all plugin identifiers to use the unified `irptvcr` / `IRPTVCR_` prefix — functions, classes, defines, options, hooks, transients, REST handlers, CSS classes, JS globals, admin page slugs, and shortcodes (WordPress.org review compliance for consistent prefixing)
* Shortcodes renamed: [irptvcr_tv_player] (was [ireplaytv_player]) and [irptvcr_radio_player] (was [ireplayradio_player])
* wp-config.php constants renamed: IRPTVCR_API_KEY, IRPTVCR_API_SECRET (were JEWEBTV_*)

= 1.0.7 =
* Rename shortcodes to [ireplaytv_player] and [ireplayradio_player] to use distinct, conflict-resistant prefixes
* Add channel visibility checks (is_active + is_public) to /now-playing and /schedule REST endpoints

= 1.0.6 =
* Align text domain with assigned plugin slug (ireplay-tv-channel-radio)
* Add sanitize_callback to all registered settings
* Harden /stream/token REST endpoint with nonce check, channel visibility check, and per-IP rate limit

= 1.0.0 =
* Initial release
* WebTV and WebRadio channel support
* Chunked media upload with progress
* HLS transcoding via iReplay.TV
* Shortcode-based player embedding
* Now-playing info with live polling
* Admin dashboard with channel stats

== Upgrade Notice ==

= 1.0.9 =
Tightened /stream/token permission check so non-public channels can no longer be requested by public visitors via a frontend nonce. Recommended for all users.

= 1.0.8 =
All plugin identifiers renamed to a unified `irptvcr` prefix (WordPress.org review compliance). Update any embeds to [irptvcr_tv_player] / [irptvcr_radio_player], and any wp-config.php constants to IRPTVCR_API_KEY / IRPTVCR_API_SECRET.

= 1.0.7 =
WordPress.org review compliance fixes; shortcodes renamed (see changelog).

= 1.0.6 =
WordPress.org review compliance fixes; recommended for all users.

= 1.0.0 =
Initial release.

== Screenshots ==

1. Dashboard showing channels and subscription info
2. Channel creation form
3. Asset upload with progress bars
4. Settings page with API credentials
5. WebTV player embedded on a page
6. WebRadio player with now-playing info
