我需要将几个mp3文件合并为一个。
我目前正在这样做:
$combinedFiles = "";
$dir = $_POST['dir'];
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$combinedFiles .= file_get_contents(urldecode($dir."/".$entry));
}
}
closedir($handle);
}
file_put_contents("mp3/".$dir.".mp3", ($combinedFiles));
如果我这样做:
ini_set('memory_limit', -1);
它有效。我已经尝试将此限制设置为4MB,并且它不会引发内存错误,但文件没有创建。没有设置任何限制并保留默认值,我得到分配内存错误。我不想在-1
留下它,因为我读过它是不好的做法,可能导致问题。
谢谢(错误不是来自代码中的任何其他地方,我只是运行它。)
编辑:即使设置为8GB,这是我的电脑内存,它也无法正常工作。
答案 0 :(得分:1)
你可以使用sox,它对我有用了几次
答案 1 :(得分:1)
这种做法怎么样?
<?php
$dir = $_POST['dir'];
if ($handle = opendir($dir))
{
$outFd = fopen(sprintf("mp3/%s.mp3", $dir), 'wb');
while (false !== ($entry = readdir($handle)))
{
if ($entry != "." && $entry != "..")
{
$path = urldecode(sprintf("%s/%s", $dir, $entry));
$inFd = fopen($path, 'rb');
stream_copy_to_stream($inFd, $outFd);
fclose($inFd);
}
}
fclose($outFd);
closedir($handle);
}
现在,我们遇到了一些安全问题,如果没有正确验证输入,如果这是一个公共工具,您应该修复它们。但是现在我只是讨论手头的问题。
为什么我们不首先打开输出文件,然后将每个输入文件复制到输出文件的末尾,而不是将所有这些文件中的数据一次存储在内存中?我们可以使用stream_copy_to_stream()
执行此操作。
我们可以通过stream_set_chunk_size()
使用较小的块大小进行操作,但对于您的应用来说,听起来可以暂时将一个MP3存储在内存中(4-5Mb顶部)。您也可以手动一次只读取/写入一个块,而不是使用stream_copy_to_stream()
,但总的想法是一样的。
这会导致一次实际存储在内存中的文件少于一个。
答案 2 :(得分:1)
在您的示例中,您将所有文件复制到内存,并在作业完成后将其写回磁盘。
我的建议: