Hey , So I am trying to draw points on the video. Video is 12 seconds long and for one second there are 17 data points which needs to be plotted on the video of one frame( 1second) . It works for 6 seconds but not for 12 seconds. Why it's not working for longer videos? Is there any limitations of commands in ffmpeg?
public function overlayCoordinates(Request $request)
{
Log::info('Received request to overlay coordinates on video.');
set_time_limit(600); // 600 seconds = 10 minutes
try {
$request->validate([
'video' => 'required|file|mimes:mp4,avi,mkv,webm|max:102400', // Video max size 100MB
'coordinates' => 'required|file|mimes:txt|max:5120', // Coordinates text file max size 5MB
]);
$videoFile = $request->file('video');
$coordinatesFile = $request->file('coordinates');
$videoFilePath = $videoFile->getRealPath();
$videoFileName = $videoFile->getClientOriginalName();
// Move the video file to the desired location if needed
$storedVideoPath = $videoFile->storeAs('public/videos', $videoFileName);
// Open the video file using Laravel FFmpeg
$media = FFMpeg::fromDisk('public')->open('videos/' . $videoFileName);
$duration = $media->getDurationInSeconds();
Log::info('Duration: ' . $duration);
$coordinatesJson = file_get_contents($coordinatesFile->getPathname());
$coordinatesArray = json_decode($coordinatesJson, true);
$frameRate = 30; // Assuming a frame rate of 30 fps
$visibilityDuration = 0.5; // Set duration to 0.5 second
for ($currentTime = 0; $currentTime < 7; $currentTime++) {
$filterString = ""; // Reset filter string for each frame
$frameIndex = intval($currentTime * $frameRate); // Convert current time to an index
if (isset($coordinatesArray['graphics'][$frameIndex])) {
// Loop through the first 5 keypoints (or fewer if not available)
$keypoints = $coordinatesArray['graphics'][$frameIndex]['kpts'];
for ($i = 0; $i < min(12, count($keypoints)); $i++) {
$keypoint = $keypoints[$i];
$x = $keypoint['p'][0] * 1920; // Scale x coordinate to video width
$y = $keypoint['p'][1] * 1080; // Scale y coordinate to video height
$startTime = $frameIndex / $frameRate; // Calculate start time
$endTime = $startTime + $visibilityDuration; // Set end time for 0.5 second duration
// Add drawbox filter for the current keypoint
$filterString .= "drawbox=x={$x}:y={$y}:w=10:h=10:color=red@0.5:t=fill:enable='between(t,{$startTime},{$endTime})',";
}
Log::info("Processing frame index: {$frameIndex}, Drawing first 5 keypoints.");
}
$filterString = rtrim($filterString, ',');
// Apply the filter for the current frame
if (!empty($filterString)) {
$media->addFilter(function ($filters) use ($filterString) {
$filters->custom($filterString);
});
}
}
$filename = uniqid() . '_overlayed.mp4';
$destinationPath = 'videos/' . $filename;
$format = new \FFMpeg\Format\Video\X264('aac');
$format->setKiloBitrate(5000) // Increase bitrate for better quality
->setAdditionalParameters(['-profile:v', 'high', '-preset', 'veryslow', '-crf', '18']) // High profile, very slow preset, and CRF of 18 for better quality
->setAudioCodec('aac')
->setAudioKiloBitrate(192); // Higher audio bitrate
// Export the video in one pass to a specific disk and directory
$media->export()
->toDisk('public')
->inFormat($format)
->save($destinationPath);
return response()->json([
'message' => 'Video processed successfully with overlays.',
'path' => Storage::url($destinationPath)
]);
} catch (\Exception $e) {
Log::error('Overlay process failed: ' . $e->getMessage());
return response()->json(['error' => 'Overlay process failed. Please check logs for details.'], 500);
}
}
Hey , So I am trying to draw points on the video. Video is 12 seconds long and for one second there are 17 data points which needs to be plotted on the video of one frame( 1second) . It works for 6 seconds but not for 12 seconds. Why it's not working for longer videos? Is there any limitations of commands in ffmpeg?
public function overlayCoordinates(Request $request) { Log::info('Received request to overlay coordinates on video.');