У меня есть приложение, созданное с использованием Symfony 5, и у меня есть скрипт, который загружает видео, расположенное на сервере, в канал авторизованного пользователя.
Вот в основном код моего контроллера:
/**
* Upload a video to YouTube.
*
* @Route("/upload_youtube/{id}", name="api_admin_video_upload_youtube", methods={"POST"}, requirements={"id" = "\d+"})
*/
public function upload_youtube(int $id, Request $request, VideoRepository $repository, \Google_Client $googleClient): JsonResponse
{
$video = $repository->find($id);
if (!$video) {
return $this->json([], Response::HTTP_NOT_FOUND);
}
$data = json_decode(
$request->getContent(),
true
);
$googleClient->setRedirectUri($_SERVER['CLIENT_URL'] . '/admin/videos/youtube');
$googleClient->fetchAccessTokenWithAuthCode($data['code']);
$videoPath = $this->getParameter('videos_directory') . '/' . $video->getFilename();
$service = new \Google_Service_YouTube($googleClient);
$ytVideo = new \Google_Service_YouTube_Video();
$ytVideoSnippet = new \Google_Service_YouTube_VideoSnippet();
$ytVideoSnippet->setTitle($video->getTitle());
$ytVideo->setSnippet($ytVideoSnippet);
$ytVideoStatus = new \Google_Service_YouTube_VideoStatus();
$ytVideoStatus->setPrivacyStatus('private');
$ytVideo->setStatus($ytVideoStatus);
$chunkSizeBytes = 1 * 1024 * 1024;
$googleClient->setDefer(true);
$insertRequest = $service->videos->insert(
'snippet,status',
$ytVideo
);
$media = new \Google_Http_MediaFileUpload($googleClient, $insertRequest, 'video/*', null, true, $chunkSizeBytes);
$media->setFileSize(filesize($videoPath));
$uploadStatus = false;
$handle = fopen($videoPath, "rb");
while (!$uploadStatus && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$uploadStatus = $media->nextChunk($chunk);
}
fclose($handle);
}
Это в основном работает, но проблема в том, что видео может быть очень большим (10G +), поэтому оно занимает очень много времени, и в основном Nginx завершается до того, как закончится, и возвращает "шлюз 504". Тайм-аут "до завершения загрузки.
И вообще, я не хочу, чтобы пользователю приходилось ждать загрузки страницы во время загрузки.
Итак, я ищу способ, вместо того, чтобы просто немедленно запустить этот скрипт, выполнить этот скрипт в некотором фоновом потоке или асинхронным способом.
Контроллер возвращает 200
пользователю, я могу сказать ему, что загрузка происходит, и чтобы вернуться позже, чтобы проверить прогресс.
Как это сделать?