#!/usr/bin/perl ##### # # This script scales an input video to be the duration provided. # # usage: # scale-video.pl [-a audiofile] [-b bitrate] -d hh:mm:ss infile outfile # # The bitrate should be in kbps # ##### use strict; use warnings; use Getopt::Std; my %opts; getopts('a:b:d:', \%opts); my ($src, $dst) = @ARGV; ## Convert a H:M:S duration into seconds ## sub convert_duration { my @time_parts = reverse(split(":", $_[0])); my $accum = 0; for (my $i = 0; $i < @time_parts; $i++) { $accum += $time_parts[$i] * 60 ** $i; } return $accum; } ########################################### ## Check for a custom bitrate ## my $bitrate = $opts{b} ? $opts{b} : 300; ## Parse the target duration ## my $duration_dst = $opts{d} ? convert_duration($opts{d}) :(sub{ print STDERR "No target duration found, use option -d\n"; exit(1); })->(); ## Get input file's duration ## my $probe = join(" ", grep /Duration/, `ffprobe $src 2>&1`); my $duration_src = convert_duration( join(" ", $probe =~ /Duration:(?[^,]+)/)); ## Mix in audio if we need to my $audio = $opts{a} ? "-i \"$opts{a}\"" : ""; ## If we have an input and output file attempt to convert if (@ARGV == 2) { my $pts_value = $duration_dst / $duration_src; `ffmpeg $audio -i $src -b $bitrate"."k -vf "setpts=($pts_value)*PTS" $dst`; } else { print STDERR "Requires a single source and destination file.\n"; exit(1); }