PHP Lame流过滤器
我的任务是制作一个嵌入页面的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
作为此解决方案的替代方案,您是否考虑过将 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?