Wednesday, December 31, 2008

Как весело провести праздники

Ситуация самая простая: если есть коллекция музыки и видео в одном месте, то нет ничего глупее, чем таскать части коллекции за собой, как прицепившиеся колючки лопуха. Это кажется вполне очевидным, что удобнее to stream media files over a network, чем с грустью вспоминать, как последний альбом Eluveitie остался лежать дома, а на ступеньках парадного лед, который никто не желает убирать, а еще что Днепр зимой похож на Волгу, потому что проплыть по нему можно только на ледоколе. Вспоминать, что с неба сыпет белая дрянь, а по утрам, заканчивая завтрак, с особенной ненавистью поглядывать на последнюю страницу Коммерсанта, где напечатанная температура в Сиднее будит одновременно удрученность и поток проклятий на свой адрес.

Так вот. Чтобы не быть полевым хорьком, бегающим в зубах с flash дисками и dvd (навсегда и безнадежно устаревшей чепухой), нужно поднять RTP сервер для трансляции музыки и видео в то место, где ты находишься. Это, кажется, ясно решительно всем.

Проблемы начинаются, когда узнаешь, что divx/xvid файлы нужно перекодировать в нечто, поддающееся, говоря русским языком, seekable'льности по RTSP. Например, mpeg-4. Это касается фильмов; с музыкой проще, т.к. пустить по RTP mp3 файл можно достаточно легко и без всякой перекодировки, например, посредством live555MediaServer, который идет в качестве example в комплекте c liveMedia. В качестве домашнего задания читателю можно предложить упражнение по написанию простого web-каталога с генерацией списка коллекции в виде rtsp:// ссылок.

Какой RTP и RTSP сервер выбрать? Я провел очень плохой вечер копошась с ffmpeg и vlc, чтобы потом совершенно случайно узнать, что у меня vlc был собран без faac и faad2 и мой аккуратно сварганенный тестовый sample.mp4 (ffmpeg'ом и mp4creator'ом из mp3-файла) vlс игнорировал не потому что у него вредный характер, а потому что у кого-то кривые руки.

Впрочем, Darwin Streaming Server (DSS) есть давно в портах FreeLSD, и списком зависимостей, в отличие от ffmpeg и vlc, испугать не способен. Кроме того, многие клевещут, что с ним "все работает".

Ладно. Собираем порт, читаем pkg-message и хватаеся за сердце: Mozilla, Netscape4/7 and Opera etc... are not useful. DSS Administration Tool requires MSIE(4.5 and later) J-Script feature. Пробуем DSS Administration Tool из firefox и видим, что не все так страшно.

Когда я вижу конфигурационные файлы в xml (а /usr/local/etc/streaming/streamingserver.xml им в Darwin Streaming Server и является), то всегда вспоминаю теплые слова Торвальдса по поводу конфигурационных файлов Gnome:

In past discussions, I've seen people think that since I'm a "developer", I should use a text-editor to edit binary configuration files by hand (and anybody who calls XML "text" has drunk a bit too much of the cool-aid).

Не смотря на эту пакость с конфигурированием, DSS запускается без малейших проблем, а gmp4player и vcl счастливо запели мой sample.mp4.

После тяжелой 2-й Пунической войны, народ Рима, не успев вернуть солдат из легионов Спициона в Африке, по совету сената, тут же начал войну Македонскую. Точно так же, закончив с RTP сервером, я начал воевать с Windows Media Player.

Кому дорого свое время, наилучшим решением будет положить на WMP и пользовать для смотрения трансляций версию плеера vlc под Windows. Кому нужен лишний геморрой, будет запускать wireshark, смотреть как WMP посылает по RTSP метод DESCRIBE, читает красивый ответ от DSS с кодом 200, потом, полагая что вы совершенный идиот, попытается спросить ваш http-сервер о наличие sample.mp4 и после этого покажет окошко "с ошибкой", как всегда, дающее абсолютный нуль информации.

Гугление показывает, что WMP умеет streaming только для своих asf и wma, так что не поддавайтесь на рекламу "мы можем rtsp, мы можем mpeg-4". Mpeg-4 оно может только для локальных файлов. В году 2002-м родился enviviotv plugin для WMP, который якобы позволял играть mpeg-4 RTP поток из Darwin Streaming Server, о чем даже писали в Linux Journal. Сейчас от enviviotv на сайте envivio.com отстался только пресс-релиз, а plugin ушел куда-то глубоко под воду, исследовать темные глубины океана. Сегодня, какие-то веселые парни из Elecard Ltd предлагают Elecard AVC Streaming PlugIn for WMP всего за $40, так что если вдруг, то вы знаете что делать; я же скачал неясно какой свежести версию enviviotv.exe и теперь стал особенно восхищаться происходящим.

