App-FfmpegUtils

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


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.

META.json  view on Meta::CPAN

            "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",

META.json  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",
            "perl" : "5.010001",
            "strict" : "0",
            "warnings" : "0"
         }
      },
      "test" : {
         "requires" : {

META.yml  view on Meta::CPAN

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'

META.yml  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'
  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) } ) {

README  view on Meta::CPAN


    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).

README  view on Meta::CPAN

     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

README  view on Meta::CPAN


    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).

README  view on Meta::CPAN


    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>.



( run in 0.504 second using v1.01-cache-2.11-cpan-05162d3a2b1 )