v20191226
authorkilian (ksmachome) <ksaffran@dks.lu>
Thu, 26 Dec 2019 12:54:00 +0000 (13:54 +0100)
committerkilian (ksmachome) <ksaffran@dks.lu>
Thu, 26 Dec 2019 12:54:00 +0000 (13:54 +0100)
bin/clr_playlistpack.pl [new file with mode: 0644]
bin/clr_tmpsetplaylists.pl
bin/lib/audio.pm [new file with mode: 0755]
bin/lib/sqlite.pm [new file with mode: 0755]
bin/pack_station.pl [new file with mode: 0644]
bin/playlist_creator/clr_mixandpack.pl [deleted file]
bin/uploadplaylists.sh [new file with mode: 0644]

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