Php 使用Laravel将youtube dl输出流到S3 背景:
我在拉威尔5.3频道 我正在使用Php 使用Laravel将youtube dl输出流到S3 背景:,php,laravel,youtube-dl,Php,Laravel,Youtube Dl,我在拉威尔5.3频道 我正在使用YouTube dl下载YouTube视频,使用SymfonyProcess: $command = '/usr/local/bin/youtube-dl -o '.$new_file_path.' '.$youtube_id; $process = new Process($command); $process->setTimeout(null); $process->run(); 在进程运行后,我将下载的文件放在预期位置。现在我可以将其存储到S3
YouTube dl
下载YouTube视频,使用Symfony
Process
:
$command = '/usr/local/bin/youtube-dl -o '.$new_file_path.' '.$youtube_id;
$process = new Process($command);
$process->setTimeout(null);
$process->run();
在进程运行后,我将下载的文件放在预期位置。现在我可以将其存储到S3,如下所示:
\Storage::disk('s3')->putFile($s3_location, new File($new_file_path));
// Process class supports streamed output
// https://symfony.com/doc/current/components/process.html
// note the '-' after '-o' parameter - it asks youtube-dl to give a stream output, which can be piped in a shell
$process = new Process('/usr/local/bin/youtube-dl -o - '.$youtube_id;);
$process->start();
foreach ($process as $type => $data) {
if ($process::OUT === $type) {
echo "\nRead from stdout: ".$data;
} else { // $process::ERR === $type
echo "\nRead from stderr: ".$data;
}
}
问题
如您所见,我正在将文件下载到本地存储,然后上传到S3。如果我可以直接写S3,那就太好了。特别是因为这两个组件都支持流式处理—Process class可以流式处理输出,S3存储可以存储流,如下所示:
\Storage::disk('s3')->putFile($s3_location, new File($new_file_path));
// Process class supports streamed output
// https://symfony.com/doc/current/components/process.html
// note the '-' after '-o' parameter - it asks youtube-dl to give a stream output, which can be piped in a shell
$process = new Process('/usr/local/bin/youtube-dl -o - '.$youtube_id;);
$process->start();
foreach ($process as $type => $data) {
if ($process::OUT === $type) {
echo "\nRead from stdout: ".$data;
} else { // $process::ERR === $type
echo "\nRead from stderr: ".$data;
}
}
以及
我的问题是-有没有办法将进程
类的流式输出包装为资源/流对象,并将其传递给S3存储?更正:脚本实际上会在可用时上载所有块,因为文件(get)内容
将继续到达EOF
您需要确保有足够的可用内存,因为脚本无法处理可用内存的总大小和视频的总大小
请注意,我没有实际测试,因为我没有s3帐户,请让我知道是否有任何问题,以纠正答案
//创建ramdrive
//bash$mkdir/mnt/ram\u磁盘
//bash$mount-t tmpfs-o大小=1024m新的\u ram\u磁盘/mnt/ram\u磁盘
$array_of_youtube_id=['abc001','abc002','abc003'];
$storage_path='/mnt/ram_disk/';
//开始所有下载
$index=0;
foreach($id的数组作为$id){
$youtube\u dls$index]=新YouTubeDlAsync($storage\u path.$id,$id);
$youtube_dls[$index]>start();
$index++;
}
//上传所有下载
$index=0;
foreach($id的数组作为$id){
$s3uploads[$index]=新上传到3($storage\u path.$id,$resource);
$s3上传[$index]->start();
$index++;
}
//等待所有下载完成
foreach($youtube\u dls作为$youtube\u dl)
$youtube_dl->join();
//等待所有上载完成
foreach($s3uploads作为$s3uploads上传)
$s3upload->join();
类YouTubeDlAsync扩展线程{
公共函数构造($new\u file\u path,$youtube\u id){
$command='/usr/local/bin/youtube dl-o'.$new\u file\u path'.$youtube\u id;
exec($command);
}
}
类UploadToS3扩展了线程{
公共函数构造($new\u file\u path,$resource){
存储::put(file\u get\u contents('file.jpg'),$resource);
}
}
您可以将文件存储在内存中,但您可以要求youtube服务器将您的流发送到s3,您不能在非线程php中执行此操作,您需要启用多线程以在上载到s3时获取youtube流,但您的服务器必须下载并上载。您可以扩展“要求youtube服务器将您的流发送到s3”吗部分请?当您上传到s3时,您正在从您的服务器IP地址进行握手,流必须来自您的IP,您是否正在寻找一种方法来避免将文件存储到您的HDD/内存中?使用内存中的流作为缓冲区,这是我正在寻找的。没有写入硬盘。你在使用Linux服务器吗?您可以为此分配多少内存,一次传输的最大文件大小是多少?您可能会很快耗尽内存。感谢您的回复,但这是另一个版本的“存储到磁盘,然后上载到S3”-我特别希望避免磁盘存储(甚至是ram磁盘),因为正如您在回答的第一部分正确提到的,我们需要注意高清甚至4K视频。更正:脚本实际上会在可用时上载所有块,因为file\u get\u contents
将继续达到EOF