1

オーディオ ファイルのストリーミングに使用する Web サイトがあります。主にMP3とOGG。数ヶ月以来、私は自分自身 (PHP) を処理しています (Apache2 になる前)。最初に、マルチメディア オーディオ ファイルのスライスされたバイナリ レスポンスで通常の 200 OK レスポンスを実行します (メモリ割り当て用)。正常に動作していますが、すべてのオーディオで無限の持続時間を取得しました。この質問によると、昨日ストリーミング部分を更新しました。

そして今、私は想像できる最も奇妙なバグの 1 つを持っています。私のコードのリファクタリングは、MP3 ではうまく動作しますが、OGG ではうまく動作しません... 画像、または zip ダウンロードも上記のクラスで動作し、どちらも以前と同じように動作します。

これが私のストリームクラスです。

<?php
class Stream extends Response
{
    protected $filepath;
    protected $delete;
    protected $range = ['from' => 0, 'to' => null];

    public function __construct($filePath, $delete = false, $range = NULL)
    {
        $this->delete = $delete;
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($finfo, $filePath);
        $size = filesize($filePath);

        $this->headers['Content-Type'] = $mimeType;
        $this->headers['Content-Length'] = $size;
        $this->headers['Accept-Ranges'] = 'bytes';
        $this->headers['Content-Transfer-Encoding'] = 'binary';
        unset($finfo, $mimeType);

        $this->code = 200;
        $this->range['to'] = $size - 1;

        if ($range !== NULL) {
            if (preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/i', $range) === false) {
                $this->code = 416;
            } else {
                $ranges = explode(',', substr($range, 6));
                foreach ($ranges as $rangee) {
                    $parts = explode('-', $rangee);
                    $this->range['from'] = intval($parts[0]);
                    $this->range['to'] = intval($parts[1]);

                    if (empty($this->range['to'])) {
                        $this->range['to'] = $size - 1;
                    }
                    if ($this->range['from'] > $this->range['to'] || $this->range['to'] >= $size) {
                        $this->code = 416;
                    }
                }
                $this->code = 206;
            }

        }

        if ($this->code === 416) {
            $this->headers = ['Content-Range' => 'bytes */{' . $size . '}'];
        } elseif ($this->code === 206) {
            $this->headers['Content-Range'] = 'bytes {' . $this->range['from'] . '}-{' . $this->range['to'] . '}/{' . $size . '}';
        }

        $this->filepath = $filePath;
    }

    public function show()
    {
        http_response_code($this->code);

        foreach ($this->headers as $header => $value) {
            header($header . ': ' . $value);
        }

        $file = fopen($this->filepath, 'r');
        fseek($file, $this->range['from']);

        $interval = $this->range['to'] - $this->range['from'];
        $outputBufferInterval = 4 * 1000;
        
        if ($interval < $outputBufferInterval) {
            $outputBufferInterval = $interval;
        }

        ob_start();
        while ($interval > 0) {
            echo fread($file, $outputBufferInterval);
            $interval -= $outputBufferInterval;
            ob_flush();
        }
        fclose($file);
        ob_end_clean();
        
        if ($this->delete) {
            unlink($this->filepath);
        }
    }
}

私は HTTP_RANGE と少し混乱しています。ありがとうございました、

4

0 に答える 0