SHOUTcast StreamReader — File Browser

SHOUTcastStreamReaderv1.0 / SHOUTcastStreamReaderv1.0 / streamreader / streamreader.mrc

streamreader.mrc — 16.88 KB — Download this file

; SHOUTcast StreamReader v1.0 - by Bullco
;
; Special thanks to Mervolic, for being an IRC god
; ..and also for helping with testing and improving! ;)
;
; Contact: #Mervolic at quakenet, look for a guy called cullBo

alias streamreader {
  if ($dialog($d_name)) {
    dialog -v $d_name
  }
  else {
    if (!$hget(streams)) {
      hmake streams 10
      if ($exists($+(",$scriptdir,streams.dat,"))) {
        hload -b streams $+(",$scriptdir,streams.dat,")
      }
    }
    if (!$hget(streaming)) {
      hmake streaming 100
    }
    if (!$hget(streambuf)) {
      hmake streambuf 100
    }
    dialog -md $d_name $d_name
  }
}

alias -l streamreader_version {
  return 1.0
}

menu menubar {
  SHOUTcast StreamReader:streamreader
}

on *:sockread:stream*:{
  var %id = $sockname,%state = $hget(%id,state),%read
  if (%state == data) {
    var %file = $hget(%id,file),%meta = $hget(%id,icy-metaint)
    if (%meta) {
      noop $hget(streambuf,%id,&buf)
      hdel streambuf %id
      %read = $hget(%id,read)
      sockread %read &data
      if (($sock(@streamreader_proxy_client)) && (%streamreader.proxy == %id)) {
        if ($calc($sock(@streamreader_proxy_client).sq + $bvar(&data,0)) <= 16384) {
          sockwrite @streamreader_proxy_client &data
        }
      }
      if ($sockbr == %read) {
        hadd %id state meta
      }
      else {
        hadd %id read $calc(%read - $sockbr)
      }
      bcopy -c &buf $calc($bvar(&buf,0) + 1) &data 1 -1
      if (%file) {
        bwrite %file -1 -1 &buf
      }
      else {
        hadd -b streambuf %id &buf
      }
    }
    else {
      sockread 8192 &data
      bwrite %file -1 -1 &data
    }
  }
  elseif (%state == meta) {
    var %metalen = $hget(%id,metalen)
    if (!%metalen) {
      sockread 1 &byte
      var %metalen = $calc($bvar(&byte,1,1) * 16)
      if (%metalen == 0) {
        hadd %id state data
        hadd %id read $hget(%id,icy-metaint)
      }
      else {
        hadd %id metalen %metalen
      }
    }
    else {
      sockread %metalen &read
      %read = $+($hget(%id,metadata),$bvar(&read,1,$bvar(&read,0)).text)
      
      if (%metalen == $sockbr) {
        if (($gettok(%streamreader.options,1,44) == 1) && ($hget(%id,file) != $null) && ($calc($gettok(%streamreader.options,2,44) * 1000) > $file($hget(%id,file)).size)) {
          .remove $hget(%id,file)
        }
        var %p = $calc($regex(%read,/[\W_]/g) / $len(%read))
        if (%p > 0.75) {
          stream -r $hget(%id,name)
          showerror Bugged stream detected - stream closed
        }
        var %n = 1,%t = $numtok(%read,59),%param,%value,%c,%file
        while (%n <= %t) {
          %c = $gettok(%read,%n,59)
          %param = $gettok(%c,1,61)
          %value = $right($left($gettok(%c,2,61),-1),-1)
          hadd %id %param %value
          inc %n
        }
        var %dir $+($options().output,$filter($hget(%id,icy-name)),\),%file,%ext = $hget(%id,ext),%pre = $null
        if (!$exists($qt($options().output))) {
          mkdir $qt($options().output)
        }
        if (!$exists($qt(%dir))) {
          mkdir $qt(%dir)
        }
        
        %file = $+(%dir,$filter($hget(%id,StreamTitle)))
        if ($istok(mp3|aac|nsv,$right(%file,3),124)) {
          %file = $left(%file,-3)
        }
        
        if ($exists($qt($+(%file,%ext)))) {
          if ($options().duplicateaction == 2) {
            .remove $qt($+(%file,%ext))
          }
          else {
            var %n = 1
            while ($exists($qt($+(%file,%pre,%ext)))) {
              %pre = $+([,%n,])
              inc %n
            }
          }
        }
        %file = $+(%file,%pre,%ext)
        
        hadd %id file $qt(%file)
        
        d_refresh
        hadd %id read $hget(%id,icy-metaint)
        hadd %id metalen $null
        hadd %id state data
      }
      else {
        hadd %id metadata %read
        hadd %id metalen $calc(%metalen - $sockbr)
      }
    }
  }
  elseif (%state == header) {
    sockread %read
    if ($len(%read) == 0) {
      noop $savestream($hget(%id,name),$hget(%id,icy-name))
      var %content = $hget(%id,content-type),%ext
      if (%content == audio/aacp) {
        %ext = .aac
      }
      elseif (%content == audio/mpeg) {
        %ext = .mp3
      }
      elseif (%content == video/nsv) {
        %ext = .nsv
      }
      elseif (%content == audio/x-scpls) {
        hadd %id state pls
        return
      }
      else {
        %ext = .dat
      }
      hadd %id ext %ext
      if ($hget(%id,icy-metaint)) {
        hadd %id read $v1
      }
      else {
        var %f = $+($options().output,$filter($hget(%id,icy-name)),%ext)
        hadd %id file $qt(%f)
      }
      hadd %id state data
      hadd %id status streaming
      d_refresh
    }
    else {
      var %param = $gettok(%read,1,58),%value = $gettok(%read,2-,58)
      if ($istok(icy-name|icy-genre|icy-url|icy-metaint|icy-br|content-type,%param,124)) {
        hadd %id %param %value
      }
    }
  }
  elseif (%state == first) {
    sockread %read
    var %code = $gettok(%read,2,32),%info = $gettok(%read,3-,32)
    if (%code != 200) {
      showerror $iif(%info,Could not connect to stream: %info,Could not connect: Unexpected server response)
      stream -r $hget(%id,name)
    }
    else {
      hadd %id state header
    }
  }
  elseif (%state == pls) {
    sockread %read
    if (file1=* iswm %read) {
      stream -r $hget(%id,name)
      stream -a $gettok(%read,2,61) $hget(%id,name)
    }
  }
}

