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 2. SoundManager - это javascript API к модулю на Flash для проигрывания звуковых файлов.

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:
<?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:
<?php
  // тут я читаю wav-ку из файла для примера, 
    // в реальности будет использоваться выборка из базы данных   
    readfile('sample.wav');
?>

Код out.php:
<?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');

Комментарии: 2 to “PHP. Перекодировка wav в mp3 “на лету”.”

  1. Морозов сказал:

    А типа кэширование… и все такое? Зачем один и тот же вав конвертить при каждом прослушивании? И вообще как производительность?

  2. baranoff сказал:

    Конечно, нужно кешировать уже перекодированные файлы. Добавил замечание в статью.

Оставить комментарий

BlogMemes.ru