PHP. Перекодировка wav в mp3 “на лету”.
19/09/2007
Задача.
В базе данных в blob-полях лежат звуковые фрагменты wav.
Необходимо дать пользователям сайта возможность прослушивать их с непосредственно с сайта (не заставлять их скачивать себе на компьютер).
Решение.
Как можно просто (используя dhtml и т.п.) проигрывать wav-файлы на страницах можно посмотреть, например, тут.
Мне не подходят такие варианты решения, потому что:
- физически файла у меня нет и создавать временные файлы я не хочу, хотя можно сделать что-нибудь вроде
<embed src="http://sample.com/getsound.php?id=493" autostart=false width=0 height=0 id="sound1" enablejavascript="true" /> - я хочу дать пользователю больше контроля над проигрыванием звукового фрагмента
soundManager.play('mySound', '/path/to/some.mp3');
К несчастью, он может проигрывать только mp3-файлы, поэтому мне придется написать wav-2-mp3 конвертер, который будет доставать из базы данных wav-файлы, конвертировать их на лету и отдавать браузеру. Написать конвертер это, конечно, громко сказано, я буду использовать lame для конвертации. Это консольное приложение для конвертирования MPEG Audio Layer III (MP3), которое может на вход принимать поток stdin, а на выходе формировать поток stdout.
[root@xxxx lame]# lame -?
LAME 32bits version 3.97 (http://www.mp3dev.org/)
usage: lame [options] [outfile]
and/or can be "-", which means stdin/stdout.
Моя задача - сформировать цепочку команд, в которой первая команда достает из базы wav-строку, вторая команда конвертирует ее в mp3, третья - отдает клиенту.
Код getsound.php:
header('Content-type: audio/mpeg'); $cmd = "/usr/local/bin/php ./in.php | ./lame --cbr -b 128 - - | /usr/local/bin/php ./out.php"; passthru($cmd);
Код in.php:
// тут я читаю wav-ку из файла для примера, // в реальности будет использоваться выборка из базы данных readfile('sample.wav');
Код out.php:
while (!feof(STDIN)) { $line = fgets(STDIN); echo $line; }
Я использовал файл sample.wav для примера. Естественно, реальное приложение должно быть сложнее. Файл getsound.php будет вызываться через http, например, так: http://sample.com/getsound.php?id=493.
Поэтому необходимо позаботиться о фильтрации входного параметра id. Далее, необходимо в цепочку команд добавить параметр запуска скрипта in.php, которой укажет, какую именно запись выбирать из БД. До запуска конвертера можно еще проверить, есть ли запись в БД с таким id и т.д. Также, можно кешировать уже перекодированные файлы.
Код на яваскрипт, который будет загружать файлы во flash-приложение:
soundManager.play('mySound', 'http://sample.com/getsound.php?id=493');
September 19th, 2007 at 12:40 pm
А типа кэширование… и все такое? Зачем один и тот же вав конвертить при каждом прослушивании? И вообще как производительность?
September 21st, 2007 at 4:18 pm
Конечно, нужно кешировать уже перекодированные файлы. Добавил замечание в статью.