alias -l isstreaming {
  if ($hget(streaming,$1)) {
    return $v1
  }
  return $false
}

alias -l stream {
  if ($1 == -a) {
    var %id = stream_,%addr = $2,%port = 80,%path
    while ($hget(%id)) {
      %id = %id $+ $rand(a,z)
    }
    hmake %id 10
    
    if (http://* iswm %addr) {
      %addr = $right(%addr,-7)
    }
    %path = $+(/,$gettok(%addr,2-,47))
    %addr = $gettok(%addr,1,47)
    if ($gettok(%addr,2,58)) {
      %port = $v1
      %addr = $gettok(%addr,1,58)
    }
    hadd %id name $iif($3,$3,$2)
    hadd %id address %addr
    hadd %id port %port
    hadd %id path %path
    hadd %id state first
    hadd %id status trying
    hadd streaming $hget(%id,name) %id
    sockopen %id %addr %port
  }
  elseif ($1 == -r) {
    var %id = $hget(streaming,$2)
    hdel streaming $2
    if ($hget(%id)) {
    hfree %id
    }
    if ($sock(%id)) {
      sockclose %id
    }
    if (%streamreader.proxy == %id) {
      .sockclose @streamreader_proxy*
    }
    d_refresh
  }
}

alias -l savestream {
  if (!$2) {
    if (!$hget(streams,$1)) {
      hadd streams $1 $null
      hsave -b streams $+(",$scriptdir,streams.dat,")
    }
  }
  else {
    if ((!$hget(streams,$1)) || ($hget(streams,$1) != $2)) {
      hadd streams $1 $2
      hsave -b streams $+(",$scriptdir,streams.dat,")
    }
  }
}

