LXF125:Perl

Материал из Linuxformat.

Перейти к: навигация, поиск
Hardcore Linux Проверьте себя на крутом проекте для продвинутых пользователей

Содержание

Perl: Запишем любую передачу

Автоматизируйте запись вашего ТВ с помощью Perl. Стив Прайс покажет, как просто создать мультитюнеровый ТВ-рекодер.

Вы наверняка когда-нибудь да хотели сделать автоматическую запись телепередач на компьютере с Linux – дело стало только за правильной установкой MythTV. А как насчет свободной программы, которая автоматически составит расписание записей ваших любимых передач? Или – как вам идея получить готовый цифровой видеомагнитофон, всего-навсего воткнув в USB-разъем новое устройство? Если на оба эти вопроса вы ответили «Да», то этот урок – для вас: здесь я пока жу, как использовать Perl’овский модуль (Linux::DVB::DVBT) для управления DVB-t ТВ-тюнерами.

Прежде всего решите, какой тюнер купить. Я рекомендую USB-устройство Hauppauge WinTV-NOVA-t (его обзор см. в LXF106), простое в настройке и обеспечивающее хорошее качество картинки. Дополнительным преимуществом использования USB-устройств по сравнению со встраиваемыми картами является возможность добавлять тюнеры в любой момент, и это не повлияет на компьютер. Перед походом в магазин, однако, не мешает выяснить, какие тюнеры поддерживаются вашим дистрибутивом. Запустив приложение по настройке ТВ-карты, можно получить много полезной информации: например, выведется список поддерживаемых производителей и моделей, которые должны работать на вашей машине.

Правильное оборудование

Какой бы тюнер вы ни купили, я не устану подчеркивать, насколько важно использовать хорошую антенну, а не ту, что поставляется с тюнером. У вас будет намного лучшая картинка (да и с начальной настройкой будет полегче), если антенна дает хороший сигнал. Простейший способ отделаться – подключить к имеющейся антенне усилитель с несколькими выходами, а на один из свободных портов навесить новый тюнер.

Часть 1: Установка

Без паники! Просто поищите необходимый ядру файл прошивки и скопируйте его в правильный каталог.

Обзаведясь тюнером и вставив его в свою систему, запустите утилиту установки ТВ-карты и выберите свой тюнер в списке. Этого должно хватить. Заметьте, я сказал «должно»: если возникнет проблема, то, скорее всего, у вас не загружена прошивка карты, и установить ее придется самому. Не пугайтесь: это проще, чем кажется. Сначала взгляните на сообщения в /var/log/messages и поищите там указания на доступ к аппаратной части тюнера. Если вы нашли сообщение типа «Did not find the firmware file», то вам придется поискать в сети двоичный файл прошивки, на который указывает то сообщение. Скорее всего, это будет файл с расширением FW (например, моему тюнеру Hauppauge пона добился файл прошивки под названием dvb-usb-dib0700-1.10.fw). Просто погуглите данное имя файла; сайт производителя или вики MythTV – также отличные места для поиска.

Отыскав и скачав файл прошивки, скопируйте его в каталог прошивок вашего дистрибутива (обычно это /lib/firmware). Например:

sudo cp dvb-usb-dib0700-1.10.fw /lib/firmware

После установки прошивки нужно, чтобы ядро загрузило ее в тюнер. В случае USB-устройства просто отсоедините его и присоедините обратно; в случае карт PCI вам придется перезагрузиться. Если карта определится правильно, то в файле сообщений вы увидите фразу типа «Firmware started successfully». Можете побаловать себя чашечкой кофе, прежде чем перейти ко второму этапу, но пока чайник еще не вскипел, давайте сделаем отступление и пообсуждаем поддержку устройств.

Во время работы ваш тюнер фигурирует как отдельное устройство в каталоге /dev, почти как CD-ROM. Однако, в отличие от CD-ROM’а, тюнер состоит из нескольких устройств, каждое из которых отвечает за свой аспект приема ТВ-сигнала (я буду называть их набором устройств). Эти устройства объединены в каталог под названием adapter, который представляет тюнер как целое. Так как к системе может быть подключено несколько тюнеров, каждый из них представлен своим каталогом адаптера, которые нумеруются, начиная с 0. Заглянув в каталог устройств, вы увидите, что его структура имеет примерно такой вид:

/dev/dvb/
 adapter0/
  demux0 dvr0 frontend0
 adapter1/
  demux0 dvr0 frontend0
  demux1 dvr1 frontend1

