このコードは、サーバーを介してリモートビデオファイルをストリーミングするためにしばらく前にWeb上に配置されていましたが、iOS(iPhone 6S、iOS 12.4)を除いて完全に機能します。すでにコードに実装されている「Accept-Ranges」、「Content-Length」、および「Content-Type」ヘッダーを持つことを推奨する大量のスレッドに行きました。iOSは、SafariとChromeの両方でファイルのストリーミングを拒否しています。
どんな助けでも大歓迎です!
編集#1
どうやら私のサーバーは範囲を正しく返していません。Appleは通常、「範囲:バイト= 0-1」のような部分的なコンテンツを最初に要求します。現在、コードからの応答を待って立ち往生しています。また、Safari formacOSで動作しないことも確認しました。ああアップル。
ini_set('max_execution_time', 0);
$useragent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36";
$v = 'https://notmywebsite/remotevideo.mp4';
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 222222);
curl_setopt($ch, CURLOPT_URL, $v);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_exec($ch);
$size2 = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
$filesize = $size2;
$offset = 0;
$length = $filesize;
header("Content-Type: video/mp4");
if (isset($_SERVER['HTTP_RANGE'])) {
$partialContent = "true";
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = $size2 - $offset - 1;
} else {
$partialContent = "false";
}
if ($partialContent == "true") {
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges: bytes');
header('Content-Range: bytes '. $offset .
'-' . ($offset + $length) .
'/'. $filesize);
} else {
header('Accept-Ranges: bytes');
}
header("Content-length: ". $size2);
if (isset($_SERVER['HTTP_RANGE'])) {
// if the HTTP_RANGE header is set we're dealing with partial content
$partialContent = true;
// find the requested range
// this might be too simplistic, apparently the client can request
// multiple ranges, which can become pretty complex, so ignore it for now
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = $filesize - $offset - 1;
$headers = array(
'Range: bytes=' . $offset .
'-' . ($offset + $length) .
''
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 222222);
curl_setopt($ch, CURLOPT_URL, $v);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_exec($ch);
私は解決策を見つけました。上記のコードは非常に乱雑だったので、少しクリーンアップしました。macOSとiOSで動作するようになりました!
<?php
header('Content-Type: video/mp4');
header('Accept-Ranges: bytes');
$agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36';
$url = 'https://notmywebsite/remotevideo.mp4';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_REFERER, $url); //Remote video might need it to get proper response
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
$info = curl_exec($ch);
$filesize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
$end = $filesize - 1;
if (isset($_SERVER['HTTP_RANGE'])) {
//If ranges are requested, perform a reg match and extract them
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$fr = intval($matches[1]);
$sr = is_null($matches[2]) ? $end : intval($matches[2]);
$headers = array("Range: $matches[0]");
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes {$fr}-{$sr}/{$filesize}");
//Here we set the headers (ranges) for the remote video request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_exec($ch);
curl_close($ch);
exit;
?>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加