diff options
| author | Klaus Schmidinger <vdr@tvdr.de> | 2011-08-14 13:50:26 +0200 | 
|---|---|---|
| committer | Klaus Schmidinger <vdr@tvdr.de> | 2011-08-14 13:50:26 +0200 | 
| commit | c13d6e6070d895dd33f82e80b5d045cbb417bc6c (patch) | |
| tree | c5b2a1cc93137e50c95da713504af997afe9a3f4 /PLUGINS | |
| parent | 5e2f8e761343f72ed0c491c6b2caa64637a04f54 (diff) | |
| download | vdr-c13d6e6070d895dd33f82e80b5d045cbb417bc6c.tar.gz vdr-c13d6e6070d895dd33f82e80b5d045cbb417bc6c.tar.bz2 | |
The pic2mpg script of the 'pictures' plugin now generates HD images
Diffstat (limited to 'PLUGINS')
| -rw-r--r-- | PLUGINS/src/pictures/HISTORY | 6 | ||||
| -rwxr-xr-x | PLUGINS/src/pictures/pic2mpg | 90 | ||||
| -rwxr-xr-x | PLUGINS/src/pictures/pic2mpg-sd | 193 | 
3 files changed, 221 insertions, 68 deletions
| diff --git a/PLUGINS/src/pictures/HISTORY b/PLUGINS/src/pictures/HISTORY index b67bbaca..7e82a3c7 100644 --- a/PLUGINS/src/pictures/HISTORY +++ b/PLUGINS/src/pictures/HISTORY @@ -49,3 +49,9 @@ VDR Plugin 'pictures' Revision History  2011-07-23:  - Now rotating images according to the EXIF 'Orientation' parameter. + +2011-08-14: + +- The pic2mpg script now generates HD images (thanks to Andre Weidemann for his +  support in using convert/ffmpeg). The old SD version is still available as +  pic2mpg-sd. diff --git a/PLUGINS/src/pictures/pic2mpg b/PLUGINS/src/pictures/pic2mpg index 6213091e..190ec260 100755 --- a/PLUGINS/src/pictures/pic2mpg +++ b/PLUGINS/src/pictures/pic2mpg @@ -7,63 +7,45 @@  #  # See the README file for copyright information and how to reach the author.  # -# $Id: pic2mpg 2.1 2011/07/23 14:23:59 kls Exp $ - -## TODO implement HDTV (1920 x 1080) +# $Id: pic2mpg 2.2 2011/08/14 13:34:15 kls Exp $  use File::Path;  use File::Spec;  use Getopt::Std;  use Image::ExifTool qw(:Public); -use Image::Size;  $Usage = qq{  Usage: $0 [options] picture-dir mpeg-dir         $0 [options] picture-file mpeg-file -Options: -a             Aspect ratio 4:3 (default is 16:9) -         -f             Force conversion +Options: -f             Force conversion           -h             print Help -         -i             Ignore unknown file types -         -n             NTSC (default is PAL) +         -s size        Screen size (WIDTHxHEIGHT, default is 1920x1080)           -v num         Verbose (0=none, 1=list files, 2=detailed) -         -x percent     X overscan in percent -         -y percent     Y overscan in percent  }; -getopts("afhinv:x:y:") || die $Usage; +getopts("fhs:v:") || die $Usage;  die $Usage if $opt_h; -$Aspect    = $opt_a;  $Force     = $opt_f; -$Ignore    = $opt_i; -$NTSC      = $opt_n; +$Size      = $opt_s || "1920x1080";  $Verbose   = $opt_v; -$OverscanX = $opt_x; -$OverscanY = $opt_y;  $ListFiles = $Verbose >= 1;  $Detailed  = $Verbose >= 2; -# Screen size: - -$SW = $NTSC ? 720 : 720; -$SH = $NTSC ? 480 : 576; - -$ScreenRatio = $Aspect ? 4 / 3 : 16 / 9; - -# Converter programs: - -%PNMCONV = ( -  bmp  => "bmptopnm", -  gif  => "giftopnm", -  jpeg => "jpegtopnm", -  jpg  => "jpegtopnm", -  png  => "pngtopnm", -  pnm  => "cat", -  tif  => "tifftopnm", -  tiff => "tifftopnm", +# Supported picture types:                                                                                                        + +%PICTYPES = (                                                                                                                   +  bmp  => 1, +  gif  => 1, +  jpeg => 1, +  jpg  => 1, +  png  => 1, +  pnm  => 1, +  tif  => 1, +  tiff => 1,    );  # Command options: @@ -72,13 +54,6 @@ die "$0: missing parameter\n" unless $ARGV[0] && $ARGV[1];  die "$0: file or directory not found: $ARGV[0]\n" unless -e $ARGV[0];  die "$0: source and destination must be different\n" if $ARGV[0] eq $ARGV[1]; -$verbose1  = $Detailed ? "--verbose" : ""; -$verbose2  = $Detailed ? "-v 2" : "-v 0"; -$system1   = $NTSC ? "" : "--pal"; -$system2   = $NTSC ? "n" : "p"; -$framerate = $NTSC ? "30000:1001" : "25:1"; -$aspect    = $Aspect ? "2" : "3"; -  # Convert a single file:  if (-f $ARGV[0]) { @@ -96,7 +71,7 @@ $MPGDIR = File::Spec->rel2abs($ARGV[1]);  chdir($PICDIR) || die "$PICDIR: $!\n"; -@Pictures = `find -type f`; +@Pictures = `find -type f | sort`;  chomp(@Pictures);  for $pic (@Pictures) { @@ -146,39 +121,18 @@ sub ConvertFile  {    my ($Pict, $Mpeg) = @_;    (my $Type) = lc($Pict) =~ /\.([^\.]*)$/; -  if (!defined $PNMCONV{$Type}) { -     return if ($Ignore); -     die "unknown file type '$Type': '$Pict'\n"; -     } -  my ($w, $h) = imgsize($Pict); -  print "image size is $w x $h\n" if ($Detailed); +  return if (!defined $PICTYPES{$Type});    my $Exif = ImageInfo($Pict);    my $Orientation = $$Exif{"Orientation"};    my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /;  -  my $Rotate = "-null"; -  $Rotate = "-cw"   if $Degrees eq "90"; -  $Rotate = "-ccw"  if $Degrees eq "270"; -  $Rotate = "-r180" if $Degrees eq "180"; +  my $Rotate = $Degrees ? "-rotate $Degrees" : "";    print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed); -  ($w, $h) = ($h, $w) if ($Degrees eq "90" || $Degrees eq "270"); -  if ($w / $h <= $ScreenRatio) { -     $w = $h * $ScreenRatio; -     } -  else { -     $h = $w / $ScreenRatio; -     } -  my $ScaleW = $SW / $w * (100 - 2 * $OverscanX) / 100; -  my $ScaleH = $SH / $h * (100 - 2 * $OverscanY) / 100;    $Pict = EscapeMeta($Pict);    $Mpeg = EscapeMeta($Mpeg);    print "$Pict -> $Mpeg $Rotate\n" if $ListFiles; -  my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |" -          . "pamflip $verbose1 $Rotate |" -          . "pnmscale $verbose1 --xscale=$ScaleW --yscale=$ScaleH |" -          . "pnmpad $verbose1 --black --width $SW --height $SH |" -          . "ppmntsc $verbose1 $system1 |" -          . "ppmtoy4m $verbose2 -F $framerate -I p -S 420mpeg2 |" -          . "mpeg2enc $verbose2 -f 3 -b 12500 -a $aspect -q 1 -n $system2 -o $Mpeg"; +  my $Cmd = "convert $Pict -background '#000000' $Rotate -resize $Size -gravity center -extent $Size ppm:- | " +          . "ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an -vcodec libx264 -vpre baseline -s $Size -qscale 2 -f mpegts -y $Mpeg " +          . ($Detailed ? "" : "2>/dev/null");    !system($Cmd) || die "$Cmd: $!\n";    $Cmd = "touch -r $Pict $Mpeg";    !system($Cmd) || die "$Cmd: $!\n"; diff --git a/PLUGINS/src/pictures/pic2mpg-sd b/PLUGINS/src/pictures/pic2mpg-sd new file mode 100755 index 00000000..15549dcd --- /dev/null +++ b/PLUGINS/src/pictures/pic2mpg-sd @@ -0,0 +1,193 @@ +#!/usr/bin/perl + +# pic2mpg: Convert picture files to MPEG still frames +# +# Converts either a single picture file or all files in a +# given directory (recursively) to MPEG still frames. +# +# See the README file for copyright information and how to reach the author. +# +# $Id: pic2mpg-sd 2.1 2011/07/23 14:23:59 kls Exp $ + +## TODO implement HDTV (1920 x 1080) + +use File::Path; +use File::Spec; +use Getopt::Std; +use Image::ExifTool qw(:Public); +use Image::Size; + +$Usage = qq{ +Usage: $0 [options] picture-dir mpeg-dir +       $0 [options] picture-file mpeg-file + +Options: -a             Aspect ratio 4:3 (default is 16:9) +         -f             Force conversion +         -h             print Help +         -i             Ignore unknown file types +         -n             NTSC (default is PAL) +         -v num         Verbose (0=none, 1=list files, 2=detailed) +         -x percent     X overscan in percent +         -y percent     Y overscan in percent +}; + +getopts("afhinv:x:y:") || die $Usage; + +die $Usage if $opt_h; + +$Aspect    = $opt_a; +$Force     = $opt_f; +$Ignore    = $opt_i; +$NTSC      = $opt_n; +$Verbose   = $opt_v; +$OverscanX = $opt_x; +$OverscanY = $opt_y; + +$ListFiles = $Verbose >= 1; +$Detailed  = $Verbose >= 2; + +# Screen size: + +$SW = $NTSC ? 720 : 720; +$SH = $NTSC ? 480 : 576; + +$ScreenRatio = $Aspect ? 4 / 3 : 16 / 9; + +# Converter programs: + +%PNMCONV = ( +  bmp  => "bmptopnm", +  gif  => "giftopnm", +  jpeg => "jpegtopnm", +  jpg  => "jpegtopnm", +  png  => "pngtopnm", +  pnm  => "cat", +  tif  => "tifftopnm", +  tiff => "tifftopnm", +  ); + +# Command options: + +die "$0: missing parameter\n" unless $ARGV[0] && $ARGV[1]; +die "$0: file or directory not found: $ARGV[0]\n" unless -e $ARGV[0]; +die "$0: source and destination must be different\n" if $ARGV[0] eq $ARGV[1]; + +$verbose1  = $Detailed ? "--verbose" : ""; +$verbose2  = $Detailed ? "-v 2" : "-v 0"; +$system1   = $NTSC ? "" : "--pal"; +$system2   = $NTSC ? "n" : "p"; +$framerate = $NTSC ? "30000:1001" : "25:1"; +$aspect    = $Aspect ? "2" : "3"; + +# Convert a single file: + +if (-f $ARGV[0]) { +   die "$0: mixed file and directory ('$ARGV[0]' <-> '$ARGV[1]')\n" unless !-e $ARGV[1] || -f $ARGV[1]; +   ConvertFile($ARGV[0], $ARGV[1]); +   exit; +   } + +die "$0: mixed directory and file ('$ARGV[0]' <-> '$ARGV[1]')\n" unless !-e $ARGV[1] || -d $ARGV[1]; + +$PICDIR = File::Spec->rel2abs($ARGV[0]); +$MPGDIR = File::Spec->rel2abs($ARGV[1]); + +# Convert pictures to mpegs: + +chdir($PICDIR) || die "$PICDIR: $!\n"; + +@Pictures = `find -type f`; +chomp(@Pictures); + +for $pic (@Pictures) { +    my $mpg = "$MPGDIR/$pic.mpg"; +    if ($Force || !-e $mpg || -M $mpg > -M $pic) { +       (my $dir = $mpg) =~ s/\/[^\/]*$//; +       mkpath($dir); +       ConvertFile($pic, $mpg); +       } +    } + +# Remove mpegs without pictures: + +chdir($MPGDIR) || die "$MPGDIR: $!\n"; + +@Mpegs = `find -type f`; +chomp(@Mpegs); + +for $mpg (@Mpegs) { +    my $pic = "$PICDIR/$mpg"; +    $pic =~ s/\.mpg$//; +    if (!-e $pic) { +       print "removing $mpg\n"; +       unlink($mpg); +       } +    } + +# Remove empty directories: + +chdir($MPGDIR) || die "$MPGDIR: $!\n"; + +for ($i = 0; $i < 10; $i++) { # dirs might become empty when removing empty subdirs +    @Dirs = `find -type d -empty`; +    chomp(@Dirs); +    last unless @Dirs; + +    for $dir (@Dirs) { +        $dir = EscapeMeta($dir); +        print "removing $dir\n"; +        !system("rm -rf $dir") || die "$dir: $!\n"; +        } +    } + +# Actual file conversion: + +sub ConvertFile +{ +  my ($Pict, $Mpeg) = @_; +  (my $Type) = lc($Pict) =~ /\.([^\.]*)$/; +  if (!defined $PNMCONV{$Type}) { +     return if ($Ignore); +     die "unknown file type '$Type': '$Pict'\n"; +     } +  my ($w, $h) = imgsize($Pict); +  print "image size is $w x $h\n" if ($Detailed); +  my $Exif = ImageInfo($Pict); +  my $Orientation = $$Exif{"Orientation"}; +  my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /; +  my $Rotate = "-null"; +  $Rotate = "-cw"   if $Degrees eq "90"; +  $Rotate = "-ccw"  if $Degrees eq "270"; +  $Rotate = "-r180" if $Degrees eq "180"; +  print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed); +  ($w, $h) = ($h, $w) if ($Degrees eq "90" || $Degrees eq "270"); +  if ($w / $h <= $ScreenRatio) { +     $w = $h * $ScreenRatio; +     } +  else { +     $h = $w / $ScreenRatio; +     } +  my $ScaleW = $SW / $w * (100 - 2 * $OverscanX) / 100; +  my $ScaleH = $SH / $h * (100 - 2 * $OverscanY) / 100; +  $Pict = EscapeMeta($Pict); +  $Mpeg = EscapeMeta($Mpeg); +  print "$Pict -> $Mpeg $Rotate\n" if $ListFiles; +  my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |" +          . "pamflip $verbose1 $Rotate |" +          . "pnmscale $verbose1 --xscale=$ScaleW --yscale=$ScaleH |" +          . "pnmpad $verbose1 --black --width $SW --height $SH |" +          . "ppmntsc $verbose1 $system1 |" +          . "ppmtoy4m $verbose2 -F $framerate -I p -S 420mpeg2 |" +          . "mpeg2enc $verbose2 -f 3 -b 12500 -a $aspect -q 1 -n $system2 -o $Mpeg"; +  !system($Cmd) || die "$Cmd: $!\n"; +  $Cmd = "touch -r $Pict $Mpeg"; +  !system($Cmd) || die "$Cmd: $!\n"; +} + +sub EscapeMeta +{ +  my $META = ' !"#$%&\'()*;<>?[\\]`{|}~'; +  my $s = shift; +  $s =~ s/([$META])/\\$1/g; +  return $s; +} | 