Устройства из каталога adapter контролируют разные аспекты тюнера: frontend выбирает правильную полосу частот; demux управляет выбором канала; а dvr выдает сырой поток вещания (видео), используемый при записи передач. Как и при нумерации адаптеров, если в адаптере имеется несколько приемников, то существует несколько наборов устройств, и они нумеруются, начиная с 0. Модуль Perl обеспечивает интерфейс для этих устройств. Если таковых несколько, нужно указать номер адаптера и номер устройства, которое вы хотите использовать. Для указания номера набора устройств модуль Perl использует поле frontend_num (подробности ниже).

Установка

Теперь, когда ваше оборудование заработало, перейдем к установке ПО. Самый легкий способ сделать это – зайти от имени root и запустить скрипт cpan, который поставляется с установкой Perl’а:

sudo cpan Linux::DVB::DVBT

Будет установлен модуль Linux::DVB::DVBT, а заодно автоматически учтутся все требуемые зависимости. Обратите внимание, что при первом запуске установки со CPAN вам зададут много вопросов. Ответов, предлагаемых по умолчанию, обычно достаточно для правильных настроек.

Скорая помощь

Полезно помнить: каждый час записи требует примерно 1 ГБ дискового пространства. Так что озаботьтесь покупкой большого диска исключительно под эти нужды (вы ведь не хотите, чтоб ваш сервер рухнул под тяжестью записи Дома-2, ха-ха).

Альтернатива – скачать модуль из CPAN и выполнить ручную компиляцию и установку (правда, отсутствующие зависимости придется накопать самим):

perl Makefile.PL
make test
sudo make install

При этом не только добавится Linux::DVB::DVBT, но вас еще и наградят несколькими скриптами-примерами (dvbt-scan, dvbt-record и dvbtepg). Эти сценарии – полностью работающие варианты тех функций, про которые я расскажу на данном уроке, и если вы не хотите пачкаться с написанием скриптов, можете использовать их.

Установив модуль, можно протестировать его, получив информацию о ТВ-тюнере. Linux::DVB::DVBT обеспечивает объектно-ориентированный интерфейс: как правило, вы создаете экземпляр класса, а затем используете методы данного экземпляра. Для разнообразия, метод device_list(), который мы собираемся рассматривать, использует в качестве экземпляра модуль сам по себе (если вы не знакомы с объектно-ориентированным программированием, бояться нечего: куски кода в примерах прояснят всю картину).

Метод device_list() возвращает массив хэшей; каждый хэш содержит сведения об установленных тюнерах. Эту информацию можно отобразить посредством следующего кода:

#!/usr/bin/perl -w
 use Linux::DVB::DVBT;
 # полу чить список ус танов ленных адап теров
 my @devices = Linux::DVB::DVBT->device_list() ;
 foreach (@devices)
 {
  printf%s : adapter number: %d, frontend number: %d\n”,
  $_->{name}, $_->{adapter_num}, $_->{frontend_num} ;
 }

В результате в виде списка отобразятся номера adapter и frontend для каждого тюнера, а также название изготовителя. Данные номера понадобятся вам, если вы хотите использовать мультитюнеровую запись, так что приберегите их до поры, когда мы этим займемся.

Если ваш тюнер работает, однако никакого вывода о нем не видно, значит, что-то не так. Вернитесь назад и просмотрите ваши файлы журналов на предмет сообщений об ошибках (может быть, вы забыли, что ядро должно перезагрузить прошивку тюнера). Иначе – примите сердечные поздравления: среда для записи передач с вашего ТВ-тюнера готова к работе, и пришло время перейти к чему-нибудь более интересному. Так как мы уже установили аппаратную часть и ПО, и почти закончили с настройкой, то осталась одна задача: настройка оборудования на вещаемые каналы.

Настройка

Самая тяжелая часть данного этапа – раздобыть файл частот, содержащий информацию о вашей местной сети. Тут есть две возможности: если у вас установлен пакет dvb, вы найдете файлы в /usr/share/dvb/dvb-t; если у вас установлен Kaffeine, они будут в $HOME/.kde/share/apps/kaffeine/dvb-t; а не то возьмите их с DVD этого месяца.

Отыскав каталог, выберите файл, соответствующий локальному вещанию. Простейший способ [работает только для Великобритании, – прим. пер.] – зайти на http://www.ukfree.tv/transmitters.php и ввести свой почтовый адрес. Например, для моего местного вещателя это Оксфорд, так что я использую файл uk-Oxford. Вы сразу поймете, что у вас правильный файл, когда увидите в окне терминала список названий каналов. Передайте путь вашего файла частот методу scan_from_file(), откиньтесь на спинку стула и подождите завершения. Соответствующий скрипт выглядит так:

