2026-03-11 23:54:43 +01:00
2026-03-09 21:50:01 +01:00
2026-03-11 23:54:43 +01:00
2026-03-10 09:32:56 +01:00
2026-03-09 18:20:49 +01:00
2026-03-09 14:27:40 +01:00
2026-03-09 20:40:16 +01:00
2026-03-11 18:56:50 +01:00
2026-03-11 19:51:25 +01:00

📺 GridTV

A real-time IPTV TV guide, built for Tunarr and any XMLTV/M3U source.

PHP Apache Nginx License


GridTV Preview


🌐 Demo

A public demo instance is available here:

👉 https://guide.demo.johnnybegood.fr/

This demo runs with a sample XMLTV feed and fake channels to showcase the interface.


Features

  • 🎛️ Timeline grid — horizontal EPG-style view with a live "now" indicator
  • 📱 Responsive — optimized list view on mobile
  • ⏱️ Live progress bar on the currently airing program
  • 🕶️ Past programs automatically dimmed
  • 📋 Hover tooltip — title, synopsis, season/episode, schedule, duration
  • 🔗 One-click copy buttons for EPG & M3U URLs in the topbar
  • ▶️ Built-in HLS player — click any channel or live program to watch in a PiP overlay
  • 🔀 HTTP→HTTPS proxy — streams Tunarr over HTTP transparently from an HTTPS page
  • 🎨 Theme system — drop a CSS file in themes/ and it appears in the menu automatically
  • 📡 Multi-EPG sources — configure multiple EPG/M3U sources, switch from the topbar
  • 👤 Personal EPG — optionally let visitors use your instance with their own EPG/M3U
  • ⚙️ Guided setup on first launch — no config files to edit manually
  • 🔄 Auto-reload EPG every 30 minutes
  • 0️⃣ Zero JS dependencies — vanilla PHP, hls.js loaded from CDN

🚀 Installation

Requirements

  • A web server running PHP 8.0+ with php-curl extension
  • Apache or Nginx
  • An EPG source in XMLTV format (e.g. Tunarr, Jellyfin, xTeVe...)
  • (Optional) An M3U playlist — required for the built-in player

1. Clone the repo

git clone https://github.com/Johnnybegood90/GridTV.git /var/www/gridtv
cd /var/www/gridtv

2. Set permissions

chmod 775 /var/www/gridtv
chown -R www-data:www-data /var/www/gridtv

3a. Configure Nginx

server {
    listen 80;
    server_name guide.your-domain.com;

    root /var/www/gridtv;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
}

💡 Adjust the PHP version (php8.2-fpm) to match the one installed on your server.

nginx -t && systemctl reload nginx

3b. Configure Apache

<VirtualHost *:80>
    ServerName guide.your-domain.com
    DocumentRoot /var/www/gridtv

    <Directory /var/www/gridtv>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
a2enmod php8.4 rewrite
systemctl reload apache2

4. Install php-curl

The built-in player uses proxy.php to relay HTTP streams over HTTPS. This requires the php-curl extension:

# Debian/Ubuntu — adjust version to match your PHP
apt install php8.4-curl

# Then reload the web server
systemctl reload apache2   # or: systemctl reload nginx

5. First launch — Setup

Open your browser at http://guide.your-domain.com.

GridTV detects the missing config and automatically redirects you to the setup page:

Field Description
Group name Displayed top-left in the topbar
EPG sources Add one or more XMLTV sources, each with an optional M3U URL
Personal EPG Toggle to allow visitors to use your instance with their own EPG/M3U

Once submitted, config.json is created on the server. The setup page becomes inaccessible.


6. Editing the config later

nano /var/www/gridtv/config.json
{
  "group_name": "MyGroup TV",
  "epg_sources": [
    {
      "name": "Main",
      "epg_url": "http://192.168.0.3:8000/api/xmltv.xml",
      "m3u_url": "http://192.168.0.3:8000/api/channels.m3u"
    },
    {
      "name": "Sports",
      "epg_url": "http://192.168.0.3:8001/api/xmltv.xml",
      "m3u_url": ""
    }
  ],
  "allow_personal_epg": true
}

Instances running the old single-source format (epg_url at root) are migrated automatically on first load — no manual action needed.


📁 Project structure

gridtv/
├── index.php            # The TV guide (redirects to setup if no config found)
├── setup.php            # First-launch configuration page
├── proxy.php            # HTTP→HTTPS stream proxy (required for the player)
├── config.example.json  # Config template
├── .gitignore           # config.json excluded from the repo
├── themes/              # CSS theme files
│   ├── default.css      # Dark studio (default)
│   ├── magazine.css     # Vintage newspaper
│   ├── cyberpunk.css    # Neon on black
│   └── steampunk.css    # Victorian copper
└── README.md

config.json is listed in .gitignore — your private URLs will never be pushed to GitHub.


🎨 Themes

GridTV ships with 4 built-in themes. To add your own, create a CSS file in themes/ with these metadata comments at the top:

/*
 * @name  My Theme
 * @emoji 🌙
 */

:root {
  --bg: #0a0b0d;
  --accent: #e8c842;
  /* ... */
}

Drop it in themes/ — it appears in the theme selector automatically, no code changes needed.


📡 Multiple EPG Sources

Configure as many EPG/M3U sources as you want in config.json. A dropdown appears in the topbar when more than one source is defined.

If allow_personal_epg is true, a "✏ Personal EPG" option appears in the dropdown, letting any visitor enter their own XMLTV/M3U URLs. Their choice is saved in localStorage — zero server impact.


▶️ Built-in Player

Click on any channel name or currently airing program to open a PiP (picture-in-picture) player in the bottom-right corner.

The player requires:

  • An M3U URL configured in the active source (used to match channel names to stream URLs)
  • The php-curl extension installed on the server

If your stream source (e.g. Tunarr) serves streams over HTTP while GridTV runs on HTTPS, proxy.php handles the relay transparently — no browser mixed-content errors.


⚙️ Advanced configuration

The following constants can be tweaked directly in index.php:

const PX_PER_MIN = 5;    // Horizontal zoom (pixels per minute)
const GRID_HOURS = 72;   // Total timeline duration (hours)
const ROW_H      = 80;   // Channel row height (px)

🧩 EPG Compatibility

GridTV parses the standard XMLTV format. Tested with:


🤝 Contributing

PRs are welcome! Got an idea, a fix, or a feature request — open an issue or send a PR directly.


📄 License

GNU Affero (AGPLv3)

S
Description
Real-time IPTV TV guide and any XMLTV/M3U source. Self-hosted, zero dependencies.
Readme AGPL-3.0
6.5 MiB
Languages
PHP 52.3%
JavaScript 28.8%
CSS 18.5%
Dockerfile 0.3%
Shell 0.1%