Pull to refresh

Reverse engineering: сервис tvali.ge

Reading time 4 min
Views 7.1K

Предыстория (можно пропустить)


Ситуация: есть большая локальная сеть с малодоступной «внешкой» и свободная более-менее производительная машина с безлимитным внешним интернетом.
И есть общее желание у студентов: смотреть футбол по интернету, ввиду недоступности телевизора в общежитиях.
После долгих проб и ошибок с ретрансляцией ТВ со «внешки» (обрывы связи под вечер, любой лаг источника видео — обрывы и «кубики» у всех внутри локальной сети) были поиски альтернативных источников канала со спортом. Спутниковую антенну возможности поставить нет. И в итоге был найден сайт — tvali.ge, который работает по схеме:
Захватил видео с канала (5 минут) -> сохранил -> отдал пользователю во флеш-плеер. Все с задержкой от оригинального потока в 10 минут
Демонстрация плеера


Под катом детальная схема работы сервиса и решение, как же «перетащить» канал к себе.

Схема просмотра ТВ передач

Зашел на сайт (получил cookie) -> открыл страницу с нужным каналом -> смотришь запись канала.
Но! Сookie. Если у тебя нет сессии от сайта — то плеер не подгрузит тебе плейлист и выведет на экран:
Пытаемся смотреть без сессии. Отказ в доступе

Что же, смотрим дальше.
Сервис предоставляет «вставку» на любой сайт плеера с данным каналом. Разберем «НТВ + Спорт», а именно часть вызова плеера. Прокомментирую интересные для нас строчки из вставки, что дает сервис:

  var cc=955; 
 // ID канала на сервисе
 var d = new Date();
 var cd = d.getDay()*(24*60)+d.getHours()*60+Math.floor(d.getMinutes()/5)*5-10;
 // Генерация "нужного" времени (используется далее для подгрузки плейлиста).
 var fn = "http://tvali.ge/tv/"+cc+"_list.php?d="+cd;	
 // а вот и подгрузка самого плейлиста.


Разбор запрета на доступ к каналу без cookie

Переходим по ссылке с плейлистом. Вот тут и обнаруживается, где проверяются cookie.
Если у нас есть «билет» (выразился словами разработчика сервиса) с посещения сайта — то плейлист корректно генерируется и отдает нам ссылки на файлы с записью канала. Пример ссылки на одну из записей:

tvali.ge/c.php?action=010102&vid=010102-06-12-00-00.mp4

Плейлист генерируется в зависимости от того, что мы ему передали в параметре "?d=". А там — время в секундах с начала недели (округляя по минутам (5)) и минус 10 минут (задержка трансляции).
Без cookie мы получим ссылку на одну запись, скриншот которой предоставил выше.
www.tvali.ge/noaccess.flv
Как выяснилось, cookie проверяются и при обращении к файлу. Так что без них мы никак не сможем «стянуть» файл к нам.

Начинаем реализовывать копию сервиса
Скачиваем файлы к себе

Разберем имя файла — 06-12-35-00
06 — день недели
12 — часы
35 — минуты
00 — секунды
Отлично! Идем писать скрипт, который будет скачивать файлы к нам

<?php
set_time_limit(0);

function curl_get_file_contents($URL) {
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt($c, CURLOPT_COOKIE, 'CO=cookie_from_service');
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
curl_close($c);
if ($contents) {
	$out_handle = fopen ('/var/www/domain/videos/'.substr($URL, -12), "wb+");
	fwrite ($out_handle, $contents);
}
}
//корректировка времени. У меня разница с ресурсом 2 часа. 15 минут - это прозапас
$mod_time = time() - 2*60*60 - 15*60;
$min = floor(date("i", $mod_time)/5)*5;
if ($min < 10) $min = '0'.$min;
$hours = date("H", $mod_time);
$vid = "010102-0".date("w", $mod_time)."-".$hours."-".$min."-00.mp4";
curl_get_file_contents('http://tvali.ge/c.php?action=010102&vid='.$vid);
echo 'http://tvali.ge/c.php?action=010102&vid='.$vid;
?>


И так, у нас есть скрипт, выполнение которого мы добавим в cron (каждые 5 минут)
*/5 * * * * /usr/bin/php /var/www/downloader.php

Плеер

Схема плеера, что на самом сервисе:
получил плейлист -> разделил все записи пополам и начал показывать с нее.
Пишем генератор плейлиста:

<?php
$mod_time = time() - 2*60*60 - 17*60 - 12*60*60;
$links = "<playlist version = \"1\"><trackList>";
$titles = "";
for ($i = 0; $i< 288; $i++) {
	$min = floor(date("i", $mod_time)/5)*5;
	if ($min < 10) $min = '0'.$min;
	$hours = date("H", $mod_time);	
	if ($hours < 22) $title = $hours+2;
	    else $title = $hours-22;
	$title .= ":".$min;
	$links .= "<track><title>$title</title><location>http://domain/videos/$hours-$min-00.mp4</location></track> ";
	$mod_time += 300;
}
echo $links."</trackList></playlist>";
?>

Как видно генератор плейлиста в отличии от оригинального не учитывает параметр даты, его попросту нет. Я решил что это более верный вариант, определять реальное время на сервере, нежели пользователя, чтобы избежать возможных ошибок при работе с плеером.
Собственно все, обязательно скачиваем к себе флеш плеер данного ресурса, меняем var fn =… на адрес со скриптом плейлиста и смотрим спорт в отличном качестве в локальной сети.

Возможно кто-то скажет «бессмысленно смотреть спорт с запаздыванием в 20 минут», но это пока единственный вариант.
P.S. Можно таким же способом «вытягивать» и другие каналы, но тот же «СТС» по вечерам у них обрывается, записи по 1-2 минуты (а должны быть по 5).
Tags:
Hubs:
+8
Comments 11
Comments Comments 11

Articles