#141: "Too Many Open Files" liquidsoap does not release the mp3 it has played?
-------------------------+--------------------------------------------------
  Reporter:  ~ok|        |       Owner:  admin    
      Type:  Bugs        |      Status:  new      
  Priority:  4           |   Milestone:  0.3.7    
 Component:  Liquidsoap  |     Version:  0.3.6+svn
Resolution:              |    Keywords:           
       Mac:  0           |       Linux:  0        
    Netbsd:  1           |       Other:  0        
   Freebsd:  0           |  
-------------------------+--------------------------------------------------
Comment (by ~ok|):

 just in case here's my current testing radio.liq:
 {{{
 #!/home/demo01/radio/liquidsoap/bin/liquidsoap

 set("log.level",7)
 set("log.file.path", "/var/log/liquidsoaplog")
 set("decoding.buffer_length",20.)
 set("scheduler.log",true)
 #set("init.daemon",true)
 set("init.daemon.pidfile.path",
 "/home/demo01/radio/liquidsoap/var/run/liquidsoap.pid")
 #set("server.socket",true)
 set("server.socket.path","/tmp/liquidaudio.sock")
 set("server.telnet",true)
 set("log.stdout", false)
 set("scheduler.event_queues",3)

 # === Settings ===

 icecast_password = "XXX"
 icecast_host = "192.168.1.2"
 icecast_port = 8000

 lastfm_user = "demo01Robot"
 lastfm_password="XXX"

 radio_descr = "Demo01"
 radio_url = "http://demo01.intern.local/";

 #Path to Radiopilote env.init.php
 radiopilote_conf = "/home/demo01/radio/html/init"

 # Script prefixing
 scripts = "/home/demo01/radio/radiopilote/scripts/"

 # A file for playing during failures
 interlude =
   playlist.safe("/home/demo01/radio/liquidsoap/var/BACKUP/BACKUP.pls")



 # === Main script ===


 output.icecast = output.icecast.mp3(
         restart=true,
         description=radio_descr,
         url=radio_url
 )
 out = output.icecast(
         host=icecast_host,
         port=icecast_port,
         password=icecast_password,
         stereo=true,
         samplerate=44100,
         bitrate=128
 )

 def fallback.transition(previous,next)
   add([fade.in(next),fade.final(duration=5.,previous)])
 end

 def sky(s)
   # 3-band crossover
   low = filter.iir.eq.low(frequency = 168.)
   mh = filter.iir.eq.high(frequency = 100.)
   mid = filter.iir.eq.low(frequency = 1800.)
   high = filter.iir.eq.high(frequency = 1366.)

   # Add back
   add(normalize = false,
       [ compress(attack = 100., release = 200., threshold = -20.,
                  ratio = 3., gain = 2., knee = 0.3,
            low(s)),
         compress(attack = 100., release = 200., threshold = -20.,
                  ratio = 3., gain = 2., knee = 0.3,
            mid(mh(s))),
         compress(attack = 100., release = 200., threshold = -20.,
                  ratio = 3., gain = 2., knee = 0.3,
            high(s))
       ])
 end

 def rewrite_metadata(l,~insert_missing=true,s)
   def map(m)
     def apply(x)
       label = fst(x)
       value = snd(x)
       (label,value % m)
     end
     list.map(apply,l)
   end
   map_metadata(map,insert_missing=insert_missing,s)
 end

 def smart_crossfade (~start_next=5.,~fade_in=3.,~fade_out=3.,
                      ~width=2.,~conservative=false,s)
   high   = -20.
   medium = -32.
   margin = 4.
   fade.out = fade.out(type="sin",duration=fade_out)
   fade.in  = fade.in(type="sin",duration=fade_in)
   add = fun (a,b) -> add(normalize=false,[b,a])
   log = log(label="smart_crossfade")

   def transition(a,b,ma,mb,sa,sb)

     list.iter(fun(x)-> log(level=4,"Before: #{x}"),ma)
     list.iter(fun(x)-> log(level=4,"After : #{x}"),mb)

     if
       # If A and B and not too loud and close, fully cross-fade them.
       a <= medium and b <= medium and abs(a - b) <= margin
     then
       log("Transition: crossed, fade-in, fade-out.")
       add(fade.out(sa),fade.in(sb))

     elsif
       # If B is significantly louder than A, only fade-out A.
       # We don't want to fade almost silent things, ask for >medium.
       b >= a + margin and a >= medium and b <= high
     then
       log("Transition: crossed, fade-out.")
       add(fade.out(sa),sb)

     elsif
       # Do not fade if it's already very low.
       b >= a + margin and a <= medium and b <= high
     then
       log("Transition: crossed, no fade-out.")
       add(sa,sb)

     elsif
       # Opposite as the previous one.
       a >= b + margin and b >= medium and a <= high
     then
       log("Transition: crossed, fade-in.")
       add(sa,fade.in(sb))

     # What to do with a loud end and a quiet beginning ?
     # A good idea is to use a jingle to separate the two tracks,
     # but that's another story.

     else
       # Otherwise, A and B are just too loud to overlap nicely,
       # or the difference between them is too large and overlapping would
       # completely mask one of them.
       log("No transition: just sequencing.")
       sequence([sa, sb])
     end
   end

   smart_cross(width=width, duration=start_next, conservative=conservative,
               transition,s)
 end


 # === Channels ===

 # Lastfm submission
 def lastfm (m) =
 # Only submit songs of type "chansons" (got type using annotate..)
   if (m["type"] == "songs") then
     canal = m["canal"]
     lastfm.submit(user=lastfm_user,password=lastfm_password,m)
   end
 end


 # To create a channel from a basic source, add:
 # - a new-track notification for radiopilote
 # - metadata rewriting
 # - the live shows
 # - the failsafe 'interlude' source to channels
 # - blank detection
 # - gentle compression
 def mklive(source)

 # This script updates a lastfm account for each channel...
 #  source = on_metadata( fun (meta) ->
 #                    system("/usr/pkg/bin/lastfm_submission
 "^quote(lastfm_conf)^" "
 #                   ^quote(meta["canal"])^ " "
 #               ^quote(meta["title"])^" "
 #               ^quote(meta["artist"])^" "
 #               ^quote(meta["album"])^" "
 #               ^quote(meta["length"])^" "
 #               ^quote(meta["type"])^" &"), source)

 # Add lastfm submission
   source = on_metadata(lastfm,source)

 # This scripts tells us that this file has been played
   source = on_metadata(
         fun (meta) ->
                 system(
                         scripts^"radiopilote-feedback
 "^quote(radiopilote_conf)^" "^quote(meta["canal"])^"
 "^quote(meta["file_id"])
                 ), source)

 # Some metadata rewriting, new values are provided by the anotate plugin
   source = rewrite_metadata(
    [("artist",'$(if $(display_artist),"$(display_artist)","$(artist)")'),
     ("comment",""),
     ("title", '$(if $(display_title),"$(display_title)","$(title)")'),
     ("album", '$(if $(display_album),"$(display_album)","$(album)")')],
         fallback(track_sensitive=false, [source, interlude])
   )

 # Compress the sound
 #  normalize(compress(threshold=-15.,ratio=2.,source))
 normalize(sky(source), gain_min=-9., gain_max=12.)

 end

 # === Basic sources ===

 # Create a radiopilote-driven source
 def channel_radiopilote(~skip=true,name)
   log("Creating channel #[name]")

   # Request function
   def request () =
     log("Request for #{name}")

     req_str = scripts ^ "radiopilote-getnext " ^ quote(radiopilote_conf) ^
 " " ^ quote(name);
     log(req_str)
     req_output = get_process_output(req_str)
     log(req_output)

     request.create(audio=true,
 #        get_process_output(scripts ^ "radiopilote-getnext " ^
 quote(radiopilote_conf) ^ " " ^ quote(name)) )
         req_output)
   end

   # Basic source
   source =   request.dynamic(
           id="dyn_"^name,request)

   # Only skip some channels
   if skip then
     source = skip_blank(source, length=2., threshold=-40.)
   end

   # Add smart crossfading
   smart_crossfade(fade_out=0.5, fade_in=0.5, source)

 end

 # Channels encoded here
 main = channel_radiopilote("Main")

 # Create a channel using mklive(), encode and output it to icecast.
 def mkoutput(mount,source,name)
   out(mount=mount,name=name,
      mklive(source))
 end


 # === Outputs ===

 # These channels are encoded on this machine
 main  = mkoutput("main", main, "Demo01 - Main channel")

 # Finally the web channel, and its mp3 version
 web =
   out(
         mount="stream",
         name=radio_descr^" - "^radio_url,

         fallback([main, interlude])
   )
 }}}

-- 
Ticket URL: <http://savonet.rastageeks.org/ticket/141#comment:10>
Savonet <http://savonet.rastageeks.org/>
Let's program our stream !
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Savonet-trac mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-trac

Reply via email to