M3U Editor Documentation

repository·master·Indexed 21 days ago

https://github.com/m3ue/m3u-editor

A comprehensive IPTV management tool for editing M3U playlists, managing EPG data, and serving content via Xtream API. It supports m3u, m3u8, m3u+, and Xtream codes api, featuring series management with .strm files, XMLTV and Schedules Direct integration, and post-processing automation. The tool can be self-hosted via Docker (with options for hardware acceleration via m3u-proxy) or used via managed hosting through ElfHosted.

Tokens
47.9K
Snippets
158
Records
221
Agent score
74%

What's inside M3U Editor

  1. Overview of m3u editor

    master
    m3u editor is a powerful IPTV editor providing capabilities similar to xteve or threadfin. It includes built-in EPG management, full Xtream API output, series management (supporting .strm file storage and synchronization), and customization features like custom scripts, webhooks, and email notifications. It supports M3U, M3U8, M3U+, and Xtream Codes API formats, as well as XMLTV EPG data (local, remote, or via Schedules Direct integration).
  2. Overview of M3U Editor features

    master

    M3U Editor is a powerful IPTV editor designed to manage playlists and EPG data. It is compatible with m3u, m3u8, m3u+, and Xtream codes api.

    Key Capabilities:

    • EPG Management: Supports XMLTV files (local or remote), XMLTV URLs, and full Schedules Direct integration.
    • Series Management: Ability to store and sync .strm files.
    • Xtream API: Full Xtream API output support.
    • Post-Processing: Ability to trigger custom scripts, send webhook requests, or send emails after processing.
    • Proxy Support: Includes an m3u-proxy component to enable hardware acceleration for stream processing.
  3. Automatic Run Result Tables

    master

    If a ui_table's physical table includes a column named extension_plugin_run_id (referencing extension_plugin_runs), the host automatically treats it as a run result table.

    These tables are automatically surfaced on the plugin run detail page. The table is automatically scoped to the specific run, and if the run's payload contains a playlist_id, it is further scoped to that playlist. Filters for run and playlist appear automatically when the scope is not fixed by the page context.

    { "type": "foreignId", "name": "extension_plugin_run_id", "references": "extension_plugin_runs", "on_delete": "cascade" }
  4. Requirements for successful stream pooling

    master

    Stream pooling only occurs for transcoded streams. Direct streams (those without transcoding) will always create a new connection per client.

    To ensure a request reuses an existing stream, the following metadata must match exactly:

    • original_channel_id
    • original_playlist_uuid
    • profile_id (StreamProfile ID)
    • provider_profile_id (PlaylistProfile ID)

    Pooling also supports cross-provider failover: if a channel from Provider A fails over to Provider B, m3u-editor uses the original_* metadata fields to ensure the new stream from Provider B is pooled with the original request for the channel from Provider A.

  5. How stream pooling works in m3u-editor and m3u-proxy

    master

    Stream pooling allows multiple clients to share a single transcoded stream from m3u-proxy without consuming additional provider connections. This is achieved by having m3u-editor check for an existing active stream with matching metadata before requesting a new one.

    Comparison of Behaviors

    Without Pooling (Old Behavior): Every user request triggers a new stream creation, leading to multiple provider connections. If a provider has a connection limit (e.g., 1), subsequent users are rejected. User 1 → m3u-editor → m3u-proxy → Creates Stream A → Provider Connection 1 User 2 → m3u-editor → m3u-proxy → Creates Stream B → Provider Connection 2 ❌ (REJECTED)

    With Pooling (New Behavior): Multiple users reuse the same existing stream and the same underlying provider connection. User 1 → m3u-editor → m3u-proxy → Creates Stream A → Provider Connection 1 User 2 → m3u-editor → m3u-proxy → Reuses Stream A → SAME Provider Connection ✅

    Requirements for Pooling

    For pooling to be successful, the following criteria must be met:

    1. Transcoding must be enabled (a profile parameter must be provided).
    2. Same original channel: The original_channel_id must match.
    3. Same original playlist: The original_playlist_uuid must match.
    4. Same transcoding profile: The profile_id (StreamProfile ID) must match.
    5. Same provider profile: The provider_profile_id (PlaylistProfile ID) must match (if using pooled provider profiles).
    6. Active Stream: The stream must still have at least one connected client.

    Note: Direct streams (non-transcoded) do NOT pool because they require individual connections to the provider and do not share an FFmpeg process.

  6. Understand Pool Status and Capacity

    master

    The Pool Status widget provides real-time visibility into how many connections are active across your provider profiles.

    Reading the Pool Status Display

    An example display looks like this: Total: 5/15 active | 10 available ✓ ⭐ Primary: 3/5 streams ✓ Backup: 2/5 streams ✗ Account3: 0/5 streams (Disabled)

    Legend:

    • : Profile is enabled.
    • : Profile is disabled (skipped during selection).
    • : This is the Primary profile.
    • 3/5 : 3 active connections out of a maximum of 5.
    • Total: 5/15 : 5 total active connections, 15 total capacity, 10 available slots.
  7. How Network Broadcasting and HLS works

    master

    Networks function as "pseudo-TV" channels by pulling content from media servers (like Jellyfin or Emby) and converting them into continuous HLS broadcasts.

    Key behaviors:

    • Storage: Each network writes its HLS segments (.ts) and playlist (live.m3u8) to a specific storage path: storage/app/networks/{uuid}.
    • Resumption: The system persists broadcast_programme_id and broadcast_initial_offset_seconds in the networks table. This allows the system to calculate the correct seek position and resume playback at the right spot if a broadcast restarts.
    • Seeking: To ensure accurate resumption, the system uses FFmpeg input-level seeking (-ss before -i). While the media server's StartTimeTicks is sent as a hint, the -ss flag is what guarantees the stream begins at the calculated offset.
    • Xtream API: Networks are exposed via Xtream-compatible endpoints, allowing IPTV players to list networks, fetch EPG, and stream via /live/ redirects.
  8. How the AI Copilot works

    master

    The AI Copilot is an in-app chat assistant for admins, powered by Laravel AI. It is registered via the FilamentCopilotPlugin and provides a chat interface in the top navigation bar.

    Administrators can interact with the application using natural language to perform tasks like searching records, creating/editing data, and navigating pages. The AI uses tools (PHP classes implementing a typed interface) to execute actions. The AI receives tool descriptions and JSON schemas, allowing it to call them autonomously. Settings like provider, model, and API keys are stored in the settings table via GeneralSettings and applied at runtime without requiring a server restart.

  9. Plugin execution model and constraints

    master

    Plugins operate within a controlled execution environment:

    • Manual Actions: Queued through ExecutePluginInvocation.
    • Hooks: Invocations are queued through PluginHookDispatcher.
    • Persistence: All runs are recorded in the extension_plugin_runs table.

    Safety Constraints:

    • Uninstalled plugins cannot execute until explicitly reinstalled.
    • Untrusted plugins or plugins whose integrity has changed cannot execute until they are reviewed and trusted again.
    • Cleanup: Uninstalling a plugin only removes data that was explicitly declared as plugin-owned in the manifest.
  10. Manage plugin data ownership and storage

    master

    Plugins must declare their owned data in the data_ownership section of the manifest to ensure safe cleanup during uninstallation.

    Table Naming Rules: All plugin-owned tables must follow the pattern: plugin_<plugin_id_with_underscores>_. Example: For sample-plugin, use plugin_sample_plugin_events.

    Storage Path Rules: Files and directories must reside under approved roots and be namespaced by the plugin ID.

    Approved Roots:

    • plugin-data/<plugin-id>/...
    • plugin-reports/<plugin-id>/...

    Cleanup Policies:

    • preserve: Keep data after uninstallation.
    • purge: Delete data after uninstallation.
  11. How EPG optimization works

    master

    The EPG system uses a high-performance caching solution via the EpgCacheService to avoid expensive XML parsing on every request.

    Cache Mechanism

    • Storage: Data is stored as JSON files in storage/app/epg-cache/{epg_uuid}/v1/.
    • Structure:
      • channels.json: All channel data.
      • programmes-{YYYY-MM-DD}.json: Programme data chunked by specific dates for efficient access.
      • metadata.json: Cache statistics and metadata.
    • Lifecycle: Cache is automatically generated/updated during the ProcessEpgImport job. It is also automatically validated based on file modification times to detect stale data.

    Performance Benefits

    • Speed: Reduces EPG viewing response time from 10-15 seconds (XML parsing) to <1 second (JSON reading).
    • Memory: Significantly reduces memory consumption by reading pre-processed JSON instead of parsing large XML trees.
    • Scalability: Handles large EPG files (23,000+ channels) efficiently through date-chunked storage and memory-efficient pagination.
  12. Compare Nginx and Caddy setups for m3u-editor

    master

    When deploying m3u-editor with an external reverse proxy, you can choose between Nginx or Caddy.

    Nginx (docker-compose.external-all.yml)

    • Configuration: Uses nginx.conf with traditional, verbose syntax.
    • HTTPS: Requires manual SSL certificate management and configuration.
    • Best for: Users needing maximum control, complex routing, or specific Nginx modules.

    Caddy (docker-compose.external-all-caddy.yml)

    • Configuration: Uses Caddyfile with a simple, declarative syntax.
    • HTTPS: Automatic HTTPS via Let's Encrypt (obtains, renews, and handles redirects automatically).
    • Best for: Users wanting zero-configuration HTTPS, ease of use, and readable configurations.