view release on metacpan or search on metacpan
0.013 2023-12-13 Released-By: PERLANCAR; Urgency: medium
- [bugfix] Fix Rinci metadata.
0.012 2022-09-22 Released-By: PERLANCAR; Urgency: medium
- Add utility: cut-video-by-duration (alias: vcut)
- [ux] allow specifying times/durations as percentage
- [cli split-video-by-duration] Add option --parts as alternative to
--every.
- [doc] Justify the wrapper's benefits.
0.011 2022-09-21 Released-By: PERLANCAR; Urgency: medium
- [cli split-video-by-duration] Accept multiple files.
"Rinci" : "v1.1.102"
}
},
"runtime" : {
"requires" : {
"Data::Sah::Coerce::perl::To_duration::From_float::seconds" : "0",
"Data::Sah::Coerce::perl::To_duration::From_obj::datetime_duration" : "0",
"Data::Sah::Coerce::perl::To_duration::From_str::hms" : "0",
"Data::Sah::Coerce::perl::To_duration::From_str::human" : "0",
"Data::Sah::Coerce::perl::To_duration::From_str::iso8601" : "0",
"Data::Sah::Coerce::perl::To_float::From_str::percent" : "0",
"Data::Sah::Compiler::perl::TH::any" : "0.914",
"Data::Sah::Compiler::perl::TH::array" : "0.914",
"Data::Sah::Compiler::perl::TH::bool" : "0.914",
"Data::Sah::Compiler::perl::TH::duration" : "0.914",
"Data::Sah::Compiler::perl::TH::float" : "0.914",
"Data::Sah::Compiler::perl::TH::int" : "0.914",
"Data::Sah::Compiler::perl::TH::str" : "0.914",
"Data::Sah::Filter::perl::Path::expand_tilde_when_on_unix" : "0",
"Data::Sah::Filter::perl::Path::strip_slashes_when_on_unix" : "0",
"File::Temp" : "0.2310",
"Log::ger" : "0.038",
"Math::Image::CalcResized" : "0.004",
"Media::Info" : "0.131",
"POSIX" : "0",
"Perinci::CmdLine::Any" : "0.154",
"Perinci::CmdLine::Lite" : "1.924",
"Perinci::Exporter" : "0.080",
"Perinci::Object" : "0.311",
"Perinci::Sub::DepChecker" : "0",
"Sah::Schema::filename" : "0",
"Sah::Schema::percent_str" : "0",
"Sah::Schema::posint" : "0",
"Sah::Schema::ufloat" : "0",
"Sah::Schema::uint" : "0",
"perl" : "5.010001",
"strict" : "0",
"warnings" : "0"
}
},
"test" : {
"requires" : {
provides:
App::FfmpegUtils:
file: lib/App/FfmpegUtils.pm
version: '0.014'
requires:
Data::Sah::Coerce::perl::To_duration::From_float::seconds: '0'
Data::Sah::Coerce::perl::To_duration::From_obj::datetime_duration: '0'
Data::Sah::Coerce::perl::To_duration::From_str::hms: '0'
Data::Sah::Coerce::perl::To_duration::From_str::human: '0'
Data::Sah::Coerce::perl::To_duration::From_str::iso8601: '0'
Data::Sah::Coerce::perl::To_float::From_str::percent: '0'
Data::Sah::Compiler::perl::TH::any: '0.914'
Data::Sah::Compiler::perl::TH::array: '0.914'
Data::Sah::Compiler::perl::TH::bool: '0.914'
Data::Sah::Compiler::perl::TH::duration: '0.914'
Data::Sah::Compiler::perl::TH::float: '0.914'
Data::Sah::Compiler::perl::TH::int: '0.914'
Data::Sah::Compiler::perl::TH::str: '0.914'
Data::Sah::Filter::perl::Path::expand_tilde_when_on_unix: '0'
Data::Sah::Filter::perl::Path::strip_slashes_when_on_unix: '0'
File::Temp: '0.2310'
Log::ger: '0.038'
Math::Image::CalcResized: '0.004'
Media::Info: '0.131'
POSIX: '0'
Perinci::CmdLine::Any: '0.154'
Perinci::CmdLine::Lite: '1.924'
Perinci::Exporter: '0.080'
Perinci::Object: '0.311'
Perinci::Sub::DepChecker: '0'
Sah::Schema::filename: '0'
Sah::Schema::percent_str: '0'
Sah::Schema::posint: '0'
Sah::Schema::ufloat: '0'
Sah::Schema::uint: '0'
perl: '5.010001'
strict: '0'
warnings: '0'
resources:
bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=App-FfmpegUtils
homepage: https://metacpan.org/release/App-FfmpegUtils
repository: git://github.com/perlancar/perl-App-FfmpegUtils.git
Makefile.PL view on Meta::CPAN
],
"LICENSE" => "perl",
"MIN_PERL_VERSION" => "5.010001",
"NAME" => "App::FfmpegUtils",
"PREREQ_PM" => {
"Data::Sah::Coerce::perl::To_duration::From_float::seconds" => 0,
"Data::Sah::Coerce::perl::To_duration::From_obj::datetime_duration" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::hms" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::human" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::iso8601" => 0,
"Data::Sah::Coerce::perl::To_float::From_str::percent" => 0,
"Data::Sah::Compiler::perl::TH::any" => "0.914",
"Data::Sah::Compiler::perl::TH::array" => "0.914",
"Data::Sah::Compiler::perl::TH::bool" => "0.914",
"Data::Sah::Compiler::perl::TH::duration" => "0.914",
"Data::Sah::Compiler::perl::TH::float" => "0.914",
"Data::Sah::Compiler::perl::TH::int" => "0.914",
"Data::Sah::Compiler::perl::TH::str" => "0.914",
"Data::Sah::Filter::perl::Path::expand_tilde_when_on_unix" => 0,
"Data::Sah::Filter::perl::Path::strip_slashes_when_on_unix" => 0,
"File::Temp" => "0.2310",
Makefile.PL view on Meta::CPAN
"Log::ger" => "0.038",
"Math::Image::CalcResized" => "0.004",
"Media::Info" => "0.131",
"POSIX" => 0,
"Perinci::CmdLine::Any" => "0.154",
"Perinci::CmdLine::Lite" => "1.924",
"Perinci::Exporter" => "0.080",
"Perinci::Object" => "0.311",
"Perinci::Sub::DepChecker" => 0,
"Sah::Schema::filename" => 0,
"Sah::Schema::percent_str" => 0,
"Sah::Schema::posint" => 0,
"Sah::Schema::ufloat" => 0,
"Sah::Schema::uint" => 0,
"strict" => 0,
"warnings" => 0
},
"TEST_REQUIRES" => {
"File::Spec" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
Makefile.PL view on Meta::CPAN
}
);
my %FallbackPrereqs = (
"Data::Sah::Coerce::perl::To_duration::From_float::seconds" => 0,
"Data::Sah::Coerce::perl::To_duration::From_obj::datetime_duration" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::hms" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::human" => 0,
"Data::Sah::Coerce::perl::To_duration::From_str::iso8601" => 0,
"Data::Sah::Coerce::perl::To_float::From_str::percent" => 0,
"Data::Sah::Compiler::perl::TH::any" => "0.914",
"Data::Sah::Compiler::perl::TH::array" => "0.914",
"Data::Sah::Compiler::perl::TH::bool" => "0.914",
"Data::Sah::Compiler::perl::TH::duration" => "0.914",
"Data::Sah::Compiler::perl::TH::float" => "0.914",
"Data::Sah::Compiler::perl::TH::int" => "0.914",
"Data::Sah::Compiler::perl::TH::str" => "0.914",
"Data::Sah::Filter::perl::Path::expand_tilde_when_on_unix" => 0,
"Data::Sah::Filter::perl::Path::strip_slashes_when_on_unix" => 0,
"File::Spec" => 0,
Makefile.PL view on Meta::CPAN
"Log::ger" => "0.038",
"Math::Image::CalcResized" => "0.004",
"Media::Info" => "0.131",
"POSIX" => 0,
"Perinci::CmdLine::Any" => "0.154",
"Perinci::CmdLine::Lite" => "1.924",
"Perinci::Exporter" => "0.080",
"Perinci::Object" => "0.311",
"Perinci::Sub::DepChecker" => 0,
"Sah::Schema::filename" => 0,
"Sah::Schema::percent_str" => 0,
"Sah::Schema::posint" => 0,
"Sah::Schema::ufloat" => 0,
"Sah::Schema::uint" => 0,
"Test::More" => 0,
"strict" => 0,
"warnings" => 0
);
unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
This function supports dry-run operation.
Arguments ('*' denotes required arguments):
* copy => *bool*
Whether to use the "copy" codec (fast but produces inaccurate
timings).
* duration => *duration|percent_str*
(No description)
* end => *duration|percent_str*
(No description)
* files* => *array[filename]*
(No description)
* start => *duration|percent_str*
(No description)
Special arguments:
* -dry_run => *bool*
Pass -dry_run=>1 to enable simulation mode.
Returns an enveloped result (an array).
cut_video_by_duration(%args) -> [$status_code, $reason, $payload, \%result_meta]
Get a portion (time range) of a video.
Examples:
* Specify start only, the result is 100s.cut_40_to_100.mp4:
cut_video_by_duration(files => ["100s.mp4"], start => "40s");
* Specify duration only (using percentage) of two files, the results
are 100s.cut_0_to_30.mp4 & 50s.cut_0_to_15.mp4:
cut_video_by_duration(files => ["100s.mp4", "50s.mp4"], duration => "30%");
* Specify end only (using h:m:s notation), the result is
100s.cut_0_to_63.mp4:
cut_video_by_duration(files => ["100s.mp4"], end => "00:01:03");
* Specify start & end only (using h:m:s notation), the result is
This function supports dry-run operation.
Arguments ('*' denotes required arguments):
* copy => *bool*
Whether to use the "copy" codec (fast but produces inaccurate
timings).
* duration => *duration|percent_str*
(No description)
* end => *duration|percent_str*
(No description)
* files* => *array[filename]*
(No description)
* overwrite => *bool*
(No description)
* start => *duration|percent_str*
(No description)
Special arguments:
* -dry_run => *bool*
Pass -dry_run=>1 to enable simulation mode.
Returns an enveloped result (an array).
This function supports dry-run operation.
Arguments ('*' denotes required arguments):
* copy => *bool*
Whether to use the "copy" codec (fast but produces inaccurate
timings).
* every => *duration|percent_str*
(No description)
* files* => *array[filename]*
(No description)
* overwrite => *bool*
(No description)
lib/App/FfmpegUtils.pm view on Meta::CPAN
our %argspecopt_copy = (
copy => {
summary => 'Whether to use the "copy" codec (fast but produces inaccurate timings)',
schema => 'bool*',
},
);
our %argspecsopt_duration = (
start => {
schema => ['any*', of=>['duration*', 'percent_str*']],
cmdline_aliases => {s=>{}},
},
end => {
schema => ['any*', of=>['duration*', 'percent_str*']],
cmdline_aliases => {e=>{}},
},
duration => {
schema => ['any*', of=>['duration*', 'percent_str*']],
cmdline_aliases => {d=>{}},
},
);
my @presets = qw/ultrafast superfast veryfast faster fast medium slow slower veryslow/;
sub _nearest {
sprintf("%d", $_[0]/$_[1]) * $_[1];
}
lib/App/FfmpegUtils.pm view on Meta::CPAN
Compared to using `ffmpeg` directly, this wrapper offers convenience of
calculating the times (`-ss`) option for you, handling multiple files,
automatically choosing output filename, and tab completion.
MARKDOWN
args => {
%argspec0_files,
# XXX start => {},
every => {
schema => ['any*', of=>['duration*', 'percent_str*']],
},
parts => {
schema => 'posint*',
},
%argspecopt_copy,
# XXX merge_if_last_part_is_shorter_than => {},
# XXX output_filename_pattern
overwrite => {
schema => 'bool*',
cmdline_aliases => {O=>{}},
lib/App/FfmpegUtils.pm view on Meta::CPAN
'x.doc.show_result' => 0,
},
{
summary => 'Split video into 4 equiduration parts',
src_plang => 'bash',
src => '[[prog]] foo.mp4 --parts 4',
test => 0,
'x.doc.show_result' => 0,
},
{
summary => 'Another way to split into equiduration parts using percentage in --every',
src_plang => 'bash',
src => '[[prog]] foo.mp4 --every 25%',
test => 0,
'x.doc.show_result' => 0,
},
],
features => {
dry_run => 1,
},
deps => {
lib/App/FfmpegUtils.pm view on Meta::CPAN
$envres->add_result(412, "Duration of video $file is zero", {item_id=>$j});
next;
}
my $part_dur;
if (defined $parts) {
return [400, "Please specify a positive number in --parts"] unless $parts >= 1;
$part_dur = $total_dur / $parts;
} elsif (defined $every) {
if ($every =~ s/%\z//) {
$every > 0 && $every <= 100 or return [400, "For percentage in --every, please specify a number between 0 and 100"];
$part_dur = $total_dur * ($every/100);
} else {
$every > 0 or return [400, "Please specify a positive number in --every"];
$part_dur = $every;
}
} else {
return [400, "Please specify either --every or --parts"];
}
my $num_parts = POSIX::ceil($total_dur / $part_dur);
lib/App/FfmpegUtils.pm view on Meta::CPAN
req_one => [qw/start duration/],
},
examples => [
{
summary => 'Specify start only, the result is 100s.cut_40_to_100.mp4',
argv => ['100s.mp4', '-s', '40s'],
test => 0,
'x.doc.show_result' => 0,
},
{
summary => 'Specify duration only (using percentage) of two files, the results are 100s.cut_0_to_30.mp4 & 50s.cut_0_to_15.mp4',
argv => ['100s.mp4', '50s.mp4', '-d', '30%'],
test => 0,
'x.doc.show_result' => 0,
},
{
summary => 'Specify end only (using h:m:s notation), the result is 100s.cut_0_to_63.mp4',
argv => ['100s.mp4', '-e', '00:01:03'],
test => 0,
'x.doc.show_result' => 0,
},
lib/App/FfmpegUtils.pm view on Meta::CPAN
Arguments ('*' denotes required arguments):
=over 4
=item * B<copy> => I<bool>
Whether to use the "copy" codec (fast but produces inaccurate timings).
=item * B<duration> => I<duration|percent_str>
(No description)
=item * B<end> => I<duration|percent_str>
(No description)
=item * B<files>* => I<array[filename]>
(No description)
=item * B<start> => I<duration|percent_str>
(No description)
=back
Special arguments:
=over 4
lib/App/FfmpegUtils.pm view on Meta::CPAN
Get a portion (time range) of a video.
Examples:
=over
=item * Specify start only, the result is 100s.cut_40_to_100.mp4:
cut_video_by_duration(files => ["100s.mp4"], start => "40s");
=item * Specify duration only (using percentage) of two files, the results are 100s.cut_0_to_30.mp4 & 50s.cut_0_to_15.mp4:
cut_video_by_duration(files => ["100s.mp4", "50s.mp4"], duration => "30%");
=item * Specify end only (using h:m:s notation), the result is 100s.cut_0_to_63.mp4:
cut_video_by_duration(files => ["100s.mp4"], end => "00:01:03");
=item * Specify start & end only (using h:m:s notation), the result is 100s.cut_50_to_63.mp4:
cut_video_by_duration(files => ["100s.mp4"], end => "00:01:03", start => "00:00:50");
lib/App/FfmpegUtils.pm view on Meta::CPAN
Arguments ('*' denotes required arguments):
=over 4
=item * B<copy> => I<bool>
Whether to use the "copy" codec (fast but produces inaccurate timings).
=item * B<duration> => I<duration|percent_str>
(No description)
=item * B<end> => I<duration|percent_str>
(No description)
=item * B<files>* => I<array[filename]>
(No description)
=item * B<overwrite> => I<bool>
(No description)
=item * B<start> => I<duration|percent_str>
(No description)
=back
Special arguments:
=over 4
lib/App/FfmpegUtils.pm view on Meta::CPAN
Arguments ('*' denotes required arguments):
=over 4
=item * B<copy> => I<bool>
Whether to use the "copy" codec (fast but produces inaccurate timings).
=item * B<every> => I<duration|percent_str>
(No description)
=item * B<files>* => I<array[filename]>
(No description)
=item * B<overwrite> => I<bool>
(No description)
script/cut-video-by-duration view on Meta::CPAN
=head2 other shells
For fish and zsh, install L<shcompgen> as described above.
=head1 EXAMPLES
=head2 Specify start only, the result is 100s.cut_40_to_100.mp4
% cut-video-by-duration 100s.mp4 -s 40s
=head2 Specify duration only (using percentage) of two files, the results are 100s.cut_0_to_30.mp4 & 50s.cut_0_to_15.mp4
% cut-video-by-duration 100s.mp4 50s.mp4 -d 30%
=head2 Specify end only (using h:m:s notation), the result is 100s.cut_0_to_63.mp4
% cut-video-by-duration 100s.mp4 -e 00:01:03
=head2 Specify start & end only (using h:m:s notation), the result is 100s.cut_50_to_63.mp4
% cut-video-by-duration 100s.mp4 -s 00:00:50 -e 00:01:03
script/split-video-by-duration view on Meta::CPAN
% split-video-by-duration --every 15min foo.mp4
=head2 Split video per 30s for WhatsApp status
% split-video-by-duration foo.mp4 30s
=head2 Split video into 4 equiduration parts
% split-video-by-duration foo.mp4 --parts 4
=head2 Another way to split into equiduration parts using percentage in --every
% split-video-by-duration foo.mp4 --every 25%
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-FfmpegUtils>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-FfmpegUtils>.
script/vcut view on Meta::CPAN
=head2 other shells
For fish and zsh, install L<shcompgen> as described above.
=head1 EXAMPLES
=head2 Specify start only, the result is 100s.cut_40_to_100.mp4
% vcut 100s.mp4 -s 40s
=head2 Specify duration only (using percentage) of two files, the results are 100s.cut_0_to_30.mp4 & 50s.cut_0_to_15.mp4
% vcut 100s.mp4 50s.mp4 -d 30%
=head2 Specify end only (using h:m:s notation), the result is 100s.cut_0_to_63.mp4
% vcut 100s.mp4 -e 00:01:03
=head2 Specify start & end only (using h:m:s notation), the result is 100s.cut_50_to_63.mp4
% vcut 100s.mp4 -s 00:00:50 -e 00:01:03
script/vsplit view on Meta::CPAN
% vsplit --every 15min foo.mp4
=head2 Split video per 30s for WhatsApp status
% vsplit foo.mp4 30s
=head2 Split video into 4 equiduration parts
% vsplit foo.mp4 --parts 4
=head2 Another way to split into equiduration parts using percentage in --every
% vsplit foo.mp4 --every 25%
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-FfmpegUtils>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-FfmpegUtils>.