Files
DatBrowser/app/Services/FileTools/VideoDescriptor/AbstractLLMVideoDescriptor.php
Matthias Guillitte f0e52147e4
All checks were successful
Push image to registry / build-image (push) Successful in 5m59s
Added video transcription
2025-07-04 12:36:03 +02:00

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;
}
}