我目前正在尝试将视频转换为多个.ts片段(用于HTTP视频流)。这是一项艰巨的任务,所以我要在Laravel中完成这项工作。
问题在于,作业在几分钟后运行了多次,因此,视频被多次处理。在这里,您可以看到我的Job班级:
<?php
namespace App\Jobs;
use App\Models\Media\MediaFile;
use FFMpeg\Filters\Video\ResizeFilter;
use FFMpeg\Format\Video\X264;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use FFMpeg;
class ConvertVideoForStreaming implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $mediaFile;
public $deleteWhenMissingModels = true;
public $timeout = 3600;
public $retryAfter = 4000;
public $tries = 3;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(MediaFile $mediaFile)
{
$this->mediaFile = $mediaFile;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$this->mediaFile->update([
'status' => 'Processing',
'status_message' => null,
]);
$convertingId = Str::random(6);
$lowBitrateFormat = (new X264('aac', 'libx264'))
->setKiloBitrate(500)
->setAudioKiloBitrate(128);
$midBitrateFormat = (new X264('aac', 'libx264'))
->setKiloBitrate(1500)
->setAudioKiloBitrate(192);
$highBitrateFormat = (new X264('aac', 'libx264'))
->setKiloBitrate(3000)
->setAudioKiloBitrate(256);
\Log::info('Started a new converting process with convertingID: ' . $convertingId);
FFMpeg::fromDisk('public')
->open($this->mediaFile->file)
->exportForHLS()
->setSegmentLength(4) // optional
->addFormat($lowBitrateFormat, function($media) {
$media->addFilter(function ($filters) {
$filters->resize(new \FFMpeg\Coordinate\Dimension(640, 480), ResizeFilter::RESIZEMODE_INSET);
});
})
->addFormat($midBitrateFormat, function($media) {
$media->addFilter(function ($filters) {
$filters->resize(new \FFMpeg\Coordinate\Dimension(1280, 720), ResizeFilter::RESIZEMODE_INSET);
});
})
->addFormat($highBitrateFormat, function($media) {
$media->addFilter(function ($filters) {
$filters->resize(new \FFMpeg\Coordinate\Dimension(1920, 1080), ResizeFilter::RESIZEMODE_INSET);
});
})
->onProgress(function ($percentage) use($convertingId) {
\Log::info($this->mediaFile->name . " (ConvertingID: $convertingId) - $percentage % transcoded");
\Redis::set('video-transcoded-' . $this->mediaFile->id, $percentage);
})
->toDisk('public')
->save('livestream/' . Str::slug($this->mediaFile->name) . '/playlist.m3u8');
$this->mediaFile->update([
'status' => 'Active',
'status_message' => null,
]);
}
public function failed(\Exception $exception)
{
$this->mediaFile->update([
'status' => 'Failed',
'status_message' => $exception->getMessage(),
]);
}
}
我该如何解决我的问题?
答案 0 :(得分:0)
Laravel为计划的命令提供了“锁定”功能。请参阅this文档中的“防止任务重叠”。
如果您只希望一次处理非计划作业,我建议您研究Symfony Lock Component。该组件使您可以锁定某个任务一段时间或直到将其解锁。这样,您可以按照以下方式进行操作:
handle()
方法的开头handle()
逻辑的最后,释放锁