M3U плейлист на PHP: примеры и рекомендации

Раздел:

Основные подходы к созданию M3U плейлистов на PHP

Целевое решение: универсальная функция, которая из массива данных формирует корректный M3U файл с поддержкой расширенного формата EXTINF. Используется для быстрой генерации плейлиста из любых источников (БД, API, файлы конфигурации).


function generateM3U(array $items, string $filename = 'playlist.m3u'): bool {
    $handle = fopen($filename, 'w');
    if (!$handle) {
        return false;
    }
    fwrite($handle, "#EXTM3U\n");
    foreach ($items as $item) {
        $duration = $item['duration'] ?? -1;
        $title = $item['title'] ?? 'Unknown';
        $path = $item['path'] ?? '';
        fwrite($handle, "#EXTINF:{$duration},{$title}\n");
        fwrite($handle, "{$path}\n");
    }
    fclose($handle);
    return true;
}

преобразовать php (преобразование типов в php)

Пояснение: Функция принимает массив с элементами, каждый из которых содержит duration (в секундах), title (название) и path (URL или путь к файлу). Записывает заголовок #EXTM3U и для каждого элемента строку #EXTINF и сам путь. Возвращает true при успешной записи.

Типичные проблемы:

  • Отсутствие символа новой строки в конце файла – некоторые плееры могут некорректно обрабатывать последнюю строку. Рекомендуется добавлять пустую строку в конце.
  • Некорректная кодировка – если заголовки содержат не-ASCII символы, файл должен быть сохранён в UTF-8 без BOM. Для явной установки кодировки используйте fwrite($handle, "\xEF\xBB\xBF"); перед заголовком, если требуется BOM (для Windows-плееров).
  • Неэкранированные запятые в названии – в поле title запятая может быть воспринята как разделитель. Рекомендуется заменять запятую на точку с запятой или экранировать.

Вариант 1: Генерация из базы данных MySQL

Как сформировать M3U на основе записей таблицы channels?


$db = new PDO('mysql:host=localhost;dbname=iptv', 'user', 'pass');
$stmt = $db->query('SELECT name, url, duration FROM channels WHERE active=1');
$items = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $items[] = [
        'title' => $row['name'],
        'path' => $row['url'],
        'duration' => $row['duration']
    ];
}
generateM3U($items, 'channels.m3u');

Php ai (искусственный интеллект на php)

Пояснение: Извлекаются активные каналы из БД, преобразуются в массив и передаются в ранее определённую функцию. Такой подход легко масштабируется для тысяч записей.

Возможные ошибки: Большое количество записей может исчерпать память – используйте прямое построчное добавление в файл внутри цикла, без промежуточного массива.

Вариант 2: Загрузка и модификация существующего M3U

Как добавить новые каналы в уже имеющийся плейлист?


