mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Added the 'pictures' plugin
This commit is contained in:
176
PLUGINS/src/pictures/pic2mpg
Executable file
176
PLUGINS/src/pictures/pic2mpg
Executable file
@@ -0,0 +1,176 @@
|
||||
#!/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 1.1 2008/01/13 11:39:12 kls Exp $
|
||||
|
||||
## TODO implement HDTV (1920 x 1080)
|
||||
|
||||
use File::Path;
|
||||
use Getopt::Std;
|
||||
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)
|
||||
-h print Help
|
||||
-f Force conversion
|
||||
-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("ahfnv:x:y:") || die $Usage;
|
||||
|
||||
die $Usage if $opt_h;
|
||||
|
||||
$Aspect = $opt_a;
|
||||
$Force = $opt_f;
|
||||
$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 = $ARGV[0];
|
||||
$MPGDIR = $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) = $Pict =~ /\.([^\.]*)$/;
|
||||
die "unknown file type '$Type': '$Pict'\n" unless defined $PNMCONV{$Type};
|
||||
my ($w, $h) = imgsize($Pict);
|
||||
print "image size is $w x $h\n" if ($Detailed);
|
||||
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\n" if $ListFiles;
|
||||
my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |"
|
||||
. "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;
|
||||
}
|
||||
Reference in New Issue
Block a user