alias -l remstream {
  hdel streams $$1
  hsave -b streams $+(",$scriptdir,streams.dat,")
}

alias -l getstream {
  if ($1 == 0) {
    return $hget(streams,0).item
  }
  else {
    var %i = $hget(streams,$1).item
    if ($prop == name) {
      return $hget(streams,%i)
    }
    return %i
  }
}

dialog streamreader {
  title SHOUTcast StreamReader v $+ $streamreader_version
  size -1 -1 400 375
  box "Streams",200,5 5 390 158
  list 210,20 30 360 100,vsbar
  button "Add New..",211,20 125 80 23
  button "Remove",212,105 125 80 23
  button "Start Streaming!",213,260 125 120 23
  button "Stop Streaming",214,260 125 120 23
  box "Stream Info",300,5 168 390 162
  text "Name:",301,20 196 50 20
  edit "",302,70 193 310 23,read autohs
  text "Genre:",303,20 229 50 20
  edit "",304,70 226 140 23,read autohs
  text "Bitrate:",305,230 229 50 20
  edit "",306,280 226 100 23,read autohs
  text "URL:",307,20 262 50 20
  edit "",308,70 259 205 23,read autohs
  button "Visit",309,280 259 100 23
  text "Track:",310,20 296 50 20
  edit "",311,70 292 205 23,read autohs
  button "Tune In",312,280 292 100 23
  button "Open Directory",401,10 342 123 23
  button "Options",402,138 342 123 23
  button "Close Window",403,266 342 124 23,ok
}

on *:dialog:streamreader:init:*:{
  d_refresh
  d_clearinfo
}