use Linux::DVB::DVBT ;
 ## Создаем dvb-объект (используется первый найденный адаптер).
 my $dvb = Linux::DVB::DVBT->new() ;
 ## Отображать прогресс сканирования
 Linux::DVB::DVBT->verbose(1) ;
 ## Выполнить сканирование (путь подставьте свой)
 $dvb->scan_from_file(‘/usr/share/dvb/dvb-t/uk-Oxford’) ;

Вместо этого можно использовать установленный скрипт

# Опять подставьте свой путь
 dvbt-scan /usr/share/dvb/dvb-t/uk-Oxford

Обратите внимание, что у всех скриптов одна и та же структура: импорт модуля Linux::DVB::DVBT при помощи ключевого слова use; создание нового объекта DVB методом new(); использование методов объекта DVB для некоторых действий. Метод scan_from_file() использует файл частот, чтобы сканировать информацию о вещании: он собирает детали о вещании всех каналов этого передатчика и автоматически записывает ее в файлы настроек в $HOME/.tv. Последние будут использоваться при всех последующих вызовах, так что достаточно запустить его только один раз (даже если у вас подключено несколько тюнеров).

Скорая помощь

Обратитесь к старым журналам Linux Format, и вы многое узнаете о настройке медиа-серверов. Стоит ознакомиться с Mediatomb, Fuppes, Ushare или Twonkyvision.

Часть 2: Запись

Теперь, проделав всю работу по настройке, можно приступить к тому, ради чего мы здесь собрались: записи передач. Модуль Perl обеспечивает два метода, используемые при записи: метод выбора канала select_channel() и метод записи файла record().

Для выбора канала надо всего лишь написать его название:

$dvb->select_channel(‘BBC ONE’) ;

(Приятная особенность select_channel() – то, что он допускает вольное написание имени канала. Вы можете написать название с любым числом пробелов, в произвольном регистре, с цифрами вместо числительных.)

Затем вызовем метод record(): его аргументы – имя видеофайла и время записи.

$dvb->record(‘./test.ts’, ‘00:30’) ;

Записываемый файл обычно снабжают расширением .ts, но это не обязательно, т.к. видеоинформация хранится в формате MPEG 2 Transport Stream. Длительность записи можно выражать количеством секунд (одно число), или в формате ЧАСЫ:МИНУТЫ:СЕКУНДЫ, или, как в примере, в формате ЧАСЫ:МИНУТЫ.

Вместо того, чтобы писать собственный скрипт, можно использовать скрипт dvbt-record, снабдив его теми же параметрами и в том же формате, как описано выше:

dvbt-record ‘BBC ONE’ ./test.ts 00:30

Подождите 30 минут, и у вас появится первая записанная телепередача. Естественно, это можно делать и вручную, всякий раз, когда вам захочется записать передачу. Однако гораздо удобнее взвалить эту работу на машину: тут, естественно, пригодится Cron.

Отредактируйте свой файл Cron с помощью crontab -e Формат файла Cron выглядит примерно так:

МИНУТА ЧАС ДЕНЬ_МЕСЯЦА МЕСЯЦ ДЕНЬ_НЕДЕЛИ ДЕЙСТВИЕ

Обычно для записи время начала передачи (или чуть раньше) задается в формате МИНУТА/ЧАС, дата – ДЕНЬ_МЕСЯЦА/МЕСЯЦ, а в ДЕНЬ_НЕДЕЛИ ставится *. В качестве ДЕЙСТВИЯ укажите вызов записывающего Perl-скрипта (или имеющегося у вас скрипта dvbt-record). Задав ДЕНЬ_НЕДЕЛИ, мы тем самым определим задачу Cron, которая будет выполнять запись раз в неделю. Одиночная запись 2 июля 30-минутной передачи на BBC1, начинающейся в 9:00, выглядит как

00 21 02 07 * dvbt-record bbc1 ~/news.ts 00:30

Одиночная запись часовой передачи, идущей 3 июля на ITV в восемь вечера, но с минутными интервалами в начале и конце, выглядит как

58 19 03 07 * dvbt-record itv1 ~/documentary.ts 01:04

А вот еженедельная получасовая передача на Пятом канале, начинающаяся в 10 вечера по четвергам (здесь 0=воскресенье, 1=понедельник):

00 22 * * 4 dvbt-record five ~/big_bang.ts 00:30

Как вы помните, номер adapter указывает на карту либо USB-устройство. Номер frontend указывает на приемник в адаптере (обычно это 0).

Покамест мы позволяли Perl’у автоматически устанавливать эти номера, в предположении, что тюнер у нас всего один. Если вы махнули рукой на предостережения и купили другой тюнер, то вам, наверно, интересно узнать, как велеть Perl’у использовать это новое устройство. Все, что вам нужно сделать – это указать номера adapter и frontend при создании нового объекта DVB.

Например, для создания объекта DVB, который управляет вторым из ваших тюнеров, пропишите

