From ec99cbe7b6f4ee175271d75d628479b2e3fd96fc Mon Sep 17 00:00:00 2001 From: "kilian (ksmachome)" Date: Thu, 26 Dec 2019 13:54:00 +0100 Subject: [PATCH] v20191226 --- bin/clr_playlistpack.pl | 34 ++ bin/clr_tmpsetplaylists.pl | 2 +- bin/lib/audio.pm | 752 +++++++++++++++++++++++++ bin/lib/sqlite.pm | 177 ++++++ bin/pack_station.pl | 21 + bin/playlist_creator/clr_mixandpack.pl | 39 -- bin/uploadplaylists.sh | 3 + 7 files changed, 988 insertions(+), 40 deletions(-) create mode 100644 bin/clr_playlistpack.pl create mode 100755 bin/lib/audio.pm create mode 100755 bin/lib/sqlite.pm create mode 100644 bin/pack_station.pl delete mode 100644 bin/playlist_creator/clr_mixandpack.pl create mode 100644 bin/uploadplaylists.sh diff --git a/bin/clr_playlistpack.pl b/bin/clr_playlistpack.pl new file mode 100644 index 0000000..8e22069 --- /dev/null +++ b/bin/clr_playlistpack.pl @@ -0,0 +1,34 @@ +#!/Users/kilian/perl5/perlbrew/perls/perl-5.24.1/bin/perl + +use strict; +use Getopt::Long; +use File::Basename; +use Getopt::Long; + +use Archive::Tar qw(COMPRESS_GZIP ); +my $playlistpath = ""; +my $ploutpath = ""; +my $sname = ""; +GetOptions("filespath|fp=s" => \$playlistpath, + "outpath|o=s" => \$ploutpath, + "station|s=s" => \$sname + ); +chdir($ploutpath); +my $tar = Archive::Tar->new; +my @files = (); +chdir($playlistpath); +opendir(PLDIR,$playlistpath); +while (my $m3u = readdir(PLDIR)){ + #print $m3u."\n"; + if ($m3u =~ /\.m3u$/){ + push(@files,$m3u); + } +} +closedir(PLDIR); +#print Dumper(@files); +$tar->add_files(@files); +foreach my $x (@files){ + $tar->rename($x,'radio/playlists/'.$x); +} +$tar->write( $ploutpath.'/'.$sname.'.tgz', COMPRESS_GZIP ); +print $ploutpath.'/'.$sname.'.tgz created!'."\n"; \ No newline at end of file diff --git a/bin/clr_tmpsetplaylists.pl b/bin/clr_tmpsetplaylists.pl index b74ea98..0327655 100644 --- a/bin/clr_tmpsetplaylists.pl +++ b/bin/clr_tmpsetplaylists.pl @@ -20,7 +20,7 @@ while (my $m3u = readdir(INP)){ $newfile =~ s/$inyear/$outyear/; open(OUT,">".$outpath.'/'.$newfile); @files = reverse(@files); - print OUT join("\n",@files); + print OUT join("",@files); close(OUT); } } diff --git a/bin/lib/audio.pm b/bin/lib/audio.pm new file mode 100755 index 0000000..81078bf --- /dev/null +++ b/bin/lib/audio.pm @@ -0,0 +1,752 @@ +package audio; + +use strict; +use File::Basename; +use File::Path qw(make_path); +use Ogg::Vorbis::Header::PurePerl; +use MP3::Info; +use MP4::Info; +use Audio::FLAC::Header; +use Text::Unidecode; +if ($^O eq "MSWin32") { + use Win32; + Win32::SetChildShowWindow(0); +} + + +sub new { + my $class = shift; + my $param = shift; + my $self = bless {}, $class; + #if ($^O eq "MSWin32") { + $self->{binpath} = dirname($0); + #} + +# foreach my $p (keys %{$param}){ +# $self->{$p} = $param->{$p}; +# } + return $self; +} + +sub checkaudiofile($){ + my $self = shift; + my $i = shift; + my $o = dirname($i); + my $wav = $self->createwavefile($i,$o); + if ($wav ne "") { + $wav = $self->checkgain($wav); + } + # unlink($wav); +} + +sub convert($$$$$$$$$){ + my ($i,$o,$f,$id3,$t,$g,$b,$r,$s); + my $self = shift; + $i = shift; #i=input file + $o = shift; #o=output path + $f = shift; #f=output filename + $id3 = shift; #id3={"title":"","artist":"","genre":"","comment":"","album":"","track":""} + $t = shift; #t=outputtype (ogg,mp3,m4a,acc,flac) + $g = shift; #g=gain (-12.0 - 12.0) + $b = shift; #b=bitrate + $r = shift; #r=samplarate + $s = shift; #s=cut silence 0|1 + my $outfile = ""; + my $bitratetouse = undef; + if ( -f $i ) { + my ($info,$tagdata) = $self->getaudiotags($i); + #get audio info current file + if ($o eq ""){ + $o = dirname($i); + } + if (! -d ($o)){ + make_path($o); + } + # if ($t ne ""){ + # $t = lc($t); + # } else { + # $t = lc(substr($f,length($f) - rindex($f,'.'))); + # } + # if ($t !~ /^\.[mp3|ogg|aac|flac|m4a]/){ + # $t = ""; + # } + + + if ($b eq ""){ + #orig file bitrate + } + + if ($r eq ""){ + #orig file samplerate + } + if ($^O eq "MSWin32") { + $i =~ s/\/+/\\/g; + $o =~ s/\/+/\\/g; + } + #print "$infile => $outpath\n"; + my $wav = $self->createwavefile($i,$o); + if ($wav ne "") { + if ($s == 1) { + #print "cut silence\n"; + $wav = $self->cutsilences($wav); + } + } + if ($wav ne "") { + if ($g ne "") { + #print "set gain\n"; + $wav = $self->setgain($wav,$g); + } + } + if ($wav ne "") { + + $bitratetouse = $info->{bitrate}; + if (defined($b)){ + $bitratetouse = $b; + } + } + #print "Quality: $qualitytouse\n Bitrate: $bitratetouse\n"; + my $sampleratetouse=$info->{samplerate}; + if (defined($r)) { + $sampleratetouse=$r; + } + if ($id3 ne "") { + my @spl = split(/,/,$id3); + my $ntagdata = (); + foreach my $t (@spl){ + $ntagdata->{$t} = $tagdata->{$t}; + } + $tagdata = $ntagdata; + } + print "Start convert:".$wav."\n"; + print "Type: $t\n"; + if ($t eq "ogg") { + $outfile = $self->createoggfile($wav,$tagdata,$sampleratetouse,$bitratetouse); + }elsif ($t eq "mp3"){ + $outfile = $self->createmp3file($wav,$tagdata,$sampleratetouse,$bitratetouse); + }elsif ($t eq "flac"){ + $outfile = $self->createflacfile($wav,$tagdata,$sampleratetouse); + }elsif ($t eq "aac"){ + $outfile = $self->createaacfile($wav,$tagdata,$sampleratetouse,$bitratetouse); + }elsif ($t eq "m4a"){ + $outfile = $self->createm4afile($wav,$tagdata); + }elsif ($t eq "opus"){ + $outfile = $self->createopusfile($wav,$tagdata,$sampleratetouse,$bitratetouse); + } + } + return $outfile; +} + + +sub createwavefile(){ + my $self = shift; + my $in = shift; + my $outpath = shift; + my $fname = basename($in); + $fname = substr($fname,0,rindex($fname,'.')).'.wav'; + print "Create WAV: from:".$in." to: ".$outpath."\n\n\n"; + if (! -d $outpath){ + make_path($outpath); + } + if (($outpath !~ /\/$/) && ($outpath !~ /\\$/)){ + $outpath = $outpath."/"; + } + $in =~ s/\\\\/\\/g; + if (-e $outpath.$fname) { + unlink($outpath.$fname); + } + my $st = undef; + my $cmd = ""; + my $dec = ""; + if (lc($in) =~ /\.ogg$/) { + $dec = $self->{binpath}.'/oggdec'; + } elsif (lc($in) =~ /\.mp3$/){ + $dec = $self->{binpath}.'/lame'; + } elsif ((lc($in) =~ /\.m4a/) || (lc($fname) =~ /\.aac/)) { + $dec = $self->{binpath}.'/faad'; + } elsif (lc($in) =~ /\.flac/){ + $dec = $self->{binpath}.'/flac'; + } elsif (lc($in) =~ /\.opus/){ + $dec = $self->{binpath}.'/opusdec'; + } else { + $dec = $self->{binpath}.'/ffmpeg'; + } + if ($^O eq "MSWin32"){ + $dec = $dec.".exe"; + $dec =~ s/\/+/\\/g; + } + $dec = '"'.$dec.'"'; + if (lc($in) =~ /\.ogg$/) { + $cmd = $dec.' -w "'.$outpath.$fname.'" "'.$in.'"'; + }elsif (lc($in) =~ /\.mp3$/){ + $cmd = $dec.' --silent --decode "'.$in.'" "'.$outpath.$fname.'"'; + }elsif ((lc($in) =~ /\.m4a/) || (lc($fname) =~ /\.aac/)){ + $cmd = $dec.' -o "'.$outpath.$fname.'" "'.$in.'"'; + }elsif (lc($in) =~ /\.flac/){ + $cmd = $dec.' -d -o "'.$outpath.$fname.'" -F "'.$in.'"'; + } elsif (lc($in) =~ /\.opus/){ + $cmd = $dec.' "'.$in.'" "'.$outpath.$fname.'"'; + } else { + $cmd = $dec.' -i "'.$in.'" "'.$outpath.$fname.'"'; + } + + print "$cmd\n"; + if ($cmd ne "") { +# if ($^O eq "MSWin32"){ +# Win32::SetChildShowWindow(0); +# } + $st = system($cmd); + if ($st > 0){ + return ""; + } + } + my $ret = $outpath.'/'.$fname; + if ($^O eq "MSWin32") { + $ret =~ s/\/+/\\/g; + } + return $ret; +} + +sub cutsilences(){ + my $self = shift; + my $wav = shift; + my $nwav = substr($wav,0,-4); + my $sox = $self->{binpath}.'/sox'; + if ($^O eq "MSWin32"){ + $sox = $sox.".exe"; + $sox =~ s/\/+/\\/g; + } + print "Cut silences\n"; + $sox = '"'.$sox.'"'; + ##Win32::SetChildShowWindow(0); + system($sox.' "'.$wav.'" "'.$nwav.'.sox0.wav" silence 1 0 -40d'); + #### Reverse file to trim the end + #Win32::SetChildShowWindow(0); + system($sox.' "'.$nwav.'.sox0.wav" "'.$nwav.'.sox1.wav" reverse' ); + #### Trim the end + #Win32::SetChildShowWindow(0); + system($sox.' "'.$nwav.'.sox1.wav" "'.$nwav.'.sox0.wav" silence 1 0 -40d' ); + #### Reverse back to original direction + #Win32::SetChildShowWindow(0); + system($sox.' "'.$nwav.'.sox0.wav" "'.$wav.'" reverse'); + unlink($nwav.'.sox0.wav'); + unlink($nwav.'.sox1.wav'); + return $wav; +} + +sub getaudiotags(){ + my $self = shift; + my $audiofile = shift; + #my $l = shift; + my $tmp = rindex($audiofile,'.'); + my $sfx = lc(substr($audiofile,rindex($audiofile,'.')+1)); + my $tagdata = (); + my $info = (); + my $ftype=""; + #print $audiofile."\n"; + if (lc($sfx) eq 'ogg'){ + #print "get ogginfo from ".$oggin."
"; + $ftype="audio/ogg"; + my $oggx = Ogg::Vorbis::Header::PurePerl->new($audiofile); + if (defined($oggx)) { + #if ($l == 1){ + my $inf = $oggx->info(); + for my $i (keys (%{$inf})){ + if ($i eq 'rate') { + $info->{samplerate} = int($inf->{$i}); + } + if ($i eq 'length') { + $info->{duration} = int($inf->{$i}); + } + if ($i eq 'bitrate_average') { + $info->{bitrate} = int($inf->{$i} / 1000); + } + } + # my $cmd = '/usr/local/bin/ogginfo -v "'.$oggin.'" | grep "Playback length:" | awk \'{ print $3 }\''; + # my $ores = `$cmd`; + # chomp($ores); + # my ($min,$sec) = $ores =~ m/(\d+)m:(\d\d)\.\d\d\ds$/; + # + # #my $ha = $oggx->info; + # $length = $min * 60 + $sec; + #} + foreach my $com ($oggx->comment_tags) { + foreach my $cc ($oggx->comment($com)){ + if (lc($com) eq 'title') { + $tagdata->{'title'} = $cc; + } + if (lc($com) eq 'album') { $tagdata->{'album'} = $cc;} + if (lc($com) eq 'artist') { + $tagdata->{'artist'} = $cc; + } + if (lc($com) eq 'year') { $tagdata->{'year'} = $cc;} + if (lc($com) eq 'genre'){ $tagdata->{'genre'} = $cc;} + if (lc($com) eq "date") { $tagdata->{'year'} = substr($cc,0,4); } + } + } + + }else { + + #print "$audiofile not a valid ogg-file!"; + return ($info,$tagdata); + #next; + } + }elsif (lc($sfx) eq 'mp3'){ + $ftype="audio/mpeg"; + my $tag = MP3::Info::get_mp3tag($audiofile); + if (defined($tag)) { + foreach my $t (keys(%{$tag})){ + if ((lc($t) eq 'title') || + (lc($t) eq 'album') || + (lc($t) eq 'artist') || + (lc($t) eq 'year') || + (lc($t) eq 'genre') + ){ + $tagdata->{lc($t)} = $tag->{$t}; + } + } + #$title = $tag->{TITLE}; + #$artist = $tag->{ARTIST}; + }else{ + #print "$audiofile not a valid mp3-file!"; + return ($info,$tagdata);; + } + #if ($l == 1) { + my $inf = MP3::Info::get_mp3info($audiofile); + if (defined($inf)) { + for my $i (keys(%{$inf})){ + #print lc($i)."\n"; + if (lc($i) eq 'bitrate') { + $info->{bitrate} = int($inf->{$i}); + } + if (lc($i) eq 'frequency') { + $info->{samplerate} = int($inf->{$i} * 1000); + } + if (lc($i) eq 'secs') { + $info->{duration} = int($inf->{$i}) + } + } + #$info = $inf; + } + else{ + #print "$audiofile not a valid mp3-file!"; + return ($info,$tagdata); + } + #} + + }elsif (lc($sfx) eq 'm4a'){ + $ftype="audio/mp4"; + my $tag = MP4::Info::get_mp4tag($audiofile); + if (defined($tag)) { + foreach my $t (keys(%{$tag})){ + if (lc($t) eq 'alb') { $tagdata->{album} = $tag->{$t}; } + if (lc($t) eq 'nam') { $tagdata->{title} = $tag->{$t}; } + if (lc($t) eq 'art') { $tagdata->{artist} = $tag->{$t}; } + if (lc($t) eq 'day') { $tagdata->{year} = $tag->{$t}; } + if (lc($t) eq 'gnre') { $tagdata->{genre} = $tag->{$t}; } + } + }else{ + #print "$audiofile not a valid m4a-file!"; + return ($info,$tagdata); + } + my $inf = MP4::Info::get_mp4info($audiofile); + if (defined($inf)) { + $info->{bitrate} = $inf->{BITRATE}; + $info->{samplerate} = int($inf->{FREQUENCY} * 1000); + $info->{duration} = $inf->{SECS}; + } + else{ + #print "$audiofile not a valid m4a-file!"; + return ($info,$tagdata);; + } + }elsif (lc($sfx) eq 'flac'){ + $ftype="audio/flac"; + my $flac = Audio::FLAC::Header->new($audiofile); + my $tag = $flac->tags(); + if (defined($tag)) { + foreach my $t (keys(%{$tag})){ + if ((lc($t) eq 'title') || + (lc($t) eq 'album') || + (lc($t) eq 'artist') || + (lc($t) eq 'genre') + ){ + $tagdata->{lc($t)} = $tag->{$t}; + } + if (lc($t) eq 'date') { + $tagdata->{year} = substr($tag->{$t},0,4); + } + + } + }else{ + #print "$audiofile not a valid flac-file!"; + return ($info,$tagdata); + } + #if ($l == 1) { + my $inf = $flac->info(); + if (defined($inf)){ + $info->{duration} = int($flac->{trackTotalLengthSeconds}); + $info->{bitrate} = int($flac->{bitRate}); + $info->{samplerate} = int($inf->{SAMPLERATE}); + #$info = $inf; + } + else{ + #print "$audiofile not a valid flac-file!"; + return ($info,$tagdata);; + } + #} + } + #$title =~ s/`//g; + #$artist =~ s/`//g; + #if ($l == 1){ + # return ($artist,$title,$info); + #} + $info->{filetype} = $ftype; + return ($info,$tagdata); + +} + +sub setgain(){ + my $self = shift; + my $wavfile = shift; + my $gain = shift; + my $cwd = dirname($wavfile); + my $wavegain = $self->{binpath}.'/wavegain'; + if ($^O eq "MSWin32"){ + $wavegain = $wavegain.".exe"; + $wavegain =~ s/\/+/\\/g; + } + $wavegain = '"'.$wavegain.'"'; + print "Set Gain: ".$gain."\n"; + #if ($^O eq "MSWin32") + my $cmd = $wavegain.' -g '.$gain.'.0 -a -y "'.$wavfile.'" -l -f "'.$ENV{TMP}.'/wavegain.log"'; + #Win32::SetChildShowWindow(0); + my $st = system($cmd); + print $st."\n"; + #open(NORM,"$cmd 2>&1 |") or die "cannot execute $cmd"; + #while (my $l =){ + # $l =~ s/\r//g; + # $l =~ s/\n//g; + # #print $l; + ## print ""; + #} + #close(NORM); + return $wavfile; +} + +sub checkgain(){ + my $self = shift; + my $wavfile = shift; + #my $gain = shift; + #my $cwd = dirname($wavfile); + if (-e $ENV{TMP}."/tmp/wavegain.log") { + unlink($ENV{TMP}."/tmp/wavegain.log"); + } + my $wavegain = $self->{binpath}.'/wavegain'; + if ($^O eq "MSWin32"){ + $wavegain = $wavegain.".exe"; + $wavegain =~ s/\/+/\\/g; + } + #print "Set Gain: "; + my $cmd = $wavegain.' -c "'.$wavfile.'" -l -f "'.$ENV{TMP}.'/wavegain.log"'; + #Win32::SetChildShowWindow(0); + system($cmd); + my $res = ""; + open(WGLOG,$ENV{TMP}.'/tmp/wavegain.log'); + while (my $l = ){ + #$res .= $l; + if ($l =~ /\d+\.\d+\sdB/) { + my @d = split(/\|/,$l); + $res = $d[0]; + $res =~ s/^\s+//; + $res =~ s/\s+$//; + } + } + close(WGLOG); + + return $res; +} + +sub createoggfile(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my $samplerate = shift; + my $bitrate = shift; + my $oggenc = $self->{binpath}.'/oggenc2'; + if ($^O eq "MSWin32"){ + $oggenc = $oggenc.".exe"; + $oggenc =~ s/\/+/\\/g; + } + $oggenc = '"'.$oggenc.'"'; +my $q = ""; + print "Crate OGG file from: $wavin\n"; + if ($bitrate ne ""){ + $q = "-b ".$bitrate; + } + my @tagdata = ""; + if (exists($tags->{title})) { + push @tagdata ,'-t "'.$tags->{title}.'"'; + } + if (exists($tags->{artist})){ + push @tagdata ,'-a "'.$tags->{artist}.'"'; + } + if (exists($tags->{album})){ + push @tagdata ,'-l "'.$tags->{album}.'"'; + } + if (exists($tags->{genre})){ + push @tagdata ,'-G "'.$tags->{genre}.'"'; + } + if (exists($tags->{year})){ + push @tagdata ,'-d "'.$tags->{year}.'"'; + } + my $oggout = substr($wavin,0,-3).'ogg'; + if (-e $oggout) { + unlink($oggout); + } + + #print '/usr/local/bin/oggenc -b '.$bitrate.' -o "'.$oggout.'" -t "'.$t.'" -a "'.$a.'" "'.$wavin.'"'; + #Win32::SetChildShowWindow(0); + print "CMD:".$oggenc.' -Q '.$q.' --resample '.$samplerate.' -o "'.$oggout.'" '.join(' ',@tagdata).' "'.$wavin.'"'."\n"; + my $st = system($oggenc.' -Q '.$q.' --resample '.$samplerate.' -o "'.$oggout.'" '.join(' ',@tagdata).' "'.$wavin.'"'); + + if ($st > 0){ + print "cannot create $oggout"; + return ""; + } + unlink($wavin); + return $oggout; +} + +sub createopusfile(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my $samplerate = shift; + my $bitrate = shift; + #my $quality = shift; + my $q = ""; + my $opusenc = $self->{binpath}.'/opusenc'; + if ($^O eq "MSWin32"){ + $opusenc = $opusenc.".exe"; + $opusenc =~ s/\/+/\\/g; + } + $opusenc = '"'.$opusenc.'"'; + #print "Crate OGG file from: $wavin\n"; + if ($bitrate ne ""){ + $q = "--bitrate ".$bitrate; + } + my @tagdata = ""; + if (exists($tags->{title})) { + push @tagdata ,'--title "'.$tags->{title}.'"'; + } + if (exists($tags->{artist})){ + push @tagdata ,'--artist "'.$tags->{artist}.'"'; + } + if (exists($tags->{album})){ + push @tagdata ,'--album "'.$tags->{album}.'"'; + } + if (exists($tags->{genre})){ + push @tagdata ,'--genre "'.$tags->{genre}.'"'; + } + if (exists($tags->{year})){ + push @tagdata ,'--date "'.$tags->{year}.'"'; + } + my $oggout = substr($wavin,0,-3).'opus'; + if (-e $oggout) { + unlink($oggout); + } + + #print '/usr/local/bin/oggenc -b '.$bitrate.' -o "'.$oggout.'" -t "'.$t.'" -a "'.$a.'" "'.$wavin.'"'; + #Win32::SetChildShowWindow(0); + #print '"'.$self->{binpath}.'opusenc" --quiet '.$q.' --raw-rate '.$samplerate.' '.join(' ',@tagdata).' "'.$wavin.'" "'.$oggout.'"'."\n"; + my $st = system($opusenc.' --quiet '.$q.' --raw-rate '.$samplerate.' '.join(' ',@tagdata).' "'.$wavin.'" "'.$oggout.'"'); + + if ($st > 0){ + #print "cannot create $oggout"; + return ""; + } + unlink($wavin); + return $oggout; +} + +sub createmp3file(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my $samplerate = shift; + my $bitrate = shift; + my $q = ""; + my $mp3enc = $self->{binpath}.'/lame'; + if ($^O eq "MSWin32"){ + $mp3enc = $mp3enc.".exe"; + $mp3enc =~ s/\/+/\\/g; + } + $mp3enc = '"'.$mp3enc.'"'; + #print "Crate MP3 file from: $wavin\n"; +# if ($quality ne "") { +# $q = "-V ".$quality." -Y "; +# }els + if ($bitrate ne ""){ + $q = "-b ".$bitrate; + } + my @tagdata = ""; + if (exists($tags->{title})) { + push @tagdata ,'--tt "'.$tags->{title}.'"'; + } + if (exists($tags->{artist})){ + push @tagdata ,'--ta "'.$tags->{artist}.'"'; + } + if (exists($tags->{album})){ + push @tagdata ,'--tl "'.$tags->{album}.'"'; + } + if (exists($tags->{genre})){ + push @tagdata ,'--tg '.$tags->{genre}.'"'; + } + if (exists($tags->{year})){ + push @tagdata ,'--ty "'.$tags->{year}.'"'; + } + my $mp3out = substr($wavin,0,-3).'mp3'; + $mp3out =~ s/\\+/\\/g; + $mp3out =~ s/\/+/\\/g; + #print '/usr/local/bin/oggenc -b '.$bitrate.' -o "'.$oggout.'" -t "'.$t.'" -a "'.$a.'" "'.$wavin.'"'; + #print '"'.$self->{binpath}.'lame.exe" '.$q.' -h -Y --add-id3v2 --id3v2-only -t -s '.$samplerate.' -tt "'.$t.'" -ta "'.$a.'" "'.$wavin.'" "'.$mp3out.'"'."\n"; + my $cmd = $mp3enc.' '.$q.' -h --quiet --add-id3v2 --id3v2-only -t -s '.$samplerate.' '.join(' ',@tagdata).' "'.$wavin.'" "'.$mp3out.'"'; + #print $cmd."\n"; + #Win32::SetChildShowWindow(0); + my $st = system($cmd); + + if ($st > 0){ + #print "cannot create $mp3out"; + return ""; + } + unlink($wavin); + return $mp3out; +} + +sub createflacfile(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my $samplerate = shift; + #print "Crate FLAC file from: $wavin\n"; + my @tagdata = ""; + my $flacenc = $self->{binpath}.'/flac'; + if ($^O eq "MSWin32"){ + $flacenc = $flacenc.".exe"; + $flacenc =~ s/\/+/\\/g; + } + $flacenc = '"'.$flacenc.'"'; + + if (exists($tags->{title})) { + push @tagdata ,'-T TITLE="'.$tags->{title}.'"'; + } + if (exists($tags->{artist})){ + push @tagdata ,'-T ARTIST="'.$tags->{artist}.'"'; + } + if (exists($tags->{album})){ + push @tagdata ,'-T ALBUM="'.$tags->{album}.'"'; + } + if (exists($tags->{genre})){ + push @tagdata ,'-T GENRE="'.$tags->{genre}.'"'; + } + if (exists($tags->{year})){ + push @tagdata ,'-T YEAR="'.$tags->{year}.'"'; + } + my $flacout = substr($wavin,0,-3).'flac'; + if (-e $flacout) { + unlink($flacout); + } + my $cmd = $flacenc.'" -s -o "'.$flacout.'" '.join(' ',@tagdata).' "'.$wavin.'"'; + #print $cmd."\n"; + #Win32::SetChildShowWindow(0); + my $st = system($cmd); + if ($st > 0){ + #print "cannot create $flacout"; + return ""; + } + unlink($wavin); + return $flacout; +} + +sub createaacfile(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my $samplerate = shift; + my $bitrate = shift; + # my $quality= shift; + my $q = ""; + my $aacenc = $self->{binpath}.'/faac'; + if ($^O eq "MSWin32"){ + $aacenc = $aacenc.".exe"; + $aacenc =~ s/\/+/\\/g; + } + $aacenc = '"'.$aacenc.'"'; + #print "Crate AAC file from: $wavin\n"; +# if ($quality ne "") { +# $q = "-q ".$quality; +# }els + if ($bitrate ne ""){ + $q = "-b ".$bitrate; + } + my $aacout = substr($wavin,0,-3).'aac'; + if (-e $aacout) { + unlink($aacout); + } + my $cmd = $aacenc.' '.$q.' -c '.$samplerate.' -o "'.$aacout.'" "'.$wavin.'"'; + #print $cmd."\n"; + #Win32::SetChildShowWindow(0); + my $st = system($cmd); + if ($st > 0){ + #print "cannot create $aacout"; + return ""; + } + unlink($wavin); + return $aacout; +} + +sub createm4afile(){ + my $self = shift; + my $wavin = shift; + my $tags = shift; + my @tagdata = ""; + my $aacenc = $self->{binpath}.'/faac'; + if ($^O eq "MSWin32"){ + $aacenc = $aacenc.".exe"; + $aacenc =~ s/\/+/\\/g; + } + $aacenc = '"'.$aacenc.'"'; + #print "Create M4A file from: $wavin\n"; + if (exists($tags->{title})) { + push @tagdata ,'--title "'.$tags->{title}.'"'; + } + if (exists($tags->{artist})){ + push @tagdata ,'--artist "'.$tags->{artist}.'"'; + } + if (exists($tags->{album})){ + push @tagdata ,'--album "'.$tags->{album}.'"'; + } + if (exists($tags->{genre})){ + push @tagdata ,'--genre "'.$tags->{genre}.'"'; + } + if (exists($tags->{year})){ + push @tagdata ,'--year "'.$tags->{year}.'"'; + } + my $aacout = substr($wavin,0,-3).'m4a'; + if (-e $aacout) { + unlink($aacout); + } + + my $cmd = $aacenc.' -q 100 '.join(' ',@tagdata).' -o "'.$aacout.'" "'.$wavin.'"'; + #print $cmd."\n"; + #Win32::SetChildShowWindow(0); + my $st = system($cmd); + if ($st > 0){ + #print "M4A: cannot create $aacout"; + return ""; + } + unlink($wavin); + return $aacout; +} + + +1; diff --git a/bin/lib/sqlite.pm b/bin/lib/sqlite.pm new file mode 100755 index 0000000..b771501 --- /dev/null +++ b/bin/lib/sqlite.pm @@ -0,0 +1,177 @@ +package sqlite; +use strict; +use DBI; +use DBD::SQLite; +use Encode; +use File::Basename; + +sub new { + my $class = shift; + my $p = shift; + my $self = bless {}, $class; + $self->{dbfile} =$p; + return $self; +} + +sub strreplace(){ + my $self = shift; + my $text = shift; + $text =~ s/'/''/g; + return $text; +} + +sub dbquery(){ + my $self = shift; + my $key = shift; + my $stat = shift; + my $retdata =(); + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,RaiseError=>1,AutoCommit=>1}) or print "dbquery Connection Error!".$!."\n"; + $stat = encode("utf8", $stat); + + #open FILE,">>/tmp/sql.log"; + # print FILE "key:".$key.";$stat\n"; + # close FILE; + my $sth = $dbh->prepare($stat) ; + $sth->execute() or print "dbquery: ".$sth->errstr."\n"; + while(my $data = $sth->fetchrow_hashref()) + { + if (exists $data->{$key}){ + foreach my $k (keys %{$data}){ + $retdata->{$data->{$key}}{$k} = $data->{$k}; + } + } + } + if (keys(%{$retdata}) == 0){ + $retdata =(); + } + $sth->finish(); + $dbh->disconnect(); + return $retdata; +} + +sub dbquerysorted(){ + my $self = shift; + my $stat = shift; + my $retdata = (); + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,RaiseError=>1,AutoCommit=>1}) or print "dbquery Connection Error!".$!."\n"; + $stat = encode("utf8", $stat); + #open FILE,">>/tmp/sql.log"; + #print "Query Sorted: $stat\n"; + # close FILE; + my $sth = $dbh->prepare($stat) or print "Failed prepare: ".$stat."\n"; + + $sth->execute() or print "dbquery: ".$sth->errstr."\n"; + my $count = 0; + while(my $data = $sth->fetchrow_hashref()) + { + foreach my $k (keys %{$data}){ + $retdata->{$count}->{$k} = $data->{$k}; + } + $count++; + } + + $sth->finish(); + $dbh->disconnect(); + #%retdata = sort {$a <=> $b} keys %retdata; + return $retdata; +} + +sub dbqueryarray(){ + my $self = shift; + my $stat = shift; + my @retdata = (); + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,RaiseError=>1,AutoCommit=>1}) or print "dbquery Connection Error!".$!."\n"; + $stat = encode("utf8", $stat); + open FILE,">>sqlarray.log"; + print FILE "$stat\n"; + close FILE; + my $sth = $dbh->prepare($stat) or print "Failed prepare: ".$stat."\n"; + + $sth->execute() or die "dbquery: ".$sth->errstr; + my $count = 0; + while(my $data = $sth->fetchrow_hashref()) + { + my $ret = {}; + foreach my $k (keys %{$data}){ + $ret->{$k} = $data->{$k}; + } + push @retdata,$ret; + } + + $sth->finish(); + $dbh->disconnect(); + #%retdata = sort {$a <=> $b} keys %retdata; + return @retdata; +} + +sub dbexec(){ + my $self = shift; + my $stat = shift; + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,AutoCommit=>1}) or print "dbexec Connection Error!".$!."\n"; + $stat = encode("utf8", $stat); + #print $stat."\n"; + #open FILE,">>/Users/kilian/sql.log"; + #print "$stat\n"; + #close FILE; + my $sth = $dbh->prepare($stat); + my $rv =$dbh->do($stat) or print "dbexec '".$stat. "\n".$dbh->errstr()." failed!\n"; + $dbh->disconnect(); + return $rv; +} + + +sub dbbackup(){ + my $self = shift; + my $path = shift; + my $type = shift; + + my @dx = localtime(); + $dx[5] = $dx[5] +1900; + $dx[4] = $dx[4] +1; + if ($dx[4] < 10){$dx[4] = '0'.$dx[4];} + if ($dx[3] < 10){$dx[3] = '0'.$dx[3];} + if ($dx[2] < 10){$dx[2] = '0'.$dx[2];} + if ($dx[1] < 10){$dx[1] = '0'.$dx[1];} + if ($dx[0] < 10){$dx[0] = '0'.$dx[0];} + my $xdd = $dx[5].$dx[4].$dx[3].'_'.$dx[2].$dx[1].$dx[0]; + my $bfile = ""; + if ($type eq "binary" ) { + $bfile = $path.'/'.basename($self->{dbfile}).'_'.$xdd.'.db'; + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,RaiseError=>1,AutoCommit=>1}) or print "dbexec Connection Error!".$!."\n"; + $dbh->sqlite_backup_to_file($bfile); + $dbh->disconnect(); + }elsif($type eq "sql"){ + $bfile = $path.'/'.basename($self->{dbfile}).'_'.$xdd.'.sql'; + my $st = system('sqlite3 "'.$self->{dbfile}.'" ".dump" > '.$bfile); + } + return $bfile; +} + +sub dbrestore(){ + my $self = shift; + my $file = shift; + my $type = shift; + if ($type eq "binary" ) { + my $dbh = DBI->connect('DBI:SQLite:dbname='.$self->{dbfile},"","",{PrintError=>1,RaiseError=>1,AutoCommit=>1}) or print "dbexec Connection Error!".$!."\n"; + $dbh->sqlite_backup_from_file($file); + $dbh->disconnect(); + }elsif($type eq "sql"){ + open(REST,$file) or die "cannot open restore file $file!\n"; + my $rsql = ""; + while (my $l = ) { + $rsql .= $l; + } + close(REST); + unlink($self->{dbfile}); + $self->dbexec($rsql); + } +} + +sub dbrepair(){ + my $self = shift; + my $bfile = $self->dbbackup($ENV{'TMPDIR'},'sql'); + $self->dbrestore($bfile,'sql'); + unlink($bfile); +} + +1; diff --git a/bin/pack_station.pl b/bin/pack_station.pl new file mode 100644 index 0000000..ef3dba0 --- /dev/null +++ b/bin/pack_station.pl @@ -0,0 +1,21 @@ +#!/usr/local/bin/perl + +use strict; +use File::Basename; +use FindBin qw($RealBin); +use Getopt::Long; +use lib ($RealBin.'/lib'); +use sqlite; +my $filepath = ""; +GetOptions("fp|p=s"=> \$filepath); +my $dbfile = dirname($RealBin).'/data/coloradio/newstation.sqlite'; +print "DB:".$dbfile."\n"; +my $db = sqlite->new($dbfile); +my $st = $db->dbquerysorted("select hostname,syncserver from stations;"); +my $datapath = dirname($RealBin).'/data/coloradio'; +foreach my $s (keys(%{$st})){ + print "Pack Station ".$st->{$s}->{hostname}."\n"; + my $cmd = '/usr/local/bin/perl "'.$RealBin.'/clr_playlistpack.pl" -fp "'.$datapath.'/'.$filepath.'" -o "'.$datapath.'/server/'.$st->{$s}->{syncserver}.'/update/playlists" -s '.$st->{$s}->{hostname}.''; + print $cmd."\n"; + system($cmd); +} diff --git a/bin/playlist_creator/clr_mixandpack.pl b/bin/playlist_creator/clr_mixandpack.pl deleted file mode 100644 index 939813a..0000000 --- a/bin/playlist_creator/clr_mixandpack.pl +++ /dev/null @@ -1,39 +0,0 @@ -#!/Users/kilian/perl5/perlbrew/perls/perl-5.24.1/bin/perl - -use strict; -use Getopt::Long; -use File::Basename; -my $playlistpath = ""; -my $ploutpath = ""; -my -my $sname = $cfg->{playlists}->{Stream}; - my $snamepath = $sname; - $sname =~ s/\s/\_/g; - my $ploutpath = dirname($configfile).'/playlists'; - # my $dbname = dirname($configfile).'/'.$sname.'.sqlite'; - # $db = sqlite->new($dbname); - # &writelog("PACK","Using Database ".$dbname); - #my $scheds = $db->dbquerysorted("select schedulename from schedule;"); - #foreach my $s (keys(%{$scheds})){ - &writelog("PACK","Pack playlist schedule ".$sname.""); - chdir($ploutpath.'/'.$snamepath); - my $tar = Archive::Tar->new; - my @files = (); - opendir(PLDIR,$ploutpath.'/'.$snamepath); - - while (my $m3u = readdir(PLDIR)){ - print $m3u."\n"; - if ($m3u =~ /\.m3u$/){ - push(@files,$m3u); - } - } - print Dumper(@files); - closedir(PLDIR); - $tar->add_files(@files); - foreach my $x (@files){ - $tar->rename($x,'radio/playlists/'.$x); - } - my @time = gmtime(); - my $date = strftime("%Y%m%d",@time); - $tar->write( $ploutpath.'/'.$sname.'_'.$date.'.tgz', COMPRESS_GZIP ); - print $ploutpath.'/'.$sname.'_'.$date.'.tgz created!'."\n"; \ No newline at end of file diff --git a/bin/uploadplaylists.sh b/bin/uploadplaylists.sh new file mode 100644 index 0000000..f2d5850 --- /dev/null +++ b/bin/uploadplaylists.sh @@ -0,0 +1,3 @@ +#!/usr/bin/bash + +/Users/kilian/Workspace/dksnas/data/coloradio/aral/playlists/default/2020 \ No newline at end of file -- 2.39.5