1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use Time::Piece;
6
7 if ( ! defined $ARGV[0] || ! defined $ARGV[1] ) {
8 print "Need to pass args\n";
9 exit 1;
10 }
11
12 my $ffmpegBin = `which ffmpeg`;
13 chomp $ffmpegBin;
14
15 if ( ! -e $ffmpegBin ) {
16 print "You need ffmpeg installed to use this\n";
17 exit 1;
18 }
19
20 my $track_list_path = shift(@ARGV);
21 my $full_file_path = shift(@ARGV);
22
23 my $track_list_file = `cat $track_list_path`;
24 chomp $track_list_file;
25
26 # Key is track name - val is array ref containing start time and end time
27 my %track_times;
28 my %track_names;
29
30 sub prepend_zeros($) {
31
32 my $time = shift;
33 if ( $time =~ m/^[0-9]{1,2}\:[0-9]{2}$/ ) {
34 if ( length $time == 4 ) {
35 $time = "00:0" . $time;
36 } elsif ( length $time == 5 ) {
37 $time = "00:" . $time;
38 } elsif ( length $time == 7 ) {
39 $time = "0" . $time;
40 } elsif ( length $time == 8 ) {
41 # Don't need to do anything
42 } else {
43 print "Couldn't prepend zero's for $time\n";
44 my $len = length $time;
45 print "length of $time is $len\n";
46 exit 1;
47 }
48
49 }
50
51 return $time;
52
53 }
54
55 sub remove_spaces($) {
56
57 my $track_name = shift;
58 if ( $track_name =~ m/\s/ ) {
59 $track_name =~ s/\s/_/g;
60 return $track_name;
61 }
62
63 return $track_name;
64
65 }
66
67 sub get_end_time($$) {
68
69 my $start_time = shift;
70 my $next_start_time = shift;
71 my $end_time;
72 if ( $next_start_time =~ m/^(.*)\:([0-9]{2})$/ ) {
73 my $end_time_val = $2 - 1;
74 if ( $end_time_val < 0 ) { $end_time_val = 0; }
75 if ( length $end_time_val == 1 ) { $end_time_val = "0" . $end_time_val; }
76 $end_time = $1 . ":" . $end_time_val;
77 $end_time = prepend_zeros($end_time);
78 return $end_time;
79 } else {
80 print "get_end_time couldn't match regex on $next_start_time - exiting\n";
81 exit 1;
82 }
83
84 }
85
86 sub get_track_length() {
87
88 my $ffmpegCmd = "$ffmpegBin -i '$full_file_path' 2>&1";
89 my $ffmpegOutput = `$ffmpegCmd`;
90 chomp $ffmpegOutput;
91 if ( ! defined $ffmpegOutput || $ffmpegOutput eq "" ) {
92 print "Something went wrong with calling $ffmpegCmd\n";
93 exit 1;
94 }
95
96 my $duration;
97 foreach my $line ( split("\n", $ffmpegOutput) ) {
98 if ( $line =~ m/Duration:\ (.*)\.[0-9]{2},/ ) {
99 $duration = $1;
100 return $duration;
101 }
102 }
103
104 print "Couldnt get duration of $full_file_path from $ffmpegCmd\n";
105 exit 1;
106 }
107
108 sub convert_to_mp3() {
109
110 my $filename;
111 if ( $full_file_path =~ m/^.*\/(.*)\.(mp4)$/ ) {
112 $filename = $1 . ".mp3";
113 } else {
114 print "Couldn't parse relative filename out of $full_file_path\n";
115 exit 1;
116 }
117
118 #my $ffmpegCmd = "ffmpeg -i '$full_file_path' -vn acodec libmp3lame -ac 2 -ab 160k -ar 48000 '$filename'";
119 my $ffmpegCmd = "ffmpeg -i '$full_file_path' -vn -acodec libmp3lame -ac 2 -qscale:a 4 -ar 48000 '$filename' > /dev/null 2>&1";
120
121 print "Converting $full_file_path to mp3...\n";
122 system("$ffmpegCmd") == 0 or die "Failed to convert $full_file_path to an mp3 with $ffmpegCmd\n";
123
124 return $filename;
125
126 }
127
128 sub run_split($$$$$) {
129
130 # ffmpeg -i Ryo\ Fukui\ -\ Scenery\ 1976\ \(FULL\ ALBUM\)-Hrr3dp7zRQY.mp4 -acodec copy -ss 00:00:00 -to 00:04:15 shibz.mp4
131 my $mp3_file = shift;
132 my $track_number = shift;
133 my $track_name = shift;
134 my $start_time = shift;
135 my $end_time = shift;
136 # Optionally covert to different codec?
137 my $filename = "$track_number" . "-" . "$track_name" . ".mp3";
138 my $ffmpegCmd = "$ffmpegBin -i '$mp3_file' -acodec copy -ss $start_time -to $end_time '$filename' > /dev/null 2>&1";
139 system("$ffmpegCmd") == 0 or die "Failed to run $ffmpegCmd\n";
140
141 }
142
143 foreach my $line ( split("\n",$track_list_file) ) {
144 #if ( $line =~ m/^([0-9]{1,2})\.\ (.*)\ ([0-9]{1,2}:[0-9]{2})$/ ) {
145 if ( $line =~ m/^([0-9]{1,2})\.\ (.*)\ (.*)$/ ) {
146 my @times;
147 # Start time
148 my $start_time = prepend_zeros($3);
149 push(@times, $start_time);
150 $track_times{$1} = \@times;
151 my $track_name = remove_spaces($2);
152 $track_names{$1} = $track_name;
153 } else {
154 print "$line doesn't match regex, exiting\n";
155 exit 1;
156 }
157 }
158
159 foreach my $track_number ( sort keys %track_times ) {
160
161 my $next_track_val = $track_number + 1;
162 my $next_start_time;
163 my $end_time;
164 if ( defined $track_times{$next_track_val} ) {
165 $next_start_time = $track_times{$next_track_val}[0];
166 $end_time = get_end_time($track_times{$track_number}[0],$next_start_time);
167 } else {
168 $end_time = get_track_length;
169 }
170
171 push(@{$track_times{$track_number}}, $end_time);
172
173 }
174
175 my $mp3_file = convert_to_mp3();
176
177 foreach my $track_number ( sort keys %track_times ) {
178
179 print "Splitting $track_number - $track_names{$track_number} - $track_times{$track_number}[0] - $track_times{$track_number}[1]\n";
180 run_split($mp3_file,$track_number,$track_names{$track_number},$track_times{$track_number}[0],$track_times{$track_number}[1]);
181
182 }