fix(video-clips): create unique temporary files for resources to be deleted after generation

- tempfile uniqueness ensures that each process lives in its independent context
- add
writable/temp folder to store video clips temporary resources
- add videoClipWorkers config to
Admin for specifying the number of ffmpeg processes to run in parallel
- update video clip preview
background to better suit the end result
This commit is contained in:
Yassine Doghri 2022-01-21 12:35:50 +00:00
commit 7f7c878cb6
13 changed files with 128 additions and 48 deletions

View file

@ -13,12 +13,20 @@ namespace Modules\Admin\Controllers;
use App\Models\ClipModel;
use CodeIgniter\Controller;
use CodeIgniter\I18n\Time;
use Exception;
use MediaClipper\VideoClipper;
class SchedulerController extends Controller
{
public function generateVideoClips(): bool
{
// get number of running clips to prevent from having too much running in parallel
// TODO: get the number of running ffmpeg processes directly from the machine?
$runningVideoClips = (new ClipModel())->getRunningVideoClipsCount();
if ($runningVideoClips >= config('Admin')->videoClipWorkers) {
return true;
}
// get all clips that haven't been processed yet
$scheduledClips = (new ClipModel())->getScheduledVideoClips();
@ -38,40 +46,49 @@ class SchedulerController extends Controller
// Loop through clips to generate them
foreach ($scheduledClips as $scheduledClip) {
// set clip to pending
(new ClipModel())
->update($scheduledClip->id, [
'status' => 'running',
'job_started_at' => Time::now(),
]);
$clipper = new VideoClipper(
$scheduledClip->episode,
$scheduledClip->start_time,
$scheduledClip->end_time,
$scheduledClip->format,
$scheduledClip->theme['name'],
);
$exitCode = $clipper->generate();
try {
$clipModel = new ClipModel();
if ($exitCode === 0) {
// success, video was generated
$scheduledClip->setMedia($clipper->videoClipFilePath);
$clipModel->update($scheduledClip->id, [
'media_id' => $scheduledClip->media_id,
'status' => 'passed',
'logs' => $clipper->logs,
'job_ended_at' => Time::now(),
]);
} else {
// error
$clipModel->update($scheduledClip->id, [
// set clip to pending
(new ClipModel())
->update($scheduledClip->id, [
'status' => 'running',
'job_started_at' => Time::now(),
]);
$clipper = new VideoClipper(
$scheduledClip->episode,
$scheduledClip->start_time,
$scheduledClip->end_time,
$scheduledClip->format,
$scheduledClip->theme['name'],
);
$exitCode = $clipper->generate();
$clipModel = new ClipModel();
if ($exitCode === 0) {
// success, video was generated
$scheduledClip->setMedia($clipper->videoClipFilePath);
$clipModel->update($scheduledClip->id, [
'media_id' => $scheduledClip->media_id,
'status' => 'passed',
'logs' => $clipper->logs,
'job_ended_at' => Time::now(),
]);
} else {
// error
$clipModel->update($scheduledClip->id, [
'status' => 'failed',
'logs' => $clipper->logs,
'job_ended_at' => Time::now(),
]);
}
$clipModel->clearVideoClipCache($scheduledClip->id);
} catch (Exception $exception) {
(new ClipModel())->update($scheduledClip->id, [
'status' => 'failed',
'logs' => $clipper->logs,
'logs' => $exception,
'job_ended_at' => Time::now(),
]);
}
$clipModel->clearVideoClipCache($scheduledClip->id);
}
return true;