Во-первых, оно все равно не может распознать mp4 сэмпл'ы идущие в комплекте с Darwin Streaming Server, хотя играет мой sample.mp4 (поправка от 2009-01-03: распознает, если вместо rtsp://foo.bar говорить e-rtsp://foo.bar). Во-вторых, если не трогать настройки enviviotv, при попытке начать издавать звуки, скромный WMP вместе с Vista от радости мигает экраном и показывает вот такое окно:

20 KB

Мне оно очень нравится.

Лечится убиранием галочки с "Use DirectDraw overlays if available" в %SystemRoot%\System32\EnvivioTVSettings.cpl. Btw, EnvivioTVSettings.cpl пускать нужно с правами администратора. Пожалуйста, не спрашивайте меня, почему сделано так удобно, что настройки enviviotv бывают только system wide.

В-третьих, harm, который наносит enviviotv вашему WMP, выразится кроме всего прочего и в том, что при проигрывании локальных файлов mp4 вы получите задержку (буферизации?) как будто они вам передаются по RTP с таким сомнительным рвением, как в России поют гимн. Эй! Dude, который администрирует Linux в потасканном свитере. Да-да, вы. Я вас имею ввиду. Прекратите нам тут на весь зал выводить голосом про белую овечку и продукты Microsoft. Комментарии по этому поводу слушать сил никаких нету. Хотя, конечно, я согласен граждане, иногда, чувствуешь себя ежиком из анекдота.

Thursday, October 30, 2008

Ужасные новости

Какой шторм сейчас в fedora-devel-list. Страсти кипят, шипят, как масло на сковородке. Настоящая буря в стакане.

Висение иксов на tty1 вместо tty7 это, безусловно, крушение всех надежд. Падение Геллы в бурлящий пролив Босфора. Некоторым, правда, кажется, что обсуждение этого больше похоже на мужественную борьбу за тень осла, но таких несознательных людей мы слушать не будем.

Dax Kelson выступает перед пританами. Чело его взволновано, руки дрожат:

This specific Linux behavior is well documented in hundreds of thousand of publications ranging from college text books, HOWTOs, Linux books sold in retail stores, blogs, forums, guides, and training manuals. Making a change invalidates all that published knowledge.

Как только он это произносит, начинаются ристания, кувыркаясь мечутся и здесь и там возницы. Наездники задыхаются от негодования, слышен тяжелый храп лошадей. Зрители падают ниц без сил.

Пользователь fedora:

(закрывая лицо руками)
Погиб я! О бесчестные, что поменяли tty7 на tty1!
Ради богов,
Примите плащ мой, я бегу.
(убегает, рыдая)

Saturday, October 11, 2008

Capturing output of Expect [send] command

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

Правильно сформулированный вопрос стоит так: я посылаю с [send] текст и желаю получить ответ не просто поймав его посредством [expect], но желаю иметь этот output в переменной для моей-не-скажу-для-чего прихоти.

Короткий ответ на такой вопрос будет такой: см. на переменную expect_out, которую заполняет [expect]. Это обычный Tcl array. Лучше всего понять, как он заполняется, это написать

flush stdout
parray expect_out

Где нибудь в конце вашего диалога со spawn'еной программой. Для окончательно ясности, напишем 2 скрипта: 1-й на sh, который будет программкой с которой будет работать 2-й скрипт, написанный на Expect.

% cat foobar.sh
#!/bin/sh

printf "Please enter your name: "
read name

[ -z "$name" ] && {
  echo "For what such secretiveness?"
  exit 1
}

echo -- Thank you, $name

Все что сделает наш второй Expect-скрипт, -- это избавит вас от утомительной работы по введению имени, которое потребует foobar.sh.

% cat foobar-expect.tcl
#!/bin/sh
# -*-tcl-*- \
# the next line restarts using expect \
exec expect "$0" "$@"

set cmd ./foobar.sh
set timeout 5
if {[catch {
  spawn -noecho $cmd
} r]} {
  puts stderr "$argv0 error: $r"
  exit 1
}

log_file -noappend temp-file
expect "Please enter your name: "
set name "Jeeves"
#set name ""
exp_send "$name\n"
expect {
  -re "Thank.* ${name}\r\n$" { puts "-- Yes, sir." }
  timeout {
      send_user "timeout because there was no prompt\n"
      exit 1
  }
}

flush stdout
parray expect_out

set status [wait $spawn_id]
if {[lindex $status 2] == 0} {
  exit [lindex $status 3]
}

Теперь запустим foobar-expect.tcl, чтобы окончательно разобраться с expect_out:

% ./foobar-expect.tcl
Please enter your name: Jeeves
-- Thank you, Jeeves
-- Yes, sir.
expect_out(0,string) = Thank you, Jeeves

expect_out(buffer)   = Jeeves
-- Thank you, Jeeves

expect_out(spawn_id) = exp4

$expect_out(0,string) содержит именно то, что мы поймали командой [expect] после [exp_send]. Чтобы посмотреть на полный диалог, загляните в появившийся файл temp-file, создаваемый командой [log_file].