Ignore:
Timestamp:
2009-02-20T11:40:23+13:00 (15 years ago)
Author:
davidb
Message:

Restructing of VideoPlugin to be like ImagePlugin (with its supporting ImageConverter plugin). The pattern was then repeated for Audio, so we now have an AudioPlugin and AudioConverter. Where possible code is shared in a Multimedia base class

File:
1 edited

Legend:

Unmodified
Added
Removed
  • extensions/gsdl-video/trunk/perllib/plugins/MultimediaConverter.pm

    r18543 r18556  
    1 ##########################################################################
    2 #
    3 # videoconvert.pm -- utility to help convert video file
    4 #
    5 # Copyright (C) 1999 DigiLib Systems Limited, NZ
     1###########################################################################
     2#
     3# MultimediaConverter - helper plugin that does audio and video conversion using ffmpeg
     4#
     5# A component of the Greenstone digital library software
     6# from the New Zealand Digital Library Project at the
     7# University of Waikato, New Zealand.
     8#
     9# Copyright (C) 2008 New Zealand Digital Library Project
    610#
    711# This program is free software; you can redistribute it and/or modify
     
    2024#
    2125###########################################################################
    22 
    23 
    24 package videoconvert;
     26package MultimediaConverter;
     27
     28use BaseMediaConverter;
     29
    2530
    2631use strict;
    2732no strict 'refs'; # allow filehandles to be variables and viceversa
    2833
    29 use baseconvert;
    30 
    31 sub BEGIN {
    32     @videoconvert::ISA = ('baseconvert');
    33 }
    34 
    35 
    36 # Discover the characteristics of a video file.
    37 #  Equivalent step to that in ImagePlugin that uses ImageMagicks's 'indentify' utility
    38 #  Here we use 'ffmpeg' for video but for consistency keep the Perl method name the same
    39 #  as before
     34use gsprintf 'gsprintf';
     35
     36BEGIN {
     37    @MultimediaConverter::ISA = ('BaseMediaConverter');
     38}
     39
     40my $arguments = [
     41      { 'name' => "converttotype",
     42    'desc' => "{ImageConverter.converttotype}",
     43    'type' => "string",
     44    'deft' => "",
     45    'reqd' => "no" },
     46      { 'name' => "minimumsize",
     47    'desc' => "{ImageConverter.minimumsize}",
     48    'type' => "int",
     49    'deft' => "100",
     50    'range' => "1,",
     51    'reqd' => "no" },
     52         ];
     53
     54my $options = { 'name' => "MultimediaConverter",
     55        'desc' => "{MultimediaConverter.desc}",
     56        'abstract' => "yes",
     57        'inherits' => "yes",
     58        'args' => $arguments };
     59
     60sub new {
     61    my ($class) = shift (@_);
     62    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
     63    push(@$pluginlist, $class);
     64
     65    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
     66    push(@{$hashArgOptLists->{"OptList"}},$options);
     67
     68    my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
     69
     70
     71    return bless $self, $class;
     72
     73}
     74
     75
     76
     77# needs to be called after BasePlugin init, so that outhandle is set up.
     78sub init {
     79    my $self = shift(@_);
     80
     81    my $outhandle = $self->{'outhandle'};
     82
     83    $self->{'tmp_file_paths'} = ();
     84
     85    # Check that ffmpeg is installed and available on the path
     86    my $multimedia_conversion_available = 1;
     87    my $no_multimedia_conversion_reason = "";
     88
     89    # None of this works very well on Windows 95/98...
     90    if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
     91    $multimedia_conversion_available = 0;
     92    $no_multimedia_conversion_reason = "win95notsupported";
     93    } else {
     94
     95    my $result = `ffmpeg -h 2>&1`;
     96
     97
     98    if (!defined $result || $result !~ m/^FFmpeg version/) {
     99        $self->{'ffmpeg_installed'} = 0;
     100        print $outhandle $result;
     101        $multimedia_conversion_available = 0;
     102        $no_multimedia_conversion_reason = "ffmpegnotinstalled";
     103    }
     104    else {
     105        $self->{'ffmpeg_installed'} = 1;
     106    }
     107    }
     108
     109    $self->{'multimedia_conversion_available'} = $multimedia_conversion_available;
     110    $self->{'no_multimedia_conversion_reason'} = $no_multimedia_conversion_reason;
     111
     112    if ($self->{'multimedia_conversion_available'} == 0) {
     113    &gsprintf($outhandle, "MultimediaConverter: {MultimediaConverter.noconversionavailable} ({MultimediaConverter.".$self->{'no_multimedia_conversion_reason'}."})\n");
     114    }
     115       
     116}
     117   
     118
    40119
    41120
    42121sub identify {
    43     my ($video, $outhandle, $verbosity) = @_;
    44 
    45     # Use the ffmpeg command to get the file specs
    46     my $command = "ffmpeg -i \"$video\"";
    47 
    48     print $outhandle "  $command\n" if ($verbosity > 2);
    49     my $result = '';
    50     $result = `$command 2>&1`;
    51     print $outhandle "  $result\n" if ($verbosity > 4);
    52 
    53     # Read the type, width, and height etc.
    54     my $vtype =  'unknown';
    55     my $vcodec = 'unknown';
    56     my $width =  'unknown';
    57     my $height = 'unknown';
    58     my $fps    = 'unknown';
    59 
    60     my $atype =  'unknown';
    61     my $afreq =  'unknown';
    62     my $achan =  'unknown';
    63     my $arate =  'unknown';
    64 
    65     my $video_safe = quotemeta $video;
    66 
    67     # strip off everything up to filename
    68     $result =~ s/^.*\'$video_safe\'://s;
    69 
    70     if ($result =~ m/Video: (.*?) fps/m) {
    71     my $video_info = $1;
    72     if ($video_info =~ m/([^,]+),(?: ([^,]+),)? (\d+)x(\d+),.*?(\d+\.\d+)/)
    73     {
    74         $vtype = $1;
    75         $vcodec = $2 if defined $2;
    76         $width = $3;
    77         $height = $4;
    78         $fps = $5;
    79     }
    80     }
    81 
    82 ##    if ($result =~ m/Video: (\w+), (\w+), (\d+)x(\d+),.*?(\d+\.\d+) fps/m) {
    83 #    if ($result =~ m/Video: ([^,]+),(?: ([^,]+),)? (\d+)x(\d+),.*?(\d+\.\d+) fps/m) {
    84 #   $vtype = $1;
    85 #   $vcodec = $2;
    86 #   $width = $3;
    87 #   $height = $4;
    88 #   $fps = $5;
    89 #    }
    90 
    91     if ($result =~ m/Audio: (\w+), (\d+) Hz, (\w+)(?:, (\d+.*))?/m) {
    92     $atype = $1;
    93     $afreq = $2;
    94     $achan = $3;
    95     $arate = $4 if (defined $4);
    96     }
    97 
    98     # Read the duration
    99     my $duration = "unknown";
    100     if ($result =~ m/Duration: (\d+:\d+:\d+\.\d+)/m) {
    101     $duration = $1;
    102     }
    103     print $outhandle "  file: $video:\t $vtype, $width, $height, $duration\n"
    104     if ($verbosity > 2);
    105 
    106     if ($verbosity >3) {
    107     print $outhandle "\t video codec=$vcodec, fps = $fps\n";
    108     print $outhandle "\t audio codec=$atype, freq = $afreq Hz, $achan, $arate\n";
    109     }
    110 
    111     # Return the specs
    112     return ($vtype, $width, $height, $duration, -s $video,
    113         $vcodec,$fps,$atype,$afreq,$achan,$arate);
    114 }
    115 
    116 
    117 sub vob_durations
    118 {
    119     my ($media_base_dir,$title_num,$outhandle) = @_;
    120 
    121     my $filter_re = sprintf("^VTS_%02d_[1-9]\\.VOB\$",$title_num);
    122 
    123     my $duration_info = {};
    124 
    125     if (opendir(VTSIN,$media_base_dir)) {
    126     my @vts_title_vobs = grep { $_ =~ m/$filter_re/ } readdir(VTSIN);
    127     closedir(VTSIN);
    128 
    129     foreach my $v (@vts_title_vobs) {
    130         my $full_v = &util::filename_cat($media_base_dir,$v);
    131 
    132         my ($vtype, $width, $height, $duration, $vsize,
    133         $vcodec,$fps,$atype,$afreq,$achan,$arate) = identify($full_v,$outhandle,0);
    134 
    135         my ($vob_num) = ($v =~ m/^VTS_\d\d_(\d)\.VOB$/);
    136 
    137         $duration_info->{$vob_num} = $duration;
    138         print STDERR "**** $title_num: $title_num, storing {$vob_num} => $duration\n";
    139 
    140     }
    141 
    142     }
    143     else {
    144     print $outhandle "Warning: unable to read files in directory $media_base_dir\n";
    145     }
    146    
    147     return $duration_info;
    148 
    149 }
    150 
    151 
    152 
    153 sub new {
    154     my ($class) = shift @_;
    155 
    156     my ($base_dir,$video_filename, $verbosity,$outhandle,
    157     $exp_duration,$ascii_only_filenames) = @_;
    158 
    159     my $self = new baseconvert($base_dir,$video_filename,$verbosity,$outhandle);
    160 
    161     $self->{'exp_duration'} = $exp_duration;
     122    my ($filename, $outhandle, $verbosity) = @_;
     123
     124    die "MultimediaConvert::identify() needs to be defined by inheriting plugin";
     125}
     126
     127
     128
     129sub init_cache_for_file {
     130    my $self = shift(@_);
     131
     132    my ($media_filename) = @_;
     133
     134    $self->SUPER::init_cache_for_file($media_filename);
     135
     136
     137    # This should probably be replaced with Anu's work that replaced
     138    # non-ASCII chars with URL encodings
     139
     140    my $ascii_only_filenames = $self->{'use_ascii_only_filenams'};
    162141
    163142    if (defined $ascii_only_filenames && ($ascii_only_filenames)) {
    164     my $file_root = $self->{'file_root'};
    165     $self->{'file_root'} = ascii_only_filename($file_root);
     143    my $file_root = $self->{'cached_file_root'};
     144    $self->{'cached_file_root'} = ascii_only_filename($file_root);
    166145    }
    167146                 
    168     my @ffmpeg_monitor   = ( 'monitor_init'   , "videoconvert::ffmpeg_monitor_init",
    169                  'monitor_line'   , "videoconvert::ffmpeg_monitor_line",
    170                  'monitor_deinit' , "videoconvert::ffmpeg_monitor_deinit" );
     147    my @ffmpeg_monitor   = ( 'monitor_init'   , "MultimediaConverter::ffmpeg_monitor_init",
     148                 'monitor_line'   , "MultimediaConverter::ffmpeg_monitor_line",
     149                 'monitor_deinit' , "MultimediaConverter::ffmpeg_monitor_deinit" );
    171150                   
    172     my @flvtool2_monitor = ( 'monitor_init'   ,"monitor_init_unbuffered",
    173                  'monitor_line'   , "videoconvert::flvtool2_monitor_line",
    174                  'monitor_deinit' , "monitor_deinit_unbuffered" );
    175151                   
    176152    $self->{'ffmpeg_monitor'} = \@ffmpeg_monitor;
    177     $self->{'flvtool2_monitor'} = \@flvtool2_monitor;
    178 
    179 
    180     return bless $self, $class;
    181 }
     153
     154
     155}
     156
     157
    182158
    183159
     
    216192
    217193    my $url = $file_unicode;
    218     $url =~ s/\x{2018}|\x{2019}|\x{201C}|\x{201D}//g; # remove smart quotes as cause problem in URL for video server
    219     $url =~ s/\x{2013}/\-/g; # change en-dash to '-' as again causes problems for video server
     194    $url =~ s/\x{2018}|\x{2019}|\x{201C}|\x{201D}//g; # remove smart quotes as cause problem in URL for streaming web server
     195    $url =~ s/\x{2013}/\-/g; # change en-dash to '-' as again causes problems for streaming web server
    220196   
    221197    return $url;
     
    255231
    256232
    257 
    258 sub optional_frame_scale
    259 {
    260     my $self = shift (@_);
    261     my ($orig_size,$video_width,$video_height) = @_;
    262 
    263     my $s_opt = "";
    264     if ($video_width > $video_height) {
    265     if ($video_width > $orig_size) {
    266         my $scale_factor = $orig_size/$video_width;
    267         my $scaled_width = int($video_width * $scale_factor);
    268         my $scaled_height = int($video_height * $scale_factor);
    269 
    270         # round to be ensure multiple of 2 (needed by some codecs)
    271         $scaled_width  = int($scaled_width/2)*2;
    272         $scaled_height = int($scaled_height/2)*2;
    273 
    274         $s_opt = "-s ${scaled_width}x${scaled_height}";
    275     }
    276     # else, video is smaller than requested size, don't scale up
    277     }
    278     else {
    279     if ($video_height > $orig_size) {
    280         my $scale_factor = $orig_size/$video_height;
    281         my $scaled_width = int($video_width * $scale_factor);
    282         my $scaled_height = int($video_height * $scale_factor);
    283 
    284         # round to be ensure multiple of 2 (needed by some codecs)
    285         $scaled_width  = int($scaled_width/2)*2;
    286         $scaled_height = int($scaled_height/2)*2;
    287 
    288         $s_opt = "-s ${scaled_width}x${scaled_height}";
    289     }
    290     # else, video is smaller than requested size, don't scale up
    291    
    292     }
    293    
    294     return $s_opt;
    295 }
    296 
    297 
    298 sub keyframe_cmd
    299 {
    300     my $self = shift (@_);
    301     my ($ivideo_filename) = @_;
    302 
    303     my $video_ext_dir = &util::filename_cat($ENV{'GSDLHOME'},"ext","video");
    304 
    305     my $output_dir = $self->{'cached_dir'};
    306     my $ivideo_root = $self->{'file_root'};
    307 
    308     my $oshot_filename = &util::filename_cat($output_dir,"shots.xml");
    309 
    310     my $exp_duration = $self->{'exp_duration'};
    311     my $t_opt = (defined $exp_duration) ? "-t $exp_duration" : "";
    312 
    313     my $main_opts = "-y $t_opt";
    314 
    315     my $hive = &util::filename_cat($video_ext_dir,"lib","vhook","hive.so");
    316 
    317     my $oflash_filename = &util::filename_cat($output_dir,"$ivideo_root\_keyframe.flv");
    318 
    319     my $vhook_opts = "$hive  -o $oshot_filename -k $output_dir $ivideo_filename";
    320 
    321     my $ivideo_filename_gsdlenv = $self->gsdlhome_independent($ivideo_filename);
    322     my $oflash_filename_gsdlenv = $self->gsdlhome_independent($oflash_filename);
    323 
    324     my $ffmpeg_cmd = "ffkeyframe  $main_opts -vhook \"$vhook_opts\"   -i \"$ivideo_filename_gsdlenv\" -an -y \"$oflash_filename_gsdlenv\"";
    325 
    326 
    327     return ($ffmpeg_cmd,$oflash_filename);
    328 }
    329 
    330 
    331 sub stream_cmd
    332 {
    333     my $self = shift (@_);
    334     my ($ivideo_filename,$video_width,$video_height,
    335     $streaming_quality,
    336     $streaming_bitrate,$streaming_size,
    337     $opt_streaming_achan, $opt_streaming_arate) = @_;
    338 
    339     my $streaming_achan
    340     = (defined $opt_streaming_achan) ? $opt_streaming_achan : 2;
    341 
    342     my $streaming_arate
    343     = (defined $opt_streaming_arate) ? $opt_streaming_arate : 22050;
    344 
    345     my $output_dir = $self->{'cached_dir'};
    346     my $ivideo_root = $self->{'file_root'};
    347 
    348     my $oflash_file = "${ivideo_root}_stream.flv";
    349     my $oflash_filename = &util::filename_cat($output_dir,$oflash_file);
    350 
    351     my $s_opt = $self->optional_frame_scale($streaming_size,$video_width,$video_height);
    352 
    353     my $exp_duration = $self->{'exp_duration'};
    354     my $t_opt = (defined $exp_duration) ? "-t $exp_duration" : "";
    355 
    356     my $main_opts = "-y $t_opt";
    357 
    358     my $bitrate_opt = "-b $streaming_bitrate";
    359     ### my $stream_opts = "-r 25 $s_opt";
    360     my $stream_opts .= " $s_opt -ac $streaming_achan -ar $streaming_arate";
    361 
    362     # -flags +ilme+ildct' and maybe '-flags +alt' for interlaced material, and try '-top 0/1'
    363 
    364     my $all_opts = "$main_opts $stream_opts";
    365 
    366     my $ffmpeg_cmd;
    367 
    368     my $ivideo_filename_gsdlenv = $self->gsdlhome_independent($ivideo_filename);
    369     my $oflash_filename_gsdlenv = $self->gsdlhome_independent($oflash_filename);
    370 
    371     if ($streaming_quality eq "high") {
    372 
    373     my $pass_log_file = &util::filename_cat($output_dir,"$ivideo_root-logpass.txt");
    374     if (-e $pass_log_file) {
    375         &util::rm($pass_log_file);
    376     }
    377 
    378     my $pass_log_file_gsdlenv = $self->gsdlhome_independent($pass_log_file);
    379 
    380     $all_opts .= " -passlogfile \"$pass_log_file_gsdlenv\"";
    381 
    382     my $ffmpeg_cmd_pass1 = "ffmpeg -pass 1 -i \"$ivideo_filename_gsdlenv\" $all_opts -y \"$oflash_filename_gsdlenv\"";
    383 
    384     my $ffmpeg_cmd_pass2 = "ffmpeg -pass 2 -i \"$ivideo_filename_gsdlenv\" $all_opts $bitrate_opt -y \"$oflash_filename_gsdlenv\"";
    385     $ffmpeg_cmd = "( $ffmpeg_cmd_pass1 ; $ffmpeg_cmd_pass2 )";
    386     }
    387     else {
    388     # single pass
    389 
    390     $ffmpeg_cmd = "ffmpeg -i \"$ivideo_filename_gsdlenv\" $all_opts -y \"$oflash_filename_gsdlenv\"";
    391     }
    392 
    393     return ($ffmpeg_cmd,$oflash_filename,$oflash_file);
    394 }
    395 
    396 
    397 
    398 sub audio_excerpt_cmd
    399 {
    400     my $self = shift (@_);
    401     my ($ivoa_filename,$hh,$mm,$ss,$opt_excerpt_len) = @_;
    402 
    403     # ivoa = input video or audio
    404 
    405     my $time_encoded = "$hh:$mm:$ss";
    406     my $time_encoded_file = "$hh$mm$ss";
    407    
    408    
    409     my $output_dir = $self->{'cached_dir'};
    410     my $ivoa_root = $self->{'file_root'};
    411 
    412     my $omp3_file = "${ivoa_root}_$time_encoded_file.mp3";
    413     my $omp3_filename = &util::filename_cat($output_dir,$omp3_file);
    414 
    415     my $all_opts = "-y -acodec mp3 -ss $time_encoded ";
    416 
    417     if (defined $opt_excerpt_len) {
    418     $all_opts .= "-t $opt_excerpt_len ";
    419     }
    420 
    421 
    422     my $ivoa_filename_gsdlenv = $self->gsdlhome_independent($ivoa_filename);
    423     my $omp3_filename_gsdlenv = $self->gsdlhome_independent($omp3_filename);
    424 
    425 
    426     my $ffmpeg_cmd = "ffmpeg -i \"$ivoa_filename_gsdlenv\" $all_opts  \"$omp3_filename_gsdlenv\"";
    427 
    428     return ($ffmpeg_cmd,$omp3_filename,$omp3_file);
    429 }
    430 
    431 
    432 
    433 sub streamseekable_cmd
    434 {
    435     my $self = shift (@_);
    436     my ($oflash_filename) = @_;
    437 
    438     my $output_dir = $self->{'cached_dir'};
    439     my $ivideo_root = $self->{'file_root'};
    440 
    441     my $cue_filename = &util::filename_cat($output_dir,"on_cue.xml");
    442 
    443     my $flvtool_cmd = "flvtool2 -vUP \"$oflash_filename\"";
    444 
    445     return ($flvtool_cmd,$oflash_filename);
    446 }
    447 
    448 
    449 sub streamkeyframes_cmd
    450 {
    451     my $self = shift (@_);
    452     my ($oflash_filename,$doc_obj,$section) = @_;
    453 
    454     my $assocfilepath
    455     = $doc_obj->get_metadata_element($section,"assocfilepath");
    456 
    457     my $output_dir = $self->{'cached_dir'};
    458 
    459     my $cue_filename = &util::filename_cat($output_dir,"on_cue.xml");
    460 
    461     my $video_server = $ENV{'GEXT_VIDEO_SERVER'};
    462     my $video_prefix = $ENV{'GEXT_VIDEO_PREFIX'};
    463 
    464     my $collect = $ENV{'GSDLCOLLECTION'};
    465  
    466     my $flvtool_cmd = "flvtool2 -vAUtP \"$cue_filename\" -thumbLocation:$video_server$video_prefix/collect/$collect/index/assoc/$assocfilepath \"$oflash_filename\"";
    467 
    468 
    469     return ($flvtool_cmd,$oflash_filename);
    470 }
    471 
    472 
    473 sub streamcuepts_cmd
    474 {
    475     my $self = shift (@_);
    476     my ($oflash_filename) = @_;
    477 
    478     my $output_dir = $self->{'cached_dir'};
    479 
    480     my $cue_filename = &util::filename_cat($output_dir,"on_cue.xml");
    481 
    482     my $video_server = $ENV{'GEXT_VIDEO_SERVER'};
    483     my $video_prefix = $ENV{'GEXT_VIDEO_PREFIX'};
    484 
    485     my $collect = $ENV{'GSDLCOLLECTION'};
    486     my $thumbloc = "$video_server$video_prefix/collect/$collect";
    487 
    488 
    489 #    my $flvtool_cmd = "flvtool2 -vUAtP \"$cue_filename\" -thumbLocation:$thumbloc \"$oflash_filename\"";
    490 
    491 #    my $flvtool_cmd = "flvtool2 -vUAt \"$cue_filename\" \"$oflash_filename\"";
    492 
    493 
    494 
    495 #    my $flvtool_cmd = "flvtool2 -vUAt \"$cue_filename\" \"$oflash_filename\"";
    496 
    497 
    498 ##    my $flvtool_cmd = "flvtool2 -vAt \"$cue_filename\" -UP \"$oflash_filename\" \"$output_dir/updated.flv\"";
    499 
    500 ##    my $flvtool_cmd = "flvtool2 -vAtU \"$cue_filename\" \"$oflash_filename\" \"$output_dir/updated.flv\"";
    501 
    502     my $flvtool_cmd = "flvtool2 -vAtUP \"$cue_filename\" \"$oflash_filename\"";
    503 
    504     return ($flvtool_cmd,$oflash_filename);
    505 }
    506 
    507 
    508 sub keyframe_thumbnail_cmd
    509 {
    510     my $self = shift (@_);
    511     my ($ivideo_filename,$thumbnailfile,$thumbnailwidth,$thumbnailheight) = @_;
    512 
    513     my $output_dir = $self->{'cached_dir'};
    514     my $ivideo_root = $self->{'file_root'};
    515 
    516     my $key_filename_prefix = &util::filename_cat($output_dir,$ivideo_root);
    517 
    518 
    519     # Try for 4th keyframe, but fall back to 1st if doesn't exist
    520     my $key_filename = "${key_filename_prefix}_0003.jpg";
    521     $key_filename = "${key_filename_prefix}_0000.jpg" if (!-e $key_filename);
    522 
    523     my $key_filename_gsdlenv = $self->gsdlhome_independent($key_filename);
    524     my $thumbnailfile_gsdlenv = $self->gsdlhome_independent($thumbnailfile);
    525 
    526     my $command;
    527 
    528     if (-e $key_filename) {
    529     $command = "convert -interlace plane -verbose -geometry $thumbnailwidth"
    530         . "x$thumbnailheight \"$key_filename_gsdlenv\" \"$thumbnailfile_gsdlenv\"";
    531     }
    532     else {
    533     # extractkeyframe has either not been switched on, or else had
    534     # a problem when running
    535     # => extract a from
    536     # my $frame_rate = 1.0 / 60.0;
    537    
    538     my $ivideo_filename_gsdlenv = $self->gsdlhome_independent($ivideo_filename);
    539 
    540 
    541 
    542     $command = "ffmpeg -i \"$ivideo_filename_gsdlenv\"  -ss 12.5 -vframes 1 -f image2 -s ${thumbnailwidth}x${thumbnailheight} -y \"$thumbnailfile_gsdlenv\"";
    543 
    544     # fmpeg -i input.dv -r 1 -f image2 -s 120x96 images%05d.png
    545     }
    546 
    547     return ($command,$thumbnailfile);
    548 }
    549 
    550 
    551 sub keyframe_montage_cmd
    552 {
    553     my $self = shift (@_);
    554     my ($ivideo_filename,$montagefile) = @_;
    555 
    556     my $output_dir = $self->{'cached_dir'};
    557     my $ivideo_root = $self->{'file_root'};
    558 
    559     my $key_filename_prefix = &util::filename_cat($output_dir,$ivideo_root);
    560 
    561     my $options = "-tile 10  -geometry 75x62+2+2";
    562 
    563     my $command = "montage $options ${key_filename_prefix}_*.jpg \"$montagefile\"";
    564 
    565     return ($command,$montagefile);
    566 }
    567 
    568 
    569 
    570 sub parse_shot_xml
    571 {
    572     my ($self) = shift(@_);
    573 
    574     my ($plugin) = @_;
    575 
    576     my $outhandle = $self->{'outhandle'};
    577     my $output_dir = $self->{'cached_dir'};
    578 
    579     my $shots_filename = &util::filename_cat($output_dir,"shots.xml");
    580 
    581     eval {
    582     $plugin->{'parser'}->parsefile($shots_filename);
    583     };
    584    
    585     if ($@) {
    586     print $outhandle "videoconvert.pm: skipping $shots_filename as not conformant to Hive shot syntax\n" if ($self->{'verbosity'} > 1);
    587     print $outhandle "\n Perl Error:\n $@\n" if ($self->{'verbosity'}>2);
    588     return 0;
    589     }
    590 
    591 }
    592 
    593 sub associate_keyframes_old
    594 {
    595     my ($self) = shift(@_);
    596 
    597     my ($doc_obj,$section,$plugin) = @_;
    598 
    599     my $output_dir = $self->{'cached_dir'};
    600 
    601     my $count = 1;
    602     foreach my $kframe_file (@{$plugin->{'keyframe_fnames'}}) {
    603 
    604     my $kframe_filename = &util::filename_cat($output_dir,$kframe_file);
    605     $doc_obj->associate_file($kframe_filename,"keyframe$count.jpg","image/jpeg",
    606                  $section);
    607     $count++;
    608     }
    609 
    610     $doc_obj->add_utf8_metadata($section,"NumKeyframes",scalar(@{$plugin->{'keyframe_fnames'}}));
    611 
    612 
    613     # *****
    614     # $doc_obj->add_metadata ($section, "thumblist", $plugin->{'flowplayer_thumblist'});
    615 
    616 }
    617 
    618 sub associate_keyframes
    619 {
    620     my ($self) = shift(@_);
    621 
    622     my ($doc_obj,$section,$plugin) = @_;
    623 
    624     my $output_dir = $self->{'cached_dir'};
    625     my $timeline = $plugin->{'keyframe_timeline'};
    626    
    627     my $count = 1;
    628 
    629     foreach my $t (sort { $timeline->{$a}->{'keyframeindex'} <=> $timeline->{$b}->{'keyframeindex'} } keys %$timeline)
    630     {
    631     my $kframe_file = $timeline->{$t}->{'thumb'};
    632     my $timestamp = $timeline->{$t}->{'timestamp'};
    633 
    634     my $kframe_filename = &util::filename_cat($output_dir,$kframe_file);
    635     $doc_obj->associate_file($kframe_filename,"keyframe$count.jpg","image/jpeg",
    636                  $section);
    637     $doc_obj->add_utf8_metadata($section,"KeyframeTimestamp",$timestamp);
    638 
    639     $count++;
    640     }
    641 
    642     $doc_obj->add_utf8_metadata($section,"NumKeyframes",scalar(@{$plugin->{'keyframe_fnames'}}));
    643 
    644 
    645     # *****
    646     # $doc_obj->add_metadata ($section, "thumblist", $plugin->{'flowplayer_thumblist'});
    647 }
    648 
    649 
    650 
    651233sub ffmpeg_monitor_init
    652234{
     
    693275
    694276
    695 sub flvtool2_monitor_line
    696 {
    697     my ($line) = @_;
    698 
    699     my $had_error = 0;
    700     my $generate_dot = 1;
    701 
    702     if ($line =~ m/\s+\- /) {
    703     # ignore tabulated output printed at end of command
    704     $generate_dot = 0;
    705     }
    706    
    707     if ($line =~ m/^Error:/i) {
    708     $had_error = 1;
    709     }
    710 
    711     return ($had_error,$generate_dot);
    712 }
    713 
    714 
    715 
    716277
    717278
Note: See TracChangeset for help on using the changeset viewer.