2016-02-21 36 views
4

我需要將幾個mp3文件合併爲一個。有沒有比file_get_contents更廣泛或更有效的合併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,這是我的電腦內存,它不起作用。

回答

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 tops)是可以的。您也可以手動讀取/寫入塊,而不是使用stream_copy_to_stream(),但總體思路是相同的。

這應該導致實際存儲在內存中的文件少於一個。

+0

謝謝,這與默認的內存,我打算標記爲已解決 – user3808307

+0

真棒,謝謝,很高興我可以幫助! PHP的「流」功能非常酷。 – Will

+0

並感謝您的編輯! – Will

1

您可以使用sox,它爲我工作了幾次

+0

這似乎很有趣,我會去看看,謝謝 – user3808307

1

在您的示例中,您將所有文件複製到內存,並在作業完成後將它們寫回磁盤。

我的建議是:

  1. 複製的第一個文件到新的位置
  2. 獲得第二個文件的內容,並把它添加到複製文件(file_put_contens FILE_APPEND)
  3. 未設置與變量內容
  4. 繼續第2步,直到完成
+0

我會試試這個,謝謝 – user3808307

+0

謝謝,這個作品很棒。太糟糕了,我不能有兩個接受的答案。我會堅持這個,因爲它更接近我原來的方法 – user3808307

相關問題