Открытие тяжелых видео в браузере

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
long399
Сообщения: 96
Зарегистрирован: 2019.08.13, 08:03
Откуда: г. Новосибирск

Открытие тяжелых видео в браузере

Сообщение long399 »

Всех приветствую.

Имеется микросервис, в котором хранятся различные pdf и mp4 файлы. Есть такой метод API в контроллере, для отдачи файла во внешний мир:

Код: Выделить всё

// API контроллер

/**
 * Получение файла.
 * @param int $id
 * @return \yii\web\Response
 * @throws NotFoundHttpException
 */
public function actionGetFile($id)
{
    /* @var $model \app\models\File */
    $model = $this->findModel($id);

    $filepath = Yii::getAlias("@files/$model->id/$model->filename");

    if (!is_file($filepath)) {
        throw new NotFoundHttpException("Файл с идентификатором $id не найден.");
    }

    return $this->response->sendFile($filepath);
}
С не очень большими файлами сложностей нет, они получаются и выводятся в браузер. Проблема возникает для больших видео файлов (например, 1.9 Гб). Пробую вот так:

Код: Выделить всё

// контроллер на стороне клиента, обращающегося к сервису за файлом

/**
 * Getting file.
 * @param int $id
 * @return \yii\web\Response
 * @throws NotFoundHttpException if the model cannot be found
 */
public function actionGetFile($id)
{
    $model = $this->findModel($id);

    $url = "https://hostname.ru/api/file/$file_id/get-file?access-token=token";

    try {
        $file = file_get_contents($url);
    } catch(\yii\base\ErrorException $e) {
        throw new \yii\web\NotFoundHttpException('Файл не найден.');
    }

    if ($model->type === File::TYPE_VIDEO) {
        $mimeType = 'video/mp4';
    } else {
        $mimeType = 'application/pdf';
    }

    // FIXME: not working with large video files
    return $this->response->sendContentAsFile(
        $file,
        "Файл $file_id",
        ['mimeType' => $mimeType, 'inline' => true]
    );
}
При открытии ссылки файл начинает загружаться, во вкладке появляется видеоплеер, но затем происходит ошибка 500 Internal Server Error.
В логах такое:

Код: Выделить всё

[error][yii\base\ErrorException:1] yii\base\ErrorException: Allowed memory size of 3145728000 bytes exhausted (tried to allocate 1939918848 bytes) in /home/roman/eclipse-workspace/employee/vendor/yiisoft/yii2/web/Response.php:433
Насколько я понимаю, нужно каким-то образом отправить в браузер файл по частям, потому-что file_get_contents() получает файл целиком в строку.

И проблем бы не было, если бы файл хранился там же, где мы его хотим открыть. Проводил эксперимент: нужный файл скопировал в папку web того приложения, где его требуется получить и вывел в браузер следующим образом:

Код: Выделить всё

/**
 * Getting file.
 * @param int $id
 * @return \yii\web\Response
 * @throws NotFoundHttpException if the model cannot be found
 */
public function actionGetFile($id)
{
    $url = 'file.mp4';
    $handle = fopen($url, 'rb');

    // work for LOCAL large file
    return Yii::$app->response->sendStreamAsFile(
        $handle,
        "Файл $file_id",
        ['mimeType' => 'video/mp4', 'inline' => true]
    );
}
Но с учетом того, что файл лежит на другом хосте, я пока так и не понял, какие правки нужно внести. Нужно ли править метод API? Какие правки нужны на клиенте?

Буду рад любой вашей помощи.
long399
Сообщения: 96
Зарегистрирован: 2019.08.13, 08:03
Откуда: г. Новосибирск

Re: Открытие тяжелых видео в браузере

Сообщение long399 »

Помогло использование пакета https://github.com/wbraganca/yii2-videojs-widget. Видео в этом плеере открывается нормально, никиких ошибок не возникает. API переделывать не потребовалось.
Ответить