#!/usr/bin/env perl use v5.36; use strict; use warnings; use File::Basename qw; use File::Temp qw; sub usage() { die "Usage: $0 crop1 [, crop2 ...]\n"; } sub crop($file, $crop) { my ($from, $x, $y, $plus, $to) = $crop =~ /^(\d+(:\d{1,2}){0,2})(-(\+)?(\d+(:\d{1,2}){0,2}))?$/; unless ($from) { print "Error: invalid crop '$crop' (ignoring)\n"; return; } my ($file_noext, $file_dir, $file_ext) = fileparse($file, qr/\.[^.]*/); my $to_suffix = defined $to ? "_$to" : ""; my $cropfile = "${file_noext}_${from}${to_suffix}$file_ext"; if (defined $to && defined $plus) { `ffmpeg -loglevel error -i "$file" -ss "$from" -t "${to}s" -c:v copy -c:a copy -- "$cropfile"` } elsif (defined $to) { `ffmpeg -loglevel error -i "$file" -ss "$from" -to "$to" -c:v copy -c:a copy -- "$cropfile"` } else { `ffmpeg -loglevel error -i "$file" -ss "$from" -t 20s -c:v copy -c:a copy -- "$cropfile"` } print "Cropped to '$cropfile'\n"; } @ARGV > 1 or usage; my $src = shift; my @crops = @ARGV; # Compute $file (either from arg or downloading it beforehand) my $file; if ($src =~ /^http/) { print "Downloading '$src'...\n"; my $tmpdir = tempdir(CLEANUP => 1); $file = `yt-dlp -P "$tmpdir" -q "$src" --exec 'echo "%(filepath)s"'` or die $!; chomp $file; print "Saved to '$file'\n"; } else { $file = $src; } die "ERROR: File '$file' does not exist.\n" unless -f $file; # Make crops foreach my $crop (@crops) { crop($file, $crop); }