【发布时间】:2020-02-06 00:34:06
【问题描述】:
我有一个使用 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 Gateway Timeout” .
无论如何,我不希望用户在上传页面时必须等待页面加载。
所以,我正在寻找一种方法,而不是立即运行该脚本,而是在某种后台线程中或以异步方式执行该脚本。
控制器向用户返回200,我可以告诉他正在上传,稍后再回来查看进度。
如何做到这一点?
【问题讨论】:
-
这种情况的最佳方法是使用 symfony messenger。
标签: php symfony decoupling