All checks were successful
Push image to registry / build-image (push) Successful in 5m59s
89 lines
2.9 KiB
PHP
89 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\FileTools\VideoDescriptor;
|
|
|
|
use App\Services\FileTools\VideoDescriptor\IVideoDescriptor;
|
|
use Log;
|
|
|
|
abstract class AbstractLLMVideoDescriptor implements IVideoDescriptor
|
|
{
|
|
public const MAX_FRAMES = 5;
|
|
|
|
abstract public function getDescription(string $filePath): ?string;
|
|
|
|
/**
|
|
* Cut the video into screenshots.
|
|
* Using ffmpeg to cut the video into screenshots at regular intervals.
|
|
* The screenshots will be saved in a temporary directory.
|
|
* @param string $filePath
|
|
* @return array array with timestamps as key and screenshot file paths as values.
|
|
*/
|
|
protected function cutVideoIntoScreenshots(string $filePath): array
|
|
{
|
|
$tempDir = sys_get_temp_dir() . '/video_screenshots';
|
|
if (!is_dir($tempDir)) {
|
|
mkdir($tempDir, 0777, true);
|
|
}
|
|
else {
|
|
// Clear the directory if it already exists
|
|
array_map('unlink', glob($tempDir . '/*'));
|
|
}
|
|
|
|
Log::info("Cutting video into screenshots: $filePath");
|
|
|
|
$videoDuration = shell_exec("ffprobe -v error -show_entries format=duration -of csv=p=0 " . escapeshellarg($filePath));
|
|
if ($videoDuration === null) {
|
|
Log::error("Failed to get video duration for file: $filePath");
|
|
return [];
|
|
}
|
|
$videoDuration = floatval($videoDuration);
|
|
|
|
$framesInterval = ceil($videoDuration / self::MAX_FRAMES);
|
|
$fps = 1/$framesInterval; // Frames per second for the screenshots
|
|
|
|
$outputPattern = $tempDir . '/screenshot_%d.png';
|
|
$command = "ffmpeg -i " . escapeshellarg($filePath) . " -vf fps={$fps} " . escapeshellarg($outputPattern);
|
|
exec($command);
|
|
|
|
// Collect all screenshots
|
|
$screenshots = glob($tempDir . '/screenshot_*.png');
|
|
$array = [];
|
|
foreach ($screenshots as $screenshot) {
|
|
$array[] = [
|
|
"screenshot" => $screenshot,
|
|
"timestamp" => floor(sizeof($array) * $framesInterval),
|
|
];
|
|
}
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* Extract audio from the video file.
|
|
* Using ffmpeg to extract audio from the video file.
|
|
* The audio will be saved in a temporary directory as an MP3 file.
|
|
* If the audio extraction fails, it will return null.
|
|
* @param string $filePath
|
|
* @return string|null
|
|
*/
|
|
protected function extractAudioFromVideo(string $filePath): ?string
|
|
{
|
|
$tempDir = sys_get_temp_dir() . '/video_audio';
|
|
if (!is_dir($tempDir)) {
|
|
mkdir($tempDir, 0777, true);
|
|
}
|
|
else {
|
|
// Clear the directory if it already exists
|
|
array_map('unlink', glob($tempDir . '/*'));
|
|
}
|
|
|
|
$outputFile = $tempDir . '/audio.mp3';
|
|
$command = "ffmpeg -i " . escapeshellarg($filePath) . " " . escapeshellarg($outputFile);
|
|
exec($command);
|
|
|
|
if (file_exists($outputFile)) {
|
|
return $outputFile;
|
|
}
|
|
return null;
|
|
}
|
|
}
|