Added splitting by time (and untested processing functionality)
my $uthome = $ENV{HOME} . '/.utunes';
my $outdir = $ENV{HOME} . "/dspod";
my $name = "playlist";
-my $multi;
+my ($size, $time);
my $proc;
-#$proc = sub ...
+#$proc = sub {
+# my ($in, $out) = @_;
+#};
GetOptions(
"outdir=s" => \$outdir,
- "multi=s" => \$multi,
+ "size=s" => \$size,
+ "time=s" => \$time,
"name=s" => \$name,
);
+sub timeparse {
+ my ($s, $m, $h) = reverse split(/:/, shift);
+ return $h * 3600 + $m * 60 + $s;
+}
+
+sub songlength {
+ my $filename = shift;
+ my $length;
+
+ $filename =~ s/"/\\"/g;
+ open UDB, qq!udb info "$filename"|!;
+ while (<UDB>) {
+ if (/length\s+(.*)$/) {
+ $length = timeparse($1);
+ last;
+ }
+ }
+ close UDB;
+ return $length;
+}
+
mkdir $outdir unless -d $outdir;
-if ($multi) {
- if ($multi =~ /[Kk]$/) {
- $multi *= 10**3;
- } elsif ($multi =~ /[Mm]$/) {
- $multi *= 10**6;
- } elsif ($multi =~ /[Gg]$/) {
- $multi *= 10**9;
- } elsif ($multi =~ /[Tt]$/) {
- $multi *= 10**12;
+if ($size) {
+ if ($size =~ /[Kk]$/) {
+ $size *= 10**3;
+ } elsif ($size =~ /[Mm]$/) {
+ $size *= 10**6;
+ } elsif ($size =~ /[Gg]$/) {
+ $size *= 10**9;
+ } elsif ($size =~ /[Tt]$/) {
+ $size *= 10**12;
}
}
+if ($time) {
+ $time = timeparse($time);
+}
+
my @files;
open FILES, $ARGV[0] || "$ENV{HOME}/.utunes/playlist";
chomp(@files = <FILES>);
close FILES;
my $n = 0;
+my ($c, $t);
+my $residual; # The residual is a processed file from the previous iteration
+ # and is copied instead of reprocessed.
LIST: {
- my $c = 0;
+ $c = 0;
+ $t = 0;
my ($dir, $playlist);
- if ($multi) {
+ if ($size || $time) {
$dir = "$outdir/${name}_$n";
$playlist = "$outdir/${name}_$n/${name}_$n.m3u";
} else {
my $i = 0;
while (@files) {
- if ($multi && $c + -s $files[0] > $multi) {
+ my $file = shift @files;
+ my $length = songlength($file);
+ #print "$file\n$length\t$time\n";
+ next if $time && $length > $time;
+ my $outfile = sprintf("%04d_", $i) . basename $file;
+ print PLAYLIST "$outfile\n";
+ die "$dir/$outfile already exists!" if -e "$dir/$outfile";
+
+ if ($proc) {
+ if ($residual) {
+ move $residual, "$dir/$outfile";
+ } else {
+ # Process the file somehow
+ &$proc($file, "$dir/$outfile");
+ }
+ } else {
+ symlink $file, "$dir/$outfile"
+ or copy $file, "$dir/$outfile"
+ or die "Could not symlink or copy $file to $dir/$outfile";
+ }
+ if ($size && -s "$dir/$outfile" > $size) {
+ unlink "$dir/$outfile";
+ next;
+ }
+
+ # The size of a file will change if it is processed, but
+ # (unless something screwy is going on) the length will not.
+ if ($size && $c + -s "$dir/$outfile" > $size ||
+ $time && $t + $length > $time) {
$n++;
+ unshift @files, $file;
+ if ($proc) {
+ $residual = "$dir/$outfile";
+ }
+ print PLAYLIST "# $c bytes, $t seconds\n";
+
close PLAYLIST; # I don't strictly have to close the
# file (it is automatically closed when
# PLAYLIST is reopened above), but if I
# come across this and freak out.
goto LIST;
}
- my $file = shift @files;
- $c += -s $file;
- my $outfile = sprintf("%04d_", $i++) . basename $file;
- print PLAYLIST "$outfile\n";
- die "$dir/$outfile already exists!" if -e "$dir/$outfile";
- symlink $file, "$dir/$outfile"
- or copy $file, "$dir/$outfile"
- or die "Could not symlink or copy $file to $dir/$outfile";
+ $c += -s "$dir/$outfile";
+ $t += $length;
+ } continue {
+ $i++;
}
}
+print PLAYLIST "# $c bytes, $t seconds\n";
close PLAYLIST;