Локальная TV-программа через CCcam/OScam: настройка EPG

Каналы открываются, картинка есть, но вместо программы передач — пустота или чужой регион. Это классическая ситуация после настройки CCcam/OScam: local tv guide не работает, хотя всё остальное в порядке. Причина банальная — дескремблирование и EPG технически не связаны вообще. Разберём по шагам как это починить.

Что такое локальный EPG и почему он не работает из коробки

EPG (Electronic Program Guide) — это расписание передач, которое ресивер отображает в InfoBar и планировщике записей. Данные для него могут приходить двумя принципиально разными способами, и путаница между ними — корень большинства проблем.

Разница между DVB EPG (из потока) и XMLTV EPG (внешний источник)

DVB EIT (Event Information Table) передаётся прямо в транспондере на PID 0x12. Ресивер читает эти таблицы параллельно с декодированием видео — никакого дополнительного ПО не нужно. Это работает на открытых и незашифрованных пакетах или когда провайдер передаёт EIT незашифрованным даже в scrambled-потоке.

XMLTV — это XML-файл с расписанием, который тянется с внешнего сервера по HTTP и парсится плагином на ресивере. Формат стандартизирован, файлы могут весить от нескольких мегабайт до десятков мегабайт для большого пакета каналов. Плагин EPGImport на Enigma2 работает именно с этим форматом.

Почему CCcam/OScam не передают EPG — только дескремблируют поток

CCcam и OScam работают на уровне условного доступа: они принимают ECM-запросы от ресивера, запрашивают Control Word у карты или сервера, и возвращают его обратно. Всё. Они понятия не имеют что за видео дескремблируется — HD-канал, SD или EIT-таблица с EPG.

Проблема в том, что некоторые провайдеры шифруют EIT-таблицы тем же CAID, что и видео. CCcam дескремблирует видео нормально, но EPG-таблицы в транспондере остаются зашифрованными и ресивер их не парсит. Итог: каналы идут, EPG пуст.

Когда провайдер вырезает EPG из транспондера

Это отдельный сценарий — провайдер просто не передаёт EIT в потоке. Такое делается намеренно: либо чтобы заставить использовать собственное приложение с EPG, либо просто экономия полосы транспондера. В этом случае ни CCcam, ни OScam, ни какие-либо другие плагины EIT из потока не достанут — его там нет физически.

Часовые пояса и сдвиг расписания на несколько часов

DVB EIT передаёт время в UTC. Ресивер конвертирует его в локальное время согласно настройкам часового пояса. Если ресивер выставлен в UTC, а канал московский (+0300) — всё расписание будет сдвинуто на три часа. Проверяй: Menu → Setup → Expert Setup → Time settings → Timezone.

Источники XMLTV для локальной TV-программы

Local tv guide через XMLTV — это рабочий способ получить нормальное расписание даже когда провайдер не отдаёт EIT. Но не любой XMLTV-фид подойдёт, и выбирать его нужно осознанно.

Бесплатные открытые XMLTV-фиды (общие критерии выбора)

На что смотреть при выборе фида: частота обновления (нормальный фид обновляется раз в 6-12 часов, не раз в неделю), глубина расписания (минимум 3-7 дней вперёд, лучше 14), наличие описаний передач и категорий, поддержка иконок каналов через тег icon src=.

Для русскоязычных каналов особенно важна кодировка. Фид должен быть строго UTF-8 — если в XML-декларации написано encoding="windows-1251", готовься к кракозябрам на ресивере. Ещё момент: проверяй что в фиде есть именно твои каналы, а не только федеральный пакет без региональных вставок.

Формат файла: tag channel, programme, start/stop, timezone

Валидный XMLTV выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">
<tv generator-info-name="my-grabber">
  <channel id="perviy.ru">
    <display-name lang="ru">Первый канал</display-name>
    <icon src="https://example.com/icons/perviy.png"/>
  </channel>
  <programme start="20260523180000 +0300" stop="20260523190000 +0300" channel="perviy.ru">
    <title lang="ru">Вечерние новости</title>
    <desc lang="ru">Главные события дня</desc>
    <category lang="ru">Новости</category>
  </programme>
</tv>