## Создаем dvb-объект (используется адаптер 1, а не 0.
 my $dvb2 = Linux::DVB::DVBT->new(
 ‘adapter_num’ => 1,
 ‘frontend_num’ => 0,
 ) ;

а затем вызывайте методы этого нового объекта, как делалось ранее (заменив $dvb на $dvb2). Очень просто.

Уникальные имена файлов

Для повторяющихся выпусков программ легко можно случайно перезаписать старые записи. Во избежание этого, используйте команду date для указания имени файла в задаче Cron’а, и имена файлов не будут повторяться. Самый простой способ – использовать команду date с опцией форматирования, добавляющей год, месяц, день, час и минуты как 12-значное число. Команда выглядит так:

dvbt-record five ~/big_bang-`date +”%Y%m%d%H%M”`.ts 00:30

Воспроизведение

Мы задали несколько подходящих задач Cron, и вот уже наш жесткий диск ломится от файлов TS. Что делать теперь? Простейший ответ – хотите, смотрите их прямо так: программы воспроизведения видео (наподобие MPlayer) прекрасно умеют проигрывать файлы потока MPEG 2. Ну, а если замахнуться на большее? Одна из возможностей – потоковая передача наших записей по дому; в этом случае нужно позаботиться, чтобы формат файлов годился для потоковой передачи медиа-сервером. Некоторые серверы (и клиенты) воротят нос от TS-файлов, и перед воспроизведением понадобится их конвертировать.

Для тех файлов, которые вы хотите раз посмотреть, а затем удалить (или если вам не жалко места на жестком диске), самая быстрая конвертация получится при использовании FFmpeg, если перепаковать файл как стандартный файл MPEG 2 командой

ffmpeg -i input.ts -async 1 -vcodec copy -acodec copy -y output.mpeg

Однако любое видео вы, скорее всего, пожелаете сжать как можно сильнее, сохранив качество картинки. Соответствующие командные строки FFmpeg’а имеются на LXFDVD, однако вы обнаружите, что процесс этот не быстр – сжатие часового видео может слопать часов шесть!

Программа передач

Я закончу этот урок, затронув другую возможность, предоставляемую модулем Perl: электронную программу передач. Вызвав метод epg(), можно получить программу передач на следующие две недели. На этих страницах не хватит места, чтобы выложить вам полнофункциональный скрипт для программы передач, но, по крайней мере, основы описать получится.

Вызов метода epg() возвращает две порции информации, каждая по своей ссылке на хэш: обзор передач и даты передач. Даты мы опустим (они пригодятся, только если вы держите программу передач в базе данных), а сосредоточимся на информации о передачах (можете обратиться к документации Linux::DVB::DVBT за деталями о полной структуре хэшей передач и дат). Каждая передача хранится в иерархии хэшей, проиндексированной по имени канала и по уникальной передаче. Чтобы обработать всю программу передач, мы просто пройдем в цикле все каналы и передачи на каждом канале. Например:

Скорая помощь

Для чтения файла сообщений используйте vi: он подсвечивает сообщение, и читать его проще.

## Получить программу передач
 my ($epg_href, $dates_href) = $dvb->epg() ;
 # Отсортировать имена каналов
 foreach $channel (sort keys %$epg_href)
 {
  # для каждой программы
  foreach my $pid (keys %{$epg_href->{$channel}})
  {
  print$channel : $epg_href->{$channel}{$pid}{date} “.
   “$epg_href->{$channel}{$pid}{start} :: “.
   “$epg_href->{$channel}{$pid}{title}\n” ;
  }
 }

Вместо этого можно использовать готовый скрипт:

$ dvbt-epg

На своей системе я храню EPG-данные в базе данных MySQL, а отображаю программу передач в web-приложении, где могу искать передачи и делать расписание записей. Я понял, что мне нужно регулярно обновлять EPG-данные, так как вещатели часто меняют порядок передач по своим капризам. Ежеутреннего обновления данных, скорее всего, достаточно, чтобы время записи было актуальным.

Другая идея, которая вам может понравиться, состоит в создании скрипта, который читает из файла список названий передач. Этот скрипт затем использует последнюю EPG-информацию, чтобы автоматически создавать расписание записи тех передач, названия которых встречаются в файле.

Как видите, запись передач можно сделать простой командной строкой. Также можно заметить, что довольно легко расширить вашу систему до мультитюнерового рекордера, если добавить дополнительные USB-тюнеры. Объедините все вместе, и у вас будет многоканальный рекордер, стоимость которого на порядок меньше стоимости коммерческих решений; а его возможности ограничены только вашим воображением (ну ладно, еще и вашими способностями кодировать в Perl!). LXF

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию