]> git.donarmstrong.com Git - bin.git/blob - rip_movie
* check for defined-ness of $a and $b
[bin.git] / rip_movie
1 #! /usr/bin/perl
2 # rip_movie uses HandBrakeCLI to rip movies, and is released
3 # under the terms of the GPL version 2, or any later version, at your
4 # option. See the file README and COPYING for more information.
5 # Copyright 2011 by Don Armstrong <don@donarmstrong.com>.
6 # $Id: perl_script 1432 2009-04-21 02:42:41Z don $
7
8
9 use warnings;
10 use strict;
11
12 use Getopt::Long;
13 use Pod::Usage;
14
15 =head1 NAME
16
17 rip_movie - Rips Movies using HandBrakeCLI
18
19 =head1 SYNOPSIS
20
21  rip_movie
22
23  Options:
24   --debug, -d debugging level (Default 0)
25   --help, -h display this help
26   --man, -m display manual
27
28 =head1 OPTIONS
29
30 =over
31
32 =item B<--output>
33
34 Override the output filename
35
36 =item B<--min-duration>
37
38 Minimum duration in minutes for a track to be considered an episode
39 (Default 25 minutes)
40
41 =item B<--titles>
42
43 Optional titles to rip; overrides title autodetection
44
45 =item B<--debug, -d>
46
47 Debug verbosity. (Default 0)
48
49 =item B<--help, -h>
50
51 Display brief usage information.
52
53 =item B<--man, -m>
54
55 Display this manual.
56
57 =back
58
59 =head1 EXAMPLES
60
61 rip_movie
62
63 =cut
64
65 use List::Util qw(reduce);
66
67 use vars qw($DEBUG);
68
69 my %options = (debug           => 0,
70                help            => 0,
71                man             => 0,
72                min_duration    => 25,
73                );
74
75 GetOptions(\%options,
76            'titles|title|t=i@',
77            'min_duration|min-duration=i',
78            'debug|d+','help|h|?','man|m');
79
80 pod2usage() if $options{help};
81 pod2usage({verbose=>2}) if $options{man};
82
83 $DEBUG = $options{debug};
84
85 my @titles_to_rip;
86
87 my @USAGE_ERRORS;
88 if (exists $options{min_duration}) {
89     $options{min_duration}*=60;
90 }
91 if (exists $options{titles}) {
92     for my $title (@{$options{titles}}) {
93         if ($title < 1) {
94             push @USAGE_ERRORS,"Title '$title' is not a valid title; must be greater than zero.";
95         }
96         push @titles_to_rip,$title;
97     }
98 }
99
100 pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
101
102
103 my $result = qx(HandBrakeCLI -i /dev/dvd -t 0 -o /dev/null 2>&1);
104
105 #print STDERR $result;
106 my ($title) = $result =~ /^libdvdnav:\s+DVD\s+Title:\s+(.+)/im;
107 die "no title" if not defined $title;
108 my $filename = lc($title);
109 $filename =~ s/[\s_-]+/_/;
110
111 my @titles;
112 for my $title_bit ($result =~ /\n(\+ title \d+:.+?)(?=\n\+ title\s+|$)/gs) {
113     my %title;
114     # title number
115     $title_bit =~ /^\+ title (\d+):/;
116     $title{num} = $1;
117     my ($duration) = $title_bit =~ /^\s+\+\s+duration:\s+([\d:]+)$/m;
118     # HH:MM:SS, so (HH*60 + MM) * 60 + SS
119     $duration = reduce {defined $a and defined $b ? $a * 60 + $b : undef } split /:/, $duration;
120     $title{duration} = $duration;
121     # figure out audio tracks
122     $title_bit =~ /(?<leadspace>\s+)\+\s+audio\s+tracks:\n # audio track header
123                    (?<audiotracks>(?:\g{leadspace}\s+\+\s+\d+\,.+\n){1,}) # audio track information
124                   /x;
125     my $at_info = $+{audiotracks};
126     my @at_nums = $at_info =~ /^\s+\+\s+(\d+)\,/mg;
127     $title{audio_tracks} = [@at_nums];
128     # figure out subtitle tracks
129     $title_bit =~ /(?<leadspace>\s+)\+\s+subtitle\s+tracks:\n # subtitle track header
130                    (?<subtittracks>(?:\g{leadspace}\s+\+\s+\d+\,.+(?:\n|$)){1,}) # subtitle track information
131                   /x;
132     my $st_info = $+{subtittracks};
133     my @st_nums = $st_info =~ /^\s+\+\s+(\d+)\,/mg;
134     $title{subtitle_tracks} = [@st_nums];
135     push @titles,\%title;
136 }
137
138 if (not @titles_to_rip) {
139     my $longest_title;
140     for my $i (0..$#titles) {
141         my $title = $titles[$i];
142         if (not defined $longest_title or
143             $title->{duration} > $titles[$longest_title]{duration}) {
144             $longest_title = $i;
145         }
146         if ($title->{duration} >= $options{min_duration}) {
147             push @titles_to_rip,$i+1;
148         }
149     }
150     if (not @titles_to_rip) {
151         push @titles_to_rip,$longest_title+1;
152     }
153 }
154 my $invalid_titles = 0;
155 for my $i (@titles_to_rip) {
156     if ($i > @titles or $i < 1) {
157         print STDERR "Invalid title $i\n";
158         $invalid_titles = 1;
159     }
160 }
161 exit 1 if $invalid_titles;
162
163 my $multiple_titles = @titles_to_rip > 1;
164
165 for my $i (@titles_to_rip) {
166     system('HandBrakeCLI','-i','/dev/dvd','-t',$i,
167            '-o',$filename.($multiple_titles ? '_'.$i : '').".mkv",
168            '-e','x264','-2','-q','21',
169            '-a',join(',',@{$titles[$i-1]{audio_tracks}}),
170            '-s',join(',',@{$titles[$i-1]{subtitle_tracks}}),
171           );
172 }
173
174
175
176
177
178 __END__