Критичные атрибуты: start и stop в формате YYYYMMDDHHmmss TIMEZONE. Timezone должна быть явной: +0300, +0000, но не просто Z или пустой. Отсутствие timezone — источник половины проблем со сдвигом расписания.

Как проверить корректность XMLTV через xmllint

Перед тем как заливать файл на ресивер — проверяй на компьютере:

xmllint --noout epg.xml
# Если есть ошибки — выдаст строку и описание

# Считаем количество программ:
grep -c '<programme ' epg.xml

# Проверяем кодировку:
file -i epg.xml
# Должно быть: application/xml; charset=utf-8

Если grep -c programme выдаёт 0 или несколько штук при большом файле — XML сломан, парсер ресивера молча проигнорирует всё содержимое.

Кодировка UTF-8 и проблемы с кириллицей в названиях передач

Если получил файл в windows-1251 — конвертируй перед использованием:

iconv -f cp1251 -t utf-8 epg_win.xml -o epg_utf8.xml

После конвертации обязательно проверить что XML-декларация тоже поменяна: <?xml version="1.0" encoding="UTF-8"?>. Иначе парсер будет ругаться на несоответствие.

Настройка EPGImport на Enigma2 (OpenATV, OpenPLi)

EPGImport — стандартный плагин для Enigma2, работает на OpenATV, OpenPLi, OpenVision и большинстве других прошивок. На DreamOS (Dreambox) устанавливается через ipk-пакет, не через opkg, и пути к конфигам совпадают: /etc/epgimport/.

Установка плагина: opkg install enigma2-plugin-extensions-epgimport

# Через SSH на ресивер:
opkg update
opkg install enigma2-plugin-extensions-epgimport

# На DreamOS через ipk:
dpkg -i enigma2-plugin-extensions-epgimport_*.ipk

После установки плагин появляется в меню: Plugins → EPGImport. При первом запуске создаёт каталог /etc/epgimport/ если его нет.

Структура каталогов: /etc/epgimport/ и формат .channels.xml и .sources.xml

/etc/epgimport/
├── sources.xml          # или custom.sources.xml
├── myepg.channels.xml   # маппинг channel id → ServiceRef
└── sources/             # поддиректория для дополнительных источников

Важно: EPGImport читает все файлы *.sources.xml и *.channels.xml из /etc/epgimport/ автоматически. Не надо трогать системные файлы плагина — создавай свои с префиксом custom. или любым другим именем.

Создание собственного источника: source description, url, channels href

Файл /etc/epgimport/custom.sources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<sources>
  <sourcecat sourcecatname="Мои каналы">
    <source type="gen_xmltv" nocheck="1">
      <description>Российские каналы EPG</description>
      <url>http://192.168.1.100/epg/russia.xml</url>
      <channels>/etc/epgimport/russia.channels.xml</channels>
    </source>
  </sourcecat>
</sources>

