use -V0 --vbr-new by default; add -O option
[soepkiptng.git] / soepkiptng_sync_playlist
blob1334310f407d16501f8e299a3589e9ccad94d901
1 #!/usr/bin/perl
2 ############################################################################
3 # soepkiptng (c) copyright 2000 Eric Lammerts <eric@lammerts.org>.
4 ############################################################################
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License, version 2, as
7 # published by the Free Software Foundation.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # A copy of the GNU General Public License is available on the World Wide Web
15 # at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by
16 # writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 # Boston, MA 02111-1307, USA.
18 ############################################################################
20 use Cwd 'abs_path';
21 use DBI;
22 use File::Copy;
23 use File::Path;
25 my $mp3bitrate = 128;
26 my $maxbitrate = 170;
28 # find program directory
29 $_ = $0;
30 while(-l) {
31 my $l = readlink or die "readlink $_: $!\n";
32 if($l =~ m|^/|) { $_ = $l; } else { s|[^/]*$|/$l|; }
34 m|(.*)/|;
35 my $progdir = abs_path($1);
37 require "$progdir/soepkiptng.lib";
39 sub mystring_to_filename($;$) {
40 my ($a, $lang) = @_;
42 my $ampr = $lang eq "dut"? "en" : "and";
44 $a =~ s/[ _]?&[_ ]?/_${ampr}_/g;
45 $a =~ s/([\x80-\xff])/lc($latin9_to_ascii{ord($1)}) || $1/ge;
46 $a =~ s/[^- !_()',&A-Za-z0-9]+/_/g;
47 $a =~ s/[^-A-Za-z0-9]+/_/g;
48 $a =~ s/_$//;
49 return $a;
52 sub sysordie(@) {
53 printf STDERR "### %s\n", join(" ", @_);
54 printf LOG "### %s\n", join(" ", @_);
55 system @_;
56 die "$_[0] failed\n" if $?;
59 sub renameordie($$) {
60 printf LOG "*** rename %s -> %s\n", $_[0], $_[1];
61 rename $_[0], $_[1] or die "Error renaming $_[0] -> $_[1]: $!\n";
64 read_configfile(\%conf, $opt_c);
66 $| = 1;
68 $dbh = connect_to_db(\%conf);
70 $ARGV[0] or die <<EOF;
71 Usage: $0 <playlistname> [<dir>]
73 Iif dir is omitted, only print the space needed.
75 EOF
77 my $sth = $dbh->prepare("SELECT id FROM list WHERE name=?");
78 my $rv = $sth->execute($ARGV[0])
79 or die "can't do sql command: " . $dbh->errstr;
80 my ($lid) = $sth->fetchrow_array;
82 $sth = $dbh->prepare(<<EOF);
83 SELECT title,filename,track,artist.name as artist,album.name as album,length,encoding
84 FROM list_contents
85 LEFT JOIN song ON list_contents.song_id=song.id
86 LEFT JOIN album ON album.id=song.album_id
87 LEFT JOIN artist ON artist.id=song.artist_id
88 WHERE list_id=? AND present
89 ORDER BY artist,album,track,title,filename;
90 EOF
91 $sth->execute($lid);
93 if($ARGV[1] ne "") {
94 open LOG, ">$ARGV[1]/sync.txt";
96 if(open(F, "-|") == 0) {
97 exec "find", $ARGV[1], "-iname", "*.mp3", "-print0";
98 die "find";
100 $/ = "\0";
101 while(<F>) {
102 chop;
103 $deletefile{lc $_} = 1;
105 printf "%d existing files found in $ARGV[1]\n", scalar keys %deletefile;
106 } else {
107 open LOG, ">/dev/null";
110 my %copy;
111 my $num;
112 my $totlen;
113 my $totblocks;
114 my $trans;
115 while($_ = $sth->fetchrow_hashref) {
116 #print "$_->{filename}\n";
118 $num++;
119 $totlen += $_->{length};
120 my $sz;
121 if($_->{filename} =~ /\.mp3$/i && !($_->{encoding} =~ m!(\d+)kb/s! && $1 > $maxbitrate)) {
122 $sz = -s $_->{filename};
123 } else {
124 $sz = $_->{length} * $mp3bitrate * 1000 / 8;
125 $trans++;
126 $_->{needtranscode} = 1;
128 $totblocks += int(($sz + 4095) / 4096);
129 next if $ARGV[1] eq "";
131 my $newname = "$ARGV[1]/";
132 if($_->{artist} =~ /^([a-z])/i) {
133 $newname .= lc($1);
134 } else {
135 $newname .= "a";
137 # $newname .= uc substr($_->{artist} || "_", 0, 1);
138 mkpath($newname);
139 $newname .= "/";
140 my @n;
141 push @n, mystring_to_filename($_->{artist}) if $_->{artist} ne "";
142 push @n, mystring_to_filename($_->{album}) if $_->{album} ne "";
143 push @n, sprintf("%02d", $_->{track}) if $_->{track};
144 push @n, mystring_to_filename($_->{title}) if $_->{title} ne "";
145 $newname .= join("-", @n);
146 $_->{filename} =~ /([^.]*)$/;
147 $newname .= "." . lc($1);
149 if(-e $newname) {
150 print "skipping $newname\n";
151 print LOG "skipping $newname\n";
152 } else {
153 $copy{$newname} = $_;
155 delete $deletefile{lc $newname};
158 printf "total %d songs, time %d:%02d:%02d, size %dkb, avg bitrate %dkb/s, transcode %dx\n",
159 $num, $totlen / 3600, ($totlen % 3600) / 60, $totlen % 60,
160 $totblocks * 4,
161 $totblocks * 4096 * 8e-3 / $totlen,
162 $trans;
164 exit if $ARGV[1] eq "";
166 foreach(keys %deletefile) {
167 print "deleting $_\n";
168 print LOG "deleting $_\n";
169 unlink $_ or do {
170 print "delete $_: $!\n";
171 print LOG "delete $_: $!\n";
175 my $copied;
176 my $tmpfile = "/tmp/soepkiptng_sync_playlist";
177 foreach my $newname (sort { $a cmp $b } keys %copy) {
178 my $origfile = $copy{$newname}->{filename};
179 if($copy{$newname}->{needtranscode}) {
180 unlink "$tmpfile.wav", "$tmpfile.mp3";
181 my $lameinput = "$tmpfile.wav";
182 $newname =~ /([^.]+)$/ or die;
183 if($1 eq "ogg") {
184 sysordie "oggdec", "-o", "$tmpfile.wav", $copy{$newname}->{filename};
185 } elsif($1 eq "flac") {
186 sysordie "flac", "-d", "-o", "$tmpfile.wav", $copy{$newname}->{filename};
187 } elsif($1 eq "mp3") {
188 $lameinput = $copy{$newname}->{filename};
189 } else {
190 die "no support for $1\n";
192 sysordie "lame", "-h", "--abr", $mp3bitrate,
193 "--tt", $copy{$newname}->{title},
194 "--ta", $copy{$newname}->{artist},
195 "--tl", $copy{$newname}->{album},
196 "--tn", $copy{$newname}->{track},
197 $lameinput, "$tmpfile.mp3";
198 $origfile = "$tmpfile.mp3";
200 sysordie "cp", $origfile, $newname;
201 $copied++;
203 print "$copied files copied\n";