on *:dialog:streamreader:sclick:*:{
  if ($did == 211) {
    noop $dialog($dname $+ _add, $dname $+ _add,-4)
  }
  elseif ($did == 212) {
    if ($input(Are you sure you want to remove this stream?,uywd,StreamReader)) {
      var %n = $$did(210).sel
      if ($isstreaming($getstream(%n))) {
        stream -r $getstream(%n)
      }
      remstream $getstream(%n)
      d_refresh -d
    }
  }
  elseif ($did == 213) {
    var %n = $$did(210).sel
    stream -a $getstream(%n)
    d_refresh
  }
  elseif ($did == 214) {
    var %n = $$did(210).sel
    stream -r $getstream(%n)
    d_refresh
  }
  elseif ($did == 210) {
    d_refresh
  }
  elseif ($did == 309) {
    tryrun $$did(308)
  }
  elseif ($did == 312) {
    var %id = $$hget(streaming,$getstream($did(210).sel)),%f = $+(",$scriptdir,proxy.pls"),%port = $iif($gettok(%streamreader.options,3,44),$v1,57234)
    if ($exists(%f)) {
      .remove %f
    }
    write %f [playlist]
    write %f NumberOfEntries=1
    write %f $+(File1=http://,localhost,:,%port)
    write %f Title1=StreamReader Proxy Server
    write %f Length1=-1
    write %f Version=2
    set %streamreader.proxy %id
    .sockclose @streamreader_proxy*
    socklisten @streamreader_proxy_listener %port
    tryrun %f
  }
  elseif ($did == 401) {
    var %d = $qt($options().output)
    if (!$exists(%d)) {
      mkdir %d
    }
    tryrun %d
  }
  elseif ($did == 402) {
    noop $dialog(streamreader_options,streamreader_options,-4)
  }
}

alias -l d_refresh {
  if (!$dialog($d_name)) {
    return
  }
  var %sel = $iif($1 == -d,0,$did($d_name,210).sel),%n = 1,%t = $getstream(0)
  did -r $d_name 210
  d_clearinfo
  while (%n <= %t) {
    did -a $d_name 210 $iif($isstreaming($getstream(%n)),$iif($hget($isstreaming($getstream(%n)),status) != trying,[streaming],[trying])) $iif($getstream(%n).name,$v1,$getstream(%n))
    inc %n
  }
  if (%sel == 0) {
    did -b $d_name 212,213
    did -h $d_name 214
    did -v $d_name 213
  }
  else {
    did -c $d_name 210 %sel
    did -e $d_name 212
    var %s = $getstream(%sel)
    if ($isstreaming(%s)) {
      var %id = $v1
      if ($hget(%id,status) == trying) {
        did -e $d_name 213
        did -b $d_name 213
        did -v $d_name 213
        did -h $d_name 214
      }
      else {
        did -v $d_name 214
        did -h $d_name 213
        d_dispinfo $hget(streaming,%s)
      }
    }
    else {
      did -e $d_name 213
      did -v $d_name 213
      did -h $d_name 214
    }
  }
}

alias -l d_dispinfo {
  var %id = $$1
  if ($hget(%id,icy-name)) {
    did -o $d_name 302 1 $v1
  }
  if ($hget(%id,icy-genre)) {
    did -o $d_name 304 1 $v1
  }
  if ($hget(%id,icy-url)) {
    did -o $d_name 308 1 $v1
    did -e $d_name 309
  }
  if ($hget(%id,icy-br)) {
    did -o $d_name 306 1 $v1 $+ kbit/s
  }
  if ($hget(%id,StreamTitle)) {
    did -o $d_name 311 1 $v1
  }
  if ($sock(%id)) {
    did -e $d_name 312
  }
}

alias -l d_clearinfo {
  did -b $d_name 309,312
  did -r $d_name 302,304,308,306,311
}

alias -l d_name {
  return streamreader
}

on *:sockopen:stream*:{
  var %id = $sockname
  if (!$sockerr) {
    d_refresh
    sockwrite -n $sockname GET $hget(%id,path) HTTP/1.1
    sockwrite -n $sockname Host: $hget(%id,address)
    sockwrite -n $sockname icy-metadata:1
    sockwrite $sockname $crlf
  }
  else {
    stream -r $hget(%id,name)
    if ($hget(%id)) {
    hfree %id
    }
    showerror Could not connect to stream!
  }
}

on *:sockclose:stream*:{
  var %id = $sockname
  if ($hget(%id,state) != pls) {
    stream -r $hget(%id,name)
    if ($hget(%id)) {
     hfree %id
     }
    showerror Connection closed by host
  }
}

on *:socklisten:@streamreader_proxy_listener:{
  var %id = %streamreader.proxy,%sock = @streamreader_proxy_client
  if ($sock(%sock)) {
    sockclose %sock
  }
  sockaccept %sock
  sockwrite -n %sock ICY 200 OK
  sockwrite -n %sock icy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR>
  sockwrite -n %sock icy-notice2:StreamReader Proxy Server $streamreader_version $+ <BR>
  sockwrite -n %sock icy-name:StreamReader Proxy Server
  sockwrite -n %sock icy-genre: $+ $hget(%id,icy-genre)
  sockwrite -n %sock icy-url: $+ $hget(%id,icy-url)
  sockwrite -n %sock Content-Type: $hget(%id,Content-Type)
  sockwrite -n %sock icy-br: $+ $hget(%id,icy-br)
  sockwrite %sock $crlf
}

dialog streamreader_options {
  title Options
  size -1 -1 320 253
  text "Streams output folder:",22,10 12 120 20
  edit "",23,10 32 200 23,autohs read
  button "Select",24,215 32 95 23
  check "Remove tracks smaller than:",3,10 82 180 20
  edit "",4,190 80 60 23,autohs
  text "kB",5,265 82 40 20
  text "If track exists:",20,10 112 100 20
  combo 21,190 110 120 23,drop
  text "Use proxy server port:",7,10 142 180 20
  edit "",8,190 140 60 23
  check "Disable error popups (uses /echo instead)",25,10 172 300 20
  button "OK",10,105 220 100 23,ok
  button "Cancel",11,210 220 100 23,cancel
}

on *:dialog:streamreader_options:init:*:{
  did $iif($options().minsize-enabled == 1,-c,-u) $dname 3
  did -a $dname 4 $options().minsize
  did -a $dname 8 $options().proxyport
  did -a $dname 21 Auto-rename
  did -a $dname 21 Remove old file
  did -c $dname 21 $options().duplicateaction
  did -o $dname 23 1 $options().output
  did $iif($options().popuperror == 1,-c,-u) $dname 25
}

on *:dialog:streamreader_options:sclick:*:{
  if ($did == 10) {
    var %c = 44,%s = $chr(%c)
    %port = $did(8)
    if ((%port !isnum) || (%port < 49152) || (%port > 65535)) {
      showerror Port must be a numeric value between 49152 and 65535
      %port = 57234
    }
    set %streamreader.options $+($did(3).state,%s,$int($abs($did(4))),%s,%port,%s,$did(21).sel,%s,$did(23),%s,$did(25).state)
  }
  if ($did == 24) {
    did -o $dname 23 1 $$sdir($did(23))
  }
}

alias -l options {
  var %o = %streamreader.options,%c = 44,%p = $null,%d = $null
  if ($prop == minsize-enabled) {
    %p = 1
    %d = 0
  }
  elseif ($prop == minsize) {
    %p = 2
    %d = 0
  }
  elseif ($prop == proxyport) {
    %p = 3
    %d = 57234
  }
  elseif ($prop == duplicateaction) {
    %p = 4
    %d = 1
  }
  elseif ($prop == output) {
    %p = 5
    %d = $scriptdir $+ output\
  }
  elseif ($prop == popuperror) {
    %p = 6
    %d = 0
  }
  if (%p != $null) {
    if ($gettok(%o,%p,%c) != $null) {
      return $v1
    }
    else {
      return %d
    }
  }
}

dialog streamreader_add {
  title Add Stream
  size -1 -1 320 173
  radio "Enter direct stream URL or listen.pls URL:",1,10 12 300 20
  edit "",2,25 35 285 23,autohs
  radio "Open a local playlist (.pls) file:",3,10 67 300 20
  edit "",4,25 90 200 23,read autohs
  button "Select",5,230 90 80 23
  button "Add",10,105 140 100 23,ok
  button "Cancel",11,210 140 100 23,cancel
}

on *:dialog:streamreader_add:init:*:{
  did -c $dname 1
  did -a $dname 2 http://
  did -b $dname 5
}

on *:dialog:streamreader_add:sclick:*:{
  if ($did == 10) {
    if ($did(1).state == 1) {
      noop $savestream($$did(2))
      d_refresh
    }
    else {
      if ($gettok($read($qt($did(4)),w,file1*),2,61)) {
        noop $savestream($v1)
        d_refresh
      }
      else {
        showerror Not a valid playlist file
      }
    }
  }
  elseif ($did == 5) {
    did -u $dname 1
    did -c $dname 3
    var %f = $sfile($mircdir*.pls,Select playlist file,Select)
    if (%f != $null) {
      did -ra $dname 4 %f
    }
  }
  elseif ($did == 1) {
    did -e $dname 2
    did -b $dname 5
  }
  elseif ($did == 3) {
    did -b $dname 2
    did -e $dname 5
  }
}

alias -l tryrun {
  if ($lock(run)) {
    showerror For this function $readini(mirc.ini,text,commandchar) $+ run needs to be enabled in mIRC options
  }
  else {
    run $$1-
  }
}

alias -l showerror {
  if ($options().popuperror == 0) {
    .timer 1 0 noop $ $+ input(ERROR: $str($crlf,2) $+ $$1- ,hdou,StreamReader)
  }
  else {
    beep
    if ($line($active,$line($active,0)) != -) {
      echo $color(info) -ag -
    }
    echo $color(info) -ag * StreamReader ERROR: $replace($$1-,$crlf,---)
    echo $color(info) -ag -
  }
}

alias -l filter {
  return $remove($$1-,\,/,:,*,?,",<,>,|,.)
}

on *:load:{
  if ($line($active,$line($active,0)) != -) {
    echo $color(info) -ag -
  }
  echo $color(info) -ag SHOUTcast StreamReader v $+ $streamreader_version loaded!
  echo $color(info) -ag $chr(160)
  echo $color(info) -ag Start by selecting "SHOUTcast StreamReader" from the menubar
  echo $color(info) -ag Or by typing: $readini(mirc.ini,text,commandchar) $+ streamreader
  echo $color(info) -ag -
}

; eof :)