3

私はLAMP環境でCakePHP 1.3プロジェクトに取り組んでおり、外部に多数のビデオを保存し、CakePHPのメディアビュー/app/webroot/を使用してそれらを提供しています(ファイルに直接アクセスしたくないため、これを行います)。しかし、これらのビデオを Media Views 経由で iOS デバイス (iPhone、iPad など) に配信するのに問題があります。

テスト ビデオをどこかに配置/app/webroot/して、iOS デバイスで直接アクセスすると、期待どおりに再生できるので、MOOV の問題やビデオ自体の別のエンコーディングの問題ではないと確信しています。私が知る限り、iOS デバイスがビデオをロードするときに使用するバイト範囲リクエストの CakePHP の処理 (またはその欠如) と関係があります。

残念ながら未回答の Stack Overflow チケットがもう 1 つありますが、詳細は同様の問題です。/cake/libs/view/media.phpクラス ファイルを見ると、メソッド内に値render()のチェックを指示する if ステートメントがあります。$_SERVER['HTTP_RANGE']しかし、私がテストで知る限り、この値は設定されていません (少なくとも CakePHP がそれを探すときはそうではありません)。前述のチケットにリンクされているオフサイト ソリューションは、この値のチェックにも依存しているため、私の問題を解決しません。Media View クラス自体またはコントローラーのいずれかでチェックしたときに、この値が見つからないことを確認しました。上記のビューを設定します。

では、CakePHP Media Views を使用して、iOS デバイスまで動画を配信した経験のある人はいますか? 前もって感謝します!

4

1 に答える 1

2

私がウェブ上に投稿したさまざまな質問にヒットしなかった後、私たちはこれをもう一度調べて、それを理解することができました.

これは、Media.php クラス ファイル ( /cake/libs/view/media.php) の問題であり、HTTP_RANGE ヘッダー値の期待と、後続のヘッダーのフォーマット方法に問題があることが判明しました。まず、関連する元のコード スニペットを次に示します。

$httpRange = env('HTTP_RANGE');
if (isset($httpRange)) {
    list($toss, $range) = explode('=', $httpRange);

    $size = $fileSize - 1;
    $length = $fileSize - $range;

    $this->_header(array(
        'HTTP/1.1 206 Partial Content',
        'Content-Length: ' . $length,
        'Content-Range: bytes ' . $range . $size . '/' . $fileSize));

    fseek($handle, $range);
}

数値であるかのように使用される値をlist()設定する呼び出しに注意してください。$rangeただし、ヘッダー呼び出しをさらにデバッグした後、HTTP_RANGE 値が実際には、指定されRange: bytes=0-1000た数値範囲が要求に依存する場所として指定されていることに気付きました。次の変更を行い (Media View 呼び出しでダウンロード ブール値を true に設定)、ほら、iOS デバイスでビデオが動作するようになりました。

$httpRange = env('HTTP_RANGE');
if (isset($httpRange)) {
    $start = 0; //start byte
    $end = $fileSize - 1; //end byte
    $length = $fileSize; //content length

    $c_start = $start; //default value
    $c_end = $end; //default value
    list($toss, $range) = explode('=', $httpRange); //extract range

    //grab range value(s)
    if ($range[0] == '-') {
        $c_start = $fileSize - substr($range, 1);
    } else {
        $range = explode('-', $range);
        $c_start = $range[0];
        $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $fileSize;
    }

    //validate end byte
    $c_end = ($c_end > $end) ? $end : $c_end;

    //set new values
    $start = $c_start;
    $end = $c_end;
    $length = $end - $start + 1;

    $this->_header(array(
        'HTTP/1.1 206 Partial Content',
        'Content-Length: ' . $length,
        'Content-Range: bytes ' . $start . '-' . $end . '/' . $fileSize));
    fseek($handle, $start);
}

これには、さまざまなケースを処理するこの記事の付録 A のロジックの多くが組み込まれていることに注意してください。(当初、私たちはこのロジックの多くを避けていました。再生は問題なく機能していましたが、iOS デバイスでファイルの最後に到達すると、動作がおかしくなったように見えました。)

于 2012-11-20T01:36:35.443 に答える