$existing = file('old_playlist.m3u', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$newItems = [
    ['duration' => -1, 'title' => 'Новый канал', 'path' => 'http://example.com/stream']
];
$file = fopen('merged.m3u', 'w');
fwrite($file, "#EXTM3U\n");
foreach ($existing as $line) {
    if (strpos($line, '#EXTM3U') !== 0) { // пропускаем дублирующий заголовок
        fwrite($file, $line . "\n");
    }
}
foreach ($newItems as $item) {
    fwrite($file, "#EXTINF:{$item['duration']},{$item['title']}\n");
    fwrite($file, "{$item['path']}\n");
}
fclose($file);

Click php url (обработка кликов по url в php)

Пояснение: Загружается старый файл, отбрасывается заголовок (если есть) и дописываются новые строки. Результат сохраняется в новый файл.

Вариант 3: Расширенный формат с группами и логотипами

Как добавить атрибуты tvg-id, tvg-logo, group-title для IPTV?


function generateM3UExtended(array $items, string $filename): bool {
    $fp = fopen($filename, 'w');
    if (!$fp) return false;
    fwrite($fp, "#EXTM3U\n");
    foreach ($items as $item) {
        $extinf = sprintf("#EXTINF:%d tvg-id=\"%s\" tvg-logo=\"%s\" group-title=\"%s\",%s\n",
            $item['duration'] ?? -1,
            $item['tvg_id'] ?? '',
            $item['tvg_logo'] ?? '',
            $item['group_title'] ?? 'Без группы',
            $item['title']
        );
        fwrite($fp, $extinf);
        fwrite($fp, $item['path'] . "\n");
    }
    fclose($fp);
    return true;
}

Php меньше (оператор меньше в php)

Пояснение: Добавлены нестандартные атрибуты в строку EXTINF. Это позволяет плеерам (например, IPTV Simple Client) группировать каналы и отображать логотипы.

Проблема: Синтаксис EXTINF зависит от версии M3U. Некоторые плееры игнорируют незнакомые атрибуты, другие могут сломаться. Проверяйте совместимость.

Вариант 4: Кэширование сгенерированного плейлиста

Как уменьшить нагрузку при каждом запросе плейлиста?


$cacheFile = 'cache/playlist.m3u';
$cacheTime = 3600; // 1 час
if (file_exists($cacheFile) && time() - filemtime($cacheFile) < $cacheTime) {
    readfile($cacheFile);
    exit;
}
// генерация нового плейлиста
$items = fetchChannelsFromDB();
generateM3U($items, $cacheFile);
readfile($cacheFile);

Пояснение: Перед генерацией проверяется время жизни кэша. Если кэш свежий, отдаётся готовый файл, иначе – пересоздаётся. Это значительно ускоряет отдачу для пользователей.

- Define php (определение констант в php)
- Php memory (управление памятью в php)
- Html javascript php (интеграция html, javascript и php)

Расширенные примеры создания M3U плейлистов

1. Динамическая сортировка по категориям

Пример генерации плейлиста, где каналы группируются в блоки по group-title, с разделителями в виде комментариев.

Пример

function generateGroupedM3U(array $items, string $file): void {
    $fp = fopen($file, 'w');
    fwrite($fp, "#EXTM3U\n");
    $groups = [];
    foreach ($items as $item) {
        $g = $item['group'] ?? 'Other';
        $groups[$g][] = $item;
    }
    foreach ($groups as $groupName => $groupItems) {
        fwrite($fp, "# ----- {$groupName} -----\n");
        foreach ($groupItems as $item) {
            fwrite($fp, "#EXTINF:{$item['duration']},{$item['title']}\n");
            fwrite($fp, "{$item['url']}\n");
        }
    }
    fclose($fp);
}

$data = [
    ['title' => 'Первый', 'duration' => -1, 'url' => 'http://a.com/1', 'group' => 'Новости'],
    ['title' => 'Второй', 'duration' => -1, 'url' => 'http://b.com/2', 'group' => 'Спорт'],
];
generateGroupedM3U($data, 'grouped.m3u');

Результат (grouped.m3u):

#EXTM3U
# ----- Новости -----
#EXTINF:-1,Первый
http://a.com/1
# ----- Спорт -----
#EXTINF:-1,Второй
http://b.com/2

2. Интеграция с внешним API для получения метаданных

Загрузка списка каналов из JSON API и преобразование в M3U.

Пример

$json = file_get_contents('https://api.example.com/channels');
$channels = json_decode($json, true);
if (!$channels || !isset($channels['data'])) {
    die('Ошибка получения данных');
}
$items = [];
foreach ($channels['data'] as $ch) {
    $items[] = [
        'title' => $ch['name'],
        'path'  => $ch['stream_url'],
        'duration' => $ch['duration'] ?? -1,
        'tvg_logo' => $ch['logo'] ?? ''
    ];
}
generateM3UExtended($items, 'api_playlist.m3u');

Результат: Файл M3U с расширенными атрибутами, готовый к использованию в любом плеере.

3. Потоковая запись большого плейлиста (список каналов 100000+)

Использование генератора для избежания хранения всех данных в памяти.

Пример

function channelGenerator(PDO $db): Generator {
    $stmt = $db->query('SELECT name, url FROM channels');
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        yield ['title' => $row['name'], 'path' => $row['url'], 'duration' => -1];
    }
}

$fp = fopen('big_playlist.m3u', 'w');
fwrite($fp, "#EXTM3U\n");
foreach (channelGenerator($pdo) as $item) {
    fwrite($fp, "#EXTINF:{$item['duration']},{$item['title']}\n");
    fwrite($fp, "{$item['path']}\n");
}
fclose($fp);

Пояснение: Генератор построчно читает из БД и сразу пишет в файл, не создавая промежуточного массива.

4. Поддержка разных протоколов и автоматическое определение формата

Если источник предоставляет потоки http, rtmp, mms, можно автоматически проставить соответствующий префикс в EXTINF.

Пример

foreach ($items as &$item) {
    $protocol = parse_url($item['path'], PHP_URL_SCHEME);
    $item['type'] = ($protocol === 'rtmp') ? 'rtmp' : 'hls';
}
// в EXTINF можно добавить атрибут radio="true" или protocol

Применение: Позволяет плееру правильно выбирать декодер.

5. Генерация M3U с аутентификацией (токен в URL)

Добавление временного токена к ссылкам для ограниченного доступа.

Пример

$token = generateToken(); // допустим, md5(time())
$items = array_map(function($item) use ($token) {
    $separator = (strpos($item['path'], '?') !== false) ? '&' : '?';
    $item['path'] .= $separator . 'token=' . $token;
    return $item;
}, $items);
generateM3U($items, 'secure_playlist.m3u');

Результат: Все URL в плейлисте содержат параметр token, который можно проверить на стороне сервера.

Создание M3U плейлиста на PHP - comments

En
Php m3u (php)