Атрибут nocheck="1" отключает проверку доступности URL при старте — полезно если сервер не всегда онлайн. Можно указывать как локальный файл (file:///tmp/epg.xml), так и HTTP-URL.

Маппинг ServiceRef к channel id из XMLTV

Файл /etc/epgimport/russia.channels.xml:

<?xml version="1.0" encoding="UTF-8"?>
<channels>
  <channel id="perviy.ru">1:0:19:283D:3FB:1:C00000:0:0:0:</channel>
  <channel id="russia1.ru">1:0:19:3F84:3FB:1:C00000:0:0:0:</channel>
  <channel id="ntv.ru">1:0:19:3F85:3FB:1:C00000:0:0:0:</channel>
</channels>

Здесь id должен точно совпасть с id тега channel в XMLTV-файле. ServiceRef — строка из lamedb ресивера. Несовпадение этих двух значений — причина 90% случаев когда "импорт прошёл, но EPG пуст".

Автообновление по cron: /etc/cron.daily или через настройки плагина

Через плагин: EPGImport → Settings → Schedule import → Daily, время 04:00 (когда нагрузка минимальна).

Через cron — создать файл /etc/cron.daily/epgimport:

#!/bin/sh
/usr/lib/enigma2/python/Plugins/Extensions/EPGImport/epgimport.sh
chmod +x /etc/cron.daily/epgimport

Путь к базе EPG: /etc/enigma2/epg.dat и принудительная перезагрузка

Enigma2 хранит кешированный EPG в /etc/enigma2/epg.dat. После импорта данные сохраняются туда и переживают перезагрузку — если путь задан правильно. Параметр в /etc/enigma2/settings:

config.misc.epgcache_filename=/etc/enigma2/epg.dat

Принудительный сброс кеша через telnet на ресивер (порт 23):

telnet 192.168.1.x 23
# В консоли enigma2:
e2_clearepgcache

Настройка EPG для OScam через oscam.services и dvbapi

OScam EPG не отдаёт и не собирает — это не его задача. Но в правильной связке с Tvheadend OScam дескремблирует поток через DVBAPI, а Tvheadend самостоятельно тянет XMLTV и раздаёт EPG клиентам по HTSP. Получается что местная local tv guide раздаётся централизованно одним сервером.

Файл oscam.services: привязка caid/provid к именам сервисов

Файл /etc/oscam/oscam.services используется для ограничения доступа к сервисам, не для EPG. Но для диагностики полезно знать его формат:

[RussianChannels]
caid = 0500
provid = 032000
srvid = 283D,3F84,3F85,3F86

[SportPackage]
caid = 0500
provid = 041500
srvid = 1001,1002,1003

srvid — это SSID каналов в hex. Совпадает с частью ServiceRef: в строке 1:0:19:283D:3FB:1:C00000:0:0:0: значение 283D — это и есть srvid.

DVBAPI-протокол и сокет /tmp/camd.socket

OScam общается с Enigma2 или Tvheadend через DVBAPI-протокол. Настройка в /etc/oscam/oscam.dvbapi:

[dvbapi]
enabled = 1
user = dvbapi
au = 1
boxtype = dreambox
pmt_mode = 0
request_mode = 0
listen_port = 0
extended_cw_api = 0

Сокет создаётся автоматически: /tmp/camd.socket. Tvheadend подключается к нему для дескремблирования. Если сокет не появился — OScam не запущен или dvbapi не включён.

Как OScam логирует EPG-запросы при DEBUG=4

OScam не логирует EPG-запросы как таковые — он их не обрабатывает. Но при уровне DEBUG=4 в /etc/oscam/oscam.conf можно увидеть все ECM-запросы и понять какие srvid обращаются к серверу:

[global]
logfile = /tmp/oscam.log
debuglevel = 4
tail -f /tmp/oscam.log | grep "srvid\|ECM"

Связка OScam + Tvheadend для серверной раздачи EPG

Tvheadend при этой схеме делает всё: дескремблирует через OScam (DVBAPI), собирает EPG через XMLTV-grabber, и раздаёт HTSP-поток с EPG клиентам (Kodi, второй ресивер, мобильное приложение). Конфигурация grabber находится в:

/home/hts/.hts/tvheadend/epggrab/xmltv/

В web-интерфейсе Tvheadend (порт 9981): Configuration → Channel/EPG → EPG Grabber Modules → External XMLTV. Указываешь путь к скрипту-грабберу или URL. Tvheadend сам запускает grabber по расписанию и маппит channel id на каналы.

Маппинг каналов: связать XMLTV id с ServiceRef ресивера

Это самый больной момент. XMLTV знает каналы по своим id (perviy.ru, channel.1). Enigma2 знает их по ServiceRef. Если маппинг неправильный — EPG импортируется но нигде не отображается.

Где взять ServiceRef: lamedb на ресивере /etc/enigma2/lamedb

Файл /etc/enigma2/lamedb — это база каналов ресивера. Альтернативный способ — web-интерфейс на порту 80: открыть любой канал через браузер, ServiceRef будет в URL вида:

http://192.168.1.x/web/stream.m3u?ref=1:0:19:283D:3FB:1:C00000:0:0:0:

Из lamedb строка канала выглядит так:

s 283D:3FB:1:C00000:0:0:0:  ← hex: ssid:tsid:onid:namespace
p Первый канал

Собираем ServiceRef: 1:0:19:283D:3FB:1:C00000:0:0:0: где 19 = тип сервиса (SD video), 283D = ssid, 3FB = tsid, 1 = onid, C00000 = namespace.

Скрипт автоматического маппинга по имени канала

#!/usr/bin/env python3
import re, xml.etree.ElementTree as ET

def parse_lamedb(path='/etc/enigma2/lamedb'):
    channels = {}
    with open(path, encoding='utf-8', errors='ignore') as f:
        lines = f.readlines()
    i = 0
    while i < len(lines):
        if lines[i].startswith('s '):
            ref_parts = lines[i][2:].strip().split(':')
            if i+1 < len(lines) and lines[i+1].startswith('p '):
                name = lines[i+1][2:].strip().lower()
                ssid, tsid, onid, ns = ref_parts[0], ref_parts[1], ref_parts[2], ref_parts[3]
                sref = f"1:0:19:{ssid}:{tsid}:{onid}:{ns}:0:0:0:"
                channels[name] = sref
        i += 1
    return channels

def build_channels_xml(xmltv_path, lamedb_path, out_path):
    tree = ET.parse(xmltv_path)
    lame = parse_lamedb(lamedb_path)
    root = ET.Element('channels')
    for ch in tree.getroot().findall('channel'):
        cid = ch.get('id')
        names = [d.text.lower() for d in ch.findall('display-name') if d.text]
        for name in names:
            if name in lame:
                ET.SubElement(root, 'channel', id=cid).text = lame[name]
                break
    ET.ElementTree(root).write(out_path, encoding='UTF-8', xml_declaration=True)

build_channels_xml('/tmp/epg.xml', '/etc/enigma2/lamedb', '/etc/epgimport/auto.channels.xml')
print("Done")

Что делать если имена в XMLTV и lamedb различаются (Первый HD vs Первый канал HD)

Скрипт выше делает точное совпадение по строке. Если имена не совпадают — надо вести CSV с ручным маппингом:

# mapping.csv
xmltv_id,service_ref
perviy.ru,1:0:19:283D:3FB:1:C00000:0:0:0:
perviy-hd.ru,1:0:1:1234:5678:1:C00000:0:0:0:
russia1.ru,1:0:19:3F84:3FB:1:C00000:0:0:0:

Тогда скрипт сначала смотрит в CSV, и только если там нет — пытается найти по имени. Это надёжнее fuzzy-матчинга.

Хранение маппинга в rytec.channels.xml формате

Rytec — популярный источник XMLTV для европейских каналов. Их channels.xml формат совместим с EPGImport напрямую. Если используешь rytec-фид — скачивай готовый rytec.channels.xml и дополняй его своими каналами вручную.

Troubleshooting: EPG пустой, отстаёт или показывает не то

Диагностика EPG — это последовательное сужение проблемы. Сначала проверяем что файл валидный, потом что он правильно доехал, потом что маппинг совпадает.

EPG.dat не сохраняется после перезагрузки (config.misc.epgcache_filename)

Проверь значение параметра:

grep epgcache /etc/enigma2/settings

Должно быть: config.misc.epgcache_filename=/etc/enigma2/epg.dat. Если параметра нет или путь указывает на /tmp/ — EPG будет теряться при каждой перезагрузке, потому что /tmp/ на Enigma2 в RAM. Исправить через меню или прямо в файле settings.

Время в передачах сдвинуто на 2-3 часа — проблема с timezone в XMLTV

Два сценария. Первый: фид отдаёт UTC (+0000), ресивер в +0300 — передачи сдвинуты на 3 часа вперёд в расписании. Второй (хуже): фид отдаёт время без timezone вообще, и ресивер интерпретирует его как локальное. Решение одно — найти фид с явным timezone-атрибутом, или конвертировать через скрипт перед импортом.

Импорт прошёл но в InfoBar пусто — несовпадение ServiceRef

Это самый частый случай. Алгоритм проверки:

# 1. Смотрим что импортировалось в epg.dat (через enigma2 debug):
tail -f /tmp/epgimport.log

# 2. Проверяем ServiceRef конкретного канала через web:
# http://192.168.1.x/web/epgservice?sRef=1:0:19:283D:3FB:1:C00000:0:0:0:
# Если EPG есть — ServiceRef правильный, проблема в маппинге
# Если пусто — ServiceRef не совпадает с channels.xml

Кракозябры вместо кириллицы — XMLTV в windows-1251 вместо UTF-8

file -i /tmp/epg.xml
# Если charset=iso-8859-1 или charset=windows-1251:
iconv -f cp1251 -t utf-8 /tmp/epg.xml -o /tmp/epg_utf8.xml
# Потом заменить в XML-декларации encoding="windows-1251" на encoding="UTF-8"
sed -i 's/encoding="windows-1251"/encoding="UTF-8"/i' /tmp/epg_utf8.xml

EPG обновляется но через час пропадает — мало места в /etc/enigma2/

Проверяем:

df -h /etc/enigma2/
ls -lh /etc/enigma2/epg.dat

Полный EPG для 200+ каналов на 7 дней — это 15-50 МБ. Если раздел переполнен — enigma2 не может записать epg.dat и тихо теряет данные при следующей перезагрузке. Или переносить epg.dat на USB: config.misc.epgcache_filename=/media/usb/epg.dat.

Логи: tail -f /tmp/epgimport.log и /var/volatile/log/messages

tail -f /tmp/epgimport.log
# Смотрим строки вида:
# INFO: Fetching http://...
# ERROR: Channel not found: perviy.ru
# INFO: Imported 4521 events for 87 channels

tail -f /var/volatile/log/messages | grep -i epg

Строка "Channel not found" — прямой индикатор что channel id из XMLTV не совпадает ни с одним из channels.xml. Именно здесь смотреть при пустом EPG после "успешного" импорта.

Альтернативы: OpenTV EPG, MHW, EIT через сторонний транспондер

XMLTV — не единственный вариант. Существуют плагины которые собирают EPG прямо из спутникового потока, без внешних серверов.

OpenTV EPG: где встречается и как настроить сбор

OpenTV — проприетарный формат EPG, который исторически использовали британские (Sky), французские (Canal+) и ряд других платформ. Enigma2 поддерживает его через CrossEPG. Но в 2026 году большинство операторов которые раньше транслировали OpenTV EPG перешли на собственные форматы или убрали EPG из потока совсем. Проверить наличие OpenTV на конкретном транспондере можно только сканированием через CrossEPG с включённым логированием.

MHW2 EPG на спутниковых пакетах — плагин CrossEPG

CrossEPG — плагин для Enigma2 который умеет собирать EPG из потока в форматах OpenTV, MHW, MHW2, Sky и конвертировать в формат Enigma2. Устанавливается через opkg:

opkg install enigma2-plugin-extensions-crossepg

MHW2 встречается на ряде спутниковых пакетов — CrossEPG его подхватывает автоматически при сканировании. Глубина EPG при этом зависит от самого провайдера: обычно 2-5 дней, редко больше.

EIT с соседнего спутника как источник для своих каналов

Интересный хак: некоторые провайдеры транслируют незашифрованный EIT для своих каналов на другом транспондере или спутнике. Настраиваешь ресивер на сбор EIT с этого транспондера через CrossEPG или стандартный EIT-сборщик Enigma2 — и получаешь EPG для каналов с основного пакета. Работает не всегда и требует экспериментов с конкретными транспондерами.

Раздача EPG по сети на несколько ресиверов через Tvheadend HTSP

Это правильная архитектура для дома с несколькими ресиверами. Один хост (может быть Raspberry Pi или старый ноутбук) запускает Tvheadend, тянет XMLTV-фид, маппит каналы, хранит EPG. Остальные ресиверы и Kodi подключаются по HTSP (порт 9982) и получают EPG готовым — без собственных плагинов и фидов.

Это также снижает нагрузку: вместо 3 ресиверов которые каждые 6 часов качают 30 МБ XMLTV — один сервер качает один раз и раздаёт внутри сети. При этом local tv guide обновляется централизованно и всегда актуальна на всех устройствах.

Почему после установки CCcam/OScam пропала программа передач?

CCcam и OScam не управляют EPG — они только дескремблируют видеопоток. Если EPG раньше приходил из DVB-потока (EIT на PID 0x12), он и должен продолжать приходить. Если пропал — проверь настройки в /etc/enigma2/settings: параметр config.epg.eit должен быть true. Также убедись что в меню ресивера не отключён автоматический сбор EIT.

Можно ли получить EPG только через CCcam без XMLTV?

Нет. CCcam передаёт только Control Words для дескремблирования — это всё что он умеет делать. EPG приходит либо из самого транспондера (DVB EIT), либо тянется отдельно как XMLTV. Это разные технические уровни: CCcam работает на уровне условного доступа, EPG — на уровне сервисной информации DVB. Никакой связи между ними нет.

Какой формат XMLTV правильный и как его проверить?

Файл должен начинаться с XML-декларации <?xml version="1.0" encoding="UTF-8"?> и корневого тега <tv>. Каждый канал — тег channel id="...", каждая передача — тег programme с атрибутами start, stop, channel и явным timezone: start="20260523180000 +0300". Проверка: xmllint --noout file.xml. Кодировка строго UTF-8.

EPGImport показывает Import successful, но в EPG ничего нет — что делать?

В 90% случаев это несовпадение ServiceRef в channels.xml с реальными в lamedb. Проверь через web-интерфейс ресивера на порту 80: открой канал, ServiceRef будет виден в URL. Сравни с тем что написано в channels.xml. Также проверь что config.misc.epgcache_filename=/etc/enigma2/epg.dat — иначе EPG не переживает перезагрузку.

Как настроить автоматическое обновление EPG раз в сутки?

Через настройки EPGImport: Settings → Schedule import → Daily, время 04:00 (минимальная нагрузка ночью). Альтернатива — добавить скрипт в /etc/cron.daily/. После импорта EPG сохраняется в epg.dat при штатной работе enigma2, либо принудительно через GUI меню перезагрузки.

Время передач сдвинуто на несколько часов — как починить?

Проблема в timezone XMLTV-фида. В тегах programme должен быть явный offset: start="20260523180000 +0300". Если фид отдаёт UTC (+0000), а ресивер настроен на +0300 — расписание сдвинется. Решение: использовать фид с правильным TZ, либо настроить timezone ресивера под фид. Проверяй через Menu → Expert Setup → Time settings.

Tvheadend нужен или можно обойтись EPGImport?

Для одного ресивера EPGImport полностью достаточен. Tvheadend нужен если хочешь центральный EPG-сервер: один хост собирает XMLTV, раздаёт по HTSP второму ресиверу, Kodi, мобильным клиентам — и все получают актуальную local tv guide из одного источника. Это снижает трафик и упрощает поддержку маппинга каналов.

Практические советы для стабильного просмотра

Даже самая стабильная линия CCCam или OSCam требует пары простых подготовительных шагов. Обновляйте прошивку ресивера, раз в неделю очищайте ECM‑кеш и держите 15–20% свободного места на USB‑накопителе или во встроенной памяти, чтобы кардридер записывал ключи без задержек.

При настройке антенны оставляйте запас по MER/BER: смещение на два градуса или ослабленный F‑коннектор чаще становится причиной “фризов”, чем сам кардшаринг. Держите под рукой короткий патч‑корд для проверки другого роутера и сохраните два профиля в OSCam — под TCP и под UDP — чтобы мгновенно переключиться, если провайдер начнёт фильтровать протокол.

Utgard.tv следит за каждым хабом 24/7, однако вы можете ускорить диагностику, если будете вести небольшой журнал действий. Записывайте время переключения канала, активный CAID и то, использовали ли вы Wi‑Fi или Ethernet. Такой мини‑отчёт позволит инженерам воспроизвести вашу конфигурацию в лаборатории и предложить решение не за часы, а за минуты.

  • Держите активными две линии: если первый сервер уходит на обслуживание, второй тут же подхватывает поток без повторного ввода логина.
  • Раз в месяц делайте замер скорости и задержек. Стабильных 1–2 Мбит/с при пинге до 80 мс достаточно для SD/HD, но если джиттер превышает 20 мс — переведите роутер на провод.
  • Сохраните в закладки страницу статуса Utgard.tv и Telegram‑бота @utgard_tv_bot — там появляются уведомления о работах раньше, чем успеют среагировать SEMrush или внешние мониторы.