PHP

携帯3キャリア対応 動画配信(2)

さて、前記事ではキャリアごとのダウンロード方法の特徴をつかむことができました。
今回はそれを元にスクリプトを修正します。

スポンサーリンク

スクリプトの改良

docomoのサイトによると、RangeRequest(部分リクエスト)に対応するにはLast-Modified、Accept-Ranges、Content-Type、Content-Rangeの各ヘッダが必須となっています。
念のためですが、ApacheはE-Tagも吐き出しているのを確認したので、それも追加することにします。
auも部分リクエストに対応する必要がありますが、docomoの対応と同じだと思うので、docomoが出来ればauも一緒に対応できそうです。
If-Unmodified-Sinceヘッダに対する振る舞いは良く知らないので適当にあしらっておきました。
そんなわけで改良版のスクリプトは以下のような感じ。($file_path, $mime_typeには本来キャリアごとの動画ファイルのパス、適切なMIMEタイプが入る)

// docomoやsoftbankの場合
$file_path = "/path/to/movie.3gp";
$mime_type = "video/3gpp";

$file_size = filesize($file_path);

if (($fp = fopen($file_path, "rb")) === false) {
    header(" ", true, 404);
    die;
}

$modified = gmdate("D, d M Y H:i:s", filemtime($file_path)) . " GMT";
$stats = stat($_SERVER['SCRIPT_FILENAME']);
$etag = sprintf('"%x-%x-%x"', $stats['ino'], $stats['size'], $stats['mtime']);
header("Last-Modified: " . $modified);
header("ETag: ".$etag);
header("Accept-Ranges: bytes");

// 更新日時の確認
$requests = apache_request_headers();
if (isset($requests["If-Unmodified-Since"]) && $requests["If-Unmodified-Since"] != $modified) {
    header(" ", true, 412);
    fclose($fp);
    die;
}

// RangeRequest対応
if (!empty($requests["Range"])) {
    list($range_begin, $range_end) = sscanf($requests["Range"], "bytes=%d-%d");
    $content_length = $range_end - $range_begin + 1;
    fseek($fp, $range_begin, SEEK_SET);
    header("HTTP/1.1 206 Partial Content", true, 206);
    header("Content-Range: bytes {$range_begin}-{$range_end}/{$file_size}");
} else {
    $content_length = $file_size;
}

header("Content-Length: " . $content_length);
header("Content-Type: " . $mime_type);

// ファイル内容出力
echo fread($fp, $content_length);
flush();

fclose($fp);

結果

なんとかうまくいきました。3社とも無事にダウンロード&再生できています。
ちなみにPHPのデフォルト設定だと、レスポンスヘッダにPHPのバージョン情報が付加されてダウンロード不可になってしまうことがありますので、php.iniでexpose_phpをOffにします。
「expose_phpって何?それっておいしいの?」って方は下記リンクを参照ください。

コア php.ini ディレクティブに関する説明

まとめ

docomo

500KBまで → GETで一括取得
500KB以上 → 最初の受信でヘッダを解析し、後はRangeRequestで分割してダウンロードする。

au

最初にHEADでヘッダだけを取得した後にRangeRequestによる分割ダウンロードを行う。一回の要求サイズは126.5KB程度。

softbank

GETで一括取得。

今回の件は参考になったでしょうか。

スポンサーリンク
記事を書いた人

システムえんじにゃー🐈
趣味はエレキギター、自転車など。作曲したい。
World of Warshipsやってます。
記事に関する質問はお気軽にどうぞ。

surface0 (さーふぇす)をフォローする

コメント

タイトルとURLをコピーしました