サイズが不明でサイズが増加しているリモートファイルで PHP readfile 関数を使用することは可能ですか? シナリオは次のとおりです。
サードパーティの Web サイトからビデオをダウンロードし、同時にビデオを MP3 形式にトランスコードするスクリプトを開発しています。この MP3 は、readfile を介してユーザーに転送されます。
上記のプロセスに使用されるクエリは次のようになります。
wget -q -O- "VideoURLHere" | ffmpeg -i - "Output.mp3" > /dev/null 2>&1 &
そのため、ファイルの取得とエンコードが同時に行われます。上記のプロセスが進行中のとき、出力 mp3 を readfile 経由でユーザーに送信し始めます。問題は、エンコード プロセスに時間がかかるため、ユーザーのダウンロード速度によっては、ファイル全体がエンコードされる前に readfile が推定 EoF に達し、ユーザーが部分的なコンテンツや不完全なファイルを受け取ることになります。
これを修正するための最初の試みは、ユーザーのダウンロードに速度制限を適用することでしたが、エンコード時間と速度は負荷によって異なり、部分的なダウンロードにつながるため、これは絶対確実ではありません.
エンコーディングと同時にダウンロードを提供し、完全なファイルをエンドユーザーに送信することを保証できるように、このシステムを実装する方法はありますか?
どんな助けでも大歓迎です。
編集: ピーターに応えて、私は実際に fread(read readfile_chunked) を使用しています:
<?php
function readfile_chunked($filename,$retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$totChunk = 0;
$buffer = '';
$cnt =0;
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
//usleep(120000); //Used to impose an artificial speed limit
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
readfile_chunked($linkToMp3);
?>
ユーザーのダウンロード速度とエンコード速度によっては、早期に EOF() に到達する可能性があるため、これは完全なダウンロードを保証するものではありません。
また、Jeztah のコメントに応えて、ユーザーを待たせることなくこれを達成しようとしています..それはオプションではありません。