Почему я не могу преобразовать MP4-файл, обслуживаемый PHP, из корня документа? - PullRequest
0 голосов
/ 23 октября 2018

Хорошо, я сдаюсь ... Что-то очень странное происходит, и после нескольких дней возни с этим, я должен попросить о помощи.У меня есть сценарий PHP, который обслуживает файл MP4 вне корня документа.Этот скрипт прекрасно работает, за исключением одной очень важной (по крайней мере для меня) детали: он не даст мне возможность разыграть контент.На том же сервере, когда я получаю доступ к файлу MP4, который находится внутри корня документа, я загружаю страницу, и когда я щелкаю три точки в правом нижнем углу видеопроигрывателя Chrome, у меня есть возможность загрузить или привести кChromecast.Используя мой скрипт, у меня есть только возможность скачать, и мне действительно нужно CAST!Я настроил это так сильно, что вывод заголовков любого метода практически идентичен.Вот мой код ...

<?php
$file=$_GET['file'];

//validate
if($file=="." || $file==".."){$file="";}

$mediaRoot="../../../hostMedia";
$file=$mediaRoot . DIRECTORY_SEPARATOR . $file;
$file=str_replace('\\',"/",$file);

$filesize = filesize($file);

$offset = 0;
$length = $filesize;

// find the requested range
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);

$offset = intval($matches[1]);

$length = (($matches[2]) ? intval($matches[2]) : $filesize) - $offset;

// output the right headers for partial content
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $filesize);
header('Content-Type: video/mp4');
header('Content-Length: ' . $filesize);
header('Accept-Ranges: bytes');
header('Cache-Control: max-age=0');

// open file for reading
$file = fopen($file, 'r');

// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);

// populate $data with all except the last byte of the file
$numBytes=($filesize-1);
$dataLen=0;
while($dataLen<$numBytes){
    $lenGrab=($numBytes-$dataLen);
    if($lenGrab>(1024*2700)){$lenGrab=(1024*2700);}
    $data=fread($file, $lenGrab);
    print($data);
    $dataLen+=strlen($data);
}

// close file
fclose($file);
?>

Тысяча благодарностей тем, кто решает эту проблему!

ОБНОВЛЕНИЕ

ХорошоПринимая совет @Brian Heward, я потратил бесчисленные часы, чтобы убедиться, что заголовки абсолютно идентичны !!!Я был так уверен, что это сработает, но, увы, все равно не дает мне возможность сыграть.Вот мой обновленный PHP ...

<?php
session_start();

$accessCode=$_SESSION['accessCode'];
$file=$_GET['file'];

//handle injection
if($file=="." || $file==".."){$file="";}

if($accessCode=="blahblahblah8"){

    $mediaRoot="../../../hostMedia";
    $file=$mediaRoot . DIRECTORY_SEPARATOR . $file;
    $file=str_replace('\\',"/",$file);

    $filesize = filesize($file);

    $offset = 0;
    $length = $filesize;
    $lastMod=filemtime($file);

    if ( isset($_SERVER['HTTP_RANGE']) ) {
        // if the HTTP_RANGE header is set we're dealing with partial content
        $partialContent = true;
        // find the requested range
        preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
        $offset = intval($matches[1]);
        $length = (($matches[2]) ? intval($matches[2]) : $filesize) - $offset;
    } else {
        $partialContent = false;
    }


    if ( $partialContent ) {
        // output the right headers for partial content
        header('HTTP/1.1 206 Partial Content');
        header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $filesize);
    }else{
        header('HTTP/1.1 200 OK');
    }

    // output the regular HTTP headers
    header('Content-Type: video/mp4');
    header('Content-Length: ' . $length);
    header('Accept-Ranges: bytes');
    header('ETag: "3410d79f-576de84c004aa"');
    header('Last-Modified: '.gmdate('D, d M Y H:i:s \G\M\T', $lastMod)); 

    // don't forget to send the data too
    $file = fopen($file, 'r');

    // seek to the requested offset, this is 0 if it's not a partial content request
    fseek($file, $offset);

    //populate $data with all except the last byte of the file
    $numBytes=($length);
    $dataLen=0;
    while($dataLen<$numBytes){
        $lenGrab=($numBytes-$dataLen);
        if($lenGrab>(1024*2700)){$lenGrab=(1024*2700);}
        $data=fread($file, $lenGrab);
        print($data);
        $dataLen+=strlen($data);
    }

    fclose($file);
}else{
    echo "You are not authorized to view this media.";
}

?>

Если кто-то может заставить эту штуку работать, вы серьезно супергерой!

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ (пока ...)

Ну, после многих, многих часов разочарования мне пришлось отказаться от подхода и попробовать что-то другое.К счастью, обычно есть несколько способов сделать что-то, и я нашел другой способ.Я размещаю файлы .mp4 внутри корня документа в папке, защищенной с помощью HTTP Basic Auth.Очень похоже на то, что я пытался достичь, и это работает для меня.Спасибо за ваш совет и направление!

1 Ответ

0 голосов
/ 23 октября 2018

Ваши заголовки "почти идентичны", и здесь есть проблема.Сделайте их идентичными: P

Используйте инструменты разработчика в своем браузере, (F12) и проверьте сетевые заголовки, которые делает каждый запрос.Наиболее вероятными причинами являются следующие строки, которые я использовал в аналогичном проекте, и вы, похоже, отсутствует:

header('Content-Description: File Transfer');
header('Content-Disposition: inline; filename=' . basename($file));

поочередно может потребоваться

header('Content-Disposition: attachment; filename=' . basename($file));
...