Введение

PC-ОС

БП

Дисплей

Координатор

Подробнее о проблемме

Плейер должен воспроизводить файлы подряд, обходя все директории, включая вложенные, начав с /Data/_music. Он должен помнить название последнего воспроизводимого файла и при выключении/включении питания продолжать воспроизведение с него. Коллекция включает в себя несколько тысяч файлов, около нескольких сотен каталогов, уровень вложенности которых достигает 4-5 уровней (_Instrumental/Vasja Ivanov/1924 Leto na крыше/01-Bye bye may mind.mp3). Список воспроизведения должен быть отсортирован по алфавиту (произведение может иметь несколько дорожек, порядок которых важен; исполнитель может иметь несколько альбомов - имеет смысл расставить их по годам выхода), из него имеет смысл исключить испорченные файлы.

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

Но полный обход дерева файлов такого объёма требует времени. И немало - моя машина все требуемые проверки и сортировки выполняет примерно за 10-15 минут. Такая задержка при старте системы выглядит чрезвычайно грустно, поэтому было решено составлять playlist параллельно с воспроизведением. Итак: фоновая индексация коллекции.

Решение

В самом первом разделе, где рассматривался выбор ОС и настройка скриптов инициализации, мы закончили на упоминании файла /sbin/mywrap. Этот файл будет запущен после загрузки ОС и проведения необходимых процедур настройки (вроде установки IP-адресов на сетевых интерфейсах). Его содержимое таково (вспоминаем синтаксис shell'a... ну или верим моим объяснениям ;) ):

#!/bin/sh

if [ -x /Data/main ]; then
  /Data/main "$*"
else
  echo "No /Data/main"
  sleep 5
fi

Он просто проверяет наличие и возможность запуска файла /Data/main и при его присутствии передает ему управление. Как вы помните, /sbin, а значит и /sbin/mywrap находится на системном несъемном HDD, в то время как /Data/main - на съёмнике. Задача mywrap - просто убедиться в доступности файловой системы съёмника и либо запустить плейер либо указать в консоли на наличие проблеммы. Задержка в 5 секунд позволяет избежать лишней нагрузки на процессор (/sbin/init будет пытаться перезапустить mywrap сразу после его завершения).

Содержимое /Data/main:

#!/bin/sh

cd /Data/_prog
stty -F /dev/ttyS0 57600 raw
nice -n 19 ./index &
date >> ctrl.log
./ctrl && shutdown -h now
exit 0

Задача этого файла - подготовить com-порт и разделить поток исполнения: основным процессом работает плейер (его я опишу в следующем разделе) и фоновым (с нижайшим приоритетом) - индексатор коллекции. Причем, в зависимости от кода завершения программы ctrl, скрипт может попытаться остановить ОС. Если же он этого не сделает, /sbin/init снова перезапустит плейер и индексатор.

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

#!/bin/sh

fr=/Data/_music
[ "$1" ] && fr="$1"

find "$fr/" -type f | sort | file -if - > list.all
grep ":.*audio/" list.all | sed 's|:.*||g' > list.aud
#egrep -i "\.(mp3|wav|wma|mid)" list.all | sed 's|:.*||g' > list.ext
fgrep -i ".mp3" list.all | sed 's|:.*||g' > list.ext
diff list.aud list.ext > list.dif


date >> list.ext
mv list.ext list.use

Он действует следующим образом: в первую очередь утилитой find составляется список всех файлов, имена которых оканчиваются на ".mp3". В коллекции есть и другие файлы: txt - комментарии, avi - видеоролики, jpg - фотографии, попадаются и музыка в других форматах - ogg, mid, stm.... mpg321 их не знает и поэтому индексатор их игнорирует. Затем по отобранным файлам пробегается утилита file - она по характерным признакам содержимого файла пытается оценить - на самом ли деле он является mp2 или mp3 ? Сюда можно было бы ещё добавить какой-нибудь mp3check или mp3ck. По составленному find и file списку утилитой diff вычисляется дифферент - список файлов с расширением mp3, но странным содержимым. Его я просто иногда изучаю. Наконец, если индексация успешно завершена, новый список сменяет старый одной командой mv. Изначально я использовал в качестве результирующего списка тот, что давала file, но затем перешел на список, составленный только по расширениям - file иногда ошибается, если файл имеет странности (вроде 512-и байт нулей в начале), но плейер его воспроизводит. При очередном обновлении коллекции такие файлы будут исправлены чем нибудь вроде mp3asm.

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

Владимир