PHP Lame流过滤器

发布于 2024-09-15 15:35:14 字数 1845 浏览 4 评论 0原文

我的任务是制作一个嵌入页面的 mp3 播放器,该播放器将播放数据库中存储的一些语音消息。有些消息以 WAV 格式存储,因此必须将其转换为 mp3。转换应该“即时”完成。由于并非所有消息都必须转换,因此我认为使用流过滤器是一个好主意,该过滤器将在需要时使用。

class LameFilter extends php_user_filter
{
  protected $process;
  protected $pipes = array();

  public function onCreate() {
    $descriptorspec = array(
       0 => array("pipe", "r"),
       1 => array("pipe", "w"),
       //2 => array("pipe", "w"),
    );

    $this->process = proc_open('lame --cbr -b 128 - -', $descriptorspec, $this->pipes);
  }

  public function filter($in, $out, &$consumed, $closing) {
    while ($bucket = stream_bucket_make_writeable($in)) {

      fwrite($this->pipes[0], $bucket->data);

      $data = '';
      while (true) {
        $line = fread($this->pipes[1], 8192);
        if (strlen($line) == 0) {
            /* EOF */
            break;
        }
        $data .= $line;
      }

      $bucket->data = $data;
      $consumed += $bucket->datalen;
      stream_bucket_append($out, $bucket);
    }
    return PSFS_PASS_ON;
  }

  public function onClose() {
    //$error = stream_get_contents($this->pipes[2]);
    fclose($this->pipes[0]);
    fclose($this->pipes[1]);
    //fclose($this->pipes[2]);
    proc_close($this->process);
  }
}

/* Register our filter with PHP */
stream_filter_register("lame", "LameFilter")
  or die("Failed to register filter");

$mp3 = fopen("result.mp3", "wb");

/* Attach the registered filter to the stream just opened */
stream_filter_append($mp3, "lame");

$wav = fopen('ir_end.wav', 'rb');
while (!feof($wav)) {
  fwrite($mp3, fread($wav, 8192));
}

fclose($wav);
fclose($mp3);

在示例中,我使用了从一个文件读取并写入另一个文件的方法。但实际上数据是从 OCI-lob 读取的,并且必须写入 STDOUT。

问题在于“$line = fread($this->pipes[1], 8192);”行实际上独立于预期数据长度阻止脚本。

有没有正确的方法从进程中读取而不关闭其 STDIN?

I have a task to make an mp3 player embedded on a page that will play some voice messages stored in database. Some of messages are stored in WAV-format, so they must be converted to mp3. The conversion should be done "on fly". Because of not all messages have to be converted, I desided that it will be a good idea to use a stream filter that will be used when needed.

class LameFilter extends php_user_filter
{
  protected $process;
  protected $pipes = array();

  public function onCreate() {
    $descriptorspec = array(
       0 => array("pipe", "r"),
       1 => array("pipe", "w"),
       //2 => array("pipe", "w"),
    );

    $this->process = proc_open('lame --cbr -b 128 - -', $descriptorspec, $this->pipes);
  }

  public function filter($in, $out, &$consumed, $closing) {
    while ($bucket = stream_bucket_make_writeable($in)) {

      fwrite($this->pipes[0], $bucket->data);

      $data = '';
      while (true) {
        $line = fread($this->pipes[1], 8192);
        if (strlen($line) == 0) {
            /* EOF */
            break;
        }
        $data .= $line;
      }

      $bucket->data = $data;
      $consumed += $bucket->datalen;
      stream_bucket_append($out, $bucket);
    }
    return PSFS_PASS_ON;
  }

  public function onClose() {
    //$error = stream_get_contents($this->pipes[2]);
    fclose($this->pipes[0]);
    fclose($this->pipes[1]);
    //fclose($this->pipes[2]);
    proc_close($this->process);
  }
}

/* Register our filter with PHP */
stream_filter_register("lame", "LameFilter")
  or die("Failed to register filter");

$mp3 = fopen("result.mp3", "wb");

/* Attach the registered filter to the stream just opened */
stream_filter_append($mp3, "lame");

$wav = fopen('ir_end.wav', 'rb');
while (!feof($wav)) {
  fwrite($mp3, fread($wav, 8192));
}

fclose($wav);
fclose($mp3);

In example I used reading from one file and writing to another one. But actually data is read from OCI-lob and must be written to STDOUT.

The problem is that line "$line = fread($this->pipes[1], 8192);" blocks the script actually independently on expected data length.

Is there any correct way to read from process not closing its STDIN?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兮颜 2024-09-22 15:35:14

作为此解决方案的替代方案,您是否考虑过将 BLOB 保存到临时文件并使用 lame 转换临时文件,以便您可以仅使用 popen() 将结果流式传输回来?

As an alternative to this solution, have you considered saving the BLOB to a temporary file and using lame to convert the temporary file so you can just use popen() to stream the results back?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文