mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
The pic2mpg script of the 'pictures' plugin now generates HD images
This commit is contained in:
parent
5e2f8e7613
commit
c13d6e6070
@ -2153,6 +2153,7 @@ Andr
|
|||||||
recording if Setup.UseDolbyDigital is true
|
recording if Setup.UseDolbyDigital is true
|
||||||
for suggesting that the primary device should only be avoided for recording if
|
for suggesting that the primary device should only be avoided for recording if
|
||||||
it is an old SD full featured card
|
it is an old SD full featured card
|
||||||
|
for his support in using convert/ffmpeg in the pic2mpg script of the 'pictures' plugin
|
||||||
|
|
||||||
Jürgen Schilling <juergen_schilling@web.de>
|
Jürgen Schilling <juergen_schilling@web.de>
|
||||||
for reporting that color buttons were displayed in the recording info menu if it
|
for reporting that color buttons were displayed in the recording info menu if it
|
||||||
|
5
HISTORY
5
HISTORY
@ -6650,7 +6650,7 @@ Video Disk Recorder Revision History
|
|||||||
- Added support for "content identifier descriptor" and "default authority descriptor"
|
- Added support for "content identifier descriptor" and "default authority descriptor"
|
||||||
to 'libsi' (thanks to Dave Pickles).
|
to 'libsi' (thanks to Dave Pickles).
|
||||||
|
|
||||||
2011-08-13: Version 1.7.20
|
2011-08-14: Version 1.7.20
|
||||||
|
|
||||||
- Added some missing 'const' to tChannelID (reported by Sundararaj Reel).
|
- Added some missing 'const' to tChannelID (reported by Sundararaj Reel).
|
||||||
- The isnumber() function now checks the given pointer for NULL (thanks to Holger
|
- The isnumber() function now checks the given pointer for NULL (thanks to Holger
|
||||||
@ -6683,3 +6683,6 @@ Video Disk Recorder Revision History
|
|||||||
by a call to cIndexFile::GetLength() (suggested by Christoph Haubrich).
|
by a call to cIndexFile::GetLength() (suggested by Christoph Haubrich).
|
||||||
- Fixed some crashes in subtitle display (thanks to Rolf Ahrenberg).
|
- Fixed some crashes in subtitle display (thanks to Rolf Ahrenberg).
|
||||||
- Made DELETENULL() thread safe (reported by Rolf Ahrenberg).
|
- Made DELETENULL() thread safe (reported by Rolf Ahrenberg).
|
||||||
|
- The pic2mpg script of the 'pictures' plugin 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.
|
||||||
|
@ -49,3 +49,9 @@ VDR Plugin 'pictures' Revision History
|
|||||||
2011-07-23:
|
2011-07-23:
|
||||||
|
|
||||||
- Now rotating images according to the EXIF 'Orientation' parameter.
|
- 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.
|
||||||
|
@ -7,63 +7,45 @@
|
|||||||
#
|
#
|
||||||
# See the README file for copyright information and how to reach the author.
|
# 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 $
|
# $Id: pic2mpg 2.2 2011/08/14 13:34:15 kls Exp $
|
||||||
|
|
||||||
## TODO implement HDTV (1920 x 1080)
|
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Spec;
|
use File::Spec;
|
||||||
use Getopt::Std;
|
use Getopt::Std;
|
||||||
use Image::ExifTool qw(:Public);
|
use Image::ExifTool qw(:Public);
|
||||||
use Image::Size;
|
|
||||||
|
|
||||||
$Usage = qq{
|
$Usage = qq{
|
||||||
Usage: $0 [options] picture-dir mpeg-dir
|
Usage: $0 [options] picture-dir mpeg-dir
|
||||||
$0 [options] picture-file mpeg-file
|
$0 [options] picture-file mpeg-file
|
||||||
|
|
||||||
Options: -a Aspect ratio 4:3 (default is 16:9)
|
Options: -f Force conversion
|
||||||
-f Force conversion
|
|
||||||
-h print Help
|
-h print Help
|
||||||
-i Ignore unknown file types
|
-s size Screen size (WIDTHxHEIGHT, default is 1920x1080)
|
||||||
-n NTSC (default is PAL)
|
|
||||||
-v num Verbose (0=none, 1=list files, 2=detailed)
|
-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;
|
die $Usage if $opt_h;
|
||||||
|
|
||||||
$Aspect = $opt_a;
|
|
||||||
$Force = $opt_f;
|
$Force = $opt_f;
|
||||||
$Ignore = $opt_i;
|
$Size = $opt_s || "1920x1080";
|
||||||
$NTSC = $opt_n;
|
|
||||||
$Verbose = $opt_v;
|
$Verbose = $opt_v;
|
||||||
$OverscanX = $opt_x;
|
|
||||||
$OverscanY = $opt_y;
|
|
||||||
|
|
||||||
$ListFiles = $Verbose >= 1;
|
$ListFiles = $Verbose >= 1;
|
||||||
$Detailed = $Verbose >= 2;
|
$Detailed = $Verbose >= 2;
|
||||||
|
|
||||||
# Screen size:
|
# Supported picture types:
|
||||||
|
|
||||||
$SW = $NTSC ? 720 : 720;
|
%PICTYPES = (
|
||||||
$SH = $NTSC ? 480 : 576;
|
bmp => 1,
|
||||||
|
gif => 1,
|
||||||
$ScreenRatio = $Aspect ? 4 / 3 : 16 / 9;
|
jpeg => 1,
|
||||||
|
jpg => 1,
|
||||||
# Converter programs:
|
png => 1,
|
||||||
|
pnm => 1,
|
||||||
%PNMCONV = (
|
tif => 1,
|
||||||
bmp => "bmptopnm",
|
tiff => 1,
|
||||||
gif => "giftopnm",
|
|
||||||
jpeg => "jpegtopnm",
|
|
||||||
jpg => "jpegtopnm",
|
|
||||||
png => "pngtopnm",
|
|
||||||
pnm => "cat",
|
|
||||||
tif => "tifftopnm",
|
|
||||||
tiff => "tifftopnm",
|
|
||||||
);
|
);
|
||||||
|
|
||||||
# Command options:
|
# 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: 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];
|
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:
|
# Convert a single file:
|
||||||
|
|
||||||
if (-f $ARGV[0]) {
|
if (-f $ARGV[0]) {
|
||||||
@ -96,7 +71,7 @@ $MPGDIR = File::Spec->rel2abs($ARGV[1]);
|
|||||||
|
|
||||||
chdir($PICDIR) || die "$PICDIR: $!\n";
|
chdir($PICDIR) || die "$PICDIR: $!\n";
|
||||||
|
|
||||||
@Pictures = `find -type f`;
|
@Pictures = `find -type f | sort`;
|
||||||
chomp(@Pictures);
|
chomp(@Pictures);
|
||||||
|
|
||||||
for $pic (@Pictures) {
|
for $pic (@Pictures) {
|
||||||
@ -146,39 +121,18 @@ sub ConvertFile
|
|||||||
{
|
{
|
||||||
my ($Pict, $Mpeg) = @_;
|
my ($Pict, $Mpeg) = @_;
|
||||||
(my $Type) = lc($Pict) =~ /\.([^\.]*)$/;
|
(my $Type) = lc($Pict) =~ /\.([^\.]*)$/;
|
||||||
if (!defined $PNMCONV{$Type}) {
|
return if (!defined $PICTYPES{$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 $Exif = ImageInfo($Pict);
|
||||||
my $Orientation = $$Exif{"Orientation"};
|
my $Orientation = $$Exif{"Orientation"};
|
||||||
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /;
|
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /;
|
||||||
my $Rotate = "-null";
|
my $Rotate = $Degrees ? "-rotate $Degrees" : "";
|
||||||
$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);
|
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);
|
$Pict = EscapeMeta($Pict);
|
||||||
$Mpeg = EscapeMeta($Mpeg);
|
$Mpeg = EscapeMeta($Mpeg);
|
||||||
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
|
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
|
||||||
my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |"
|
my $Cmd = "convert $Pict -background '#000000' $Rotate -resize $Size -gravity center -extent $Size ppm:- | "
|
||||||
. "pamflip $verbose1 $Rotate |"
|
. "ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an -vcodec libx264 -vpre baseline -s $Size -qscale 2 -f mpegts -y $Mpeg "
|
||||||
. "pnmscale $verbose1 --xscale=$ScaleW --yscale=$ScaleH |"
|
. ($Detailed ? "" : "2>/dev/null");
|
||||||
. "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";
|
!system($Cmd) || die "$Cmd: $!\n";
|
||||||
$Cmd = "touch -r $Pict $Mpeg";
|
$Cmd = "touch -r $Pict $Mpeg";
|
||||||
!system($Cmd) || die "$Cmd: $!\n";
|
!system($Cmd) || die "$Cmd: $!\n";
|
||||||
|
193
PLUGINS/src/pictures/pic2mpg-sd
Executable file
193
PLUGINS/src/pictures/pic2mpg-sd
Executable file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user