hello everyone,

Please bare with me, I'm a new user of the magnificent liquidsoap ;)
I've recently migrated to a recent SVN of liquidsoap, the latest one
that doesn't encompass the video-related code (SVN #5946) and I have
one question and one request for troubleshooting.

First, I've updated my release of liquidsoap because I needed the
'auth' function callback in input.harbor. And this feature works
really great. Thanks for that. However, I have one question: I need to
rewrite the metadata of the stream from input.harbor with dynamic data
(i.e. non-static, not hardcoded in the configuration file but
retrieved from an external resource). I know the ANNOTATE
functionality won't work because it can only be used along with URIs
but it is exactly this kind of mechanism I would require: fetching
external data from script outputs.
Maybe I could use the 'auth' or 'on_connect' functions of input.harbor
and store the global variables retrieved until I use rewrite_metadata
for the stream. The problem is that I really don't know how to write
that using the liquidsoap language. Any hint please? (and with a short
example it would even be better)

My second question is related to the observation of the odd behaviour
of my new liquidsoap installed (put in production mind you, I do
regret) compared to my old install (0.36SVN).
Regularly, the stream completely shuts down after the end of a track.
This happens quite often and this is really annoying because it goes
up online only a few seconds afterwards.
I believe it is either related to this build or to my conf file
because the system remained unchanged and so the downstream server
used to relay the stream (which is really reliable).

Here is an excerpt from my logs, the disconnection appears at
19:31:11. It is always the same error repeated from one end to the
other in my logs.

2008/11/04 19:31:05 [src_3723:4] Got metadata at position 896: calling
handler...
2008/11/04 19:31:05 [non-blocking queue #1:4] Left select at
1225827065.974526 (1/0/0).
2008/11/04 19:31:05 [non-blocking queue #1:4] There are 1 ready tasks.
2008/11/04 19:31:05 [non-blocking queue #1:4] Enter select at
1225827065.974942, timeout -1.000000 (5/0/0).
2008/11/04 19:31:05 [fast queue #1:4] There are 1 ready tasks.
2008/11/04 19:31:05 [generic queue #2:4] There are 1 ready tasks.
2008/11/04 19:31:05 [liqfm:4] Submiting Shina Williams & His African
Percussionists -- Agboju Logun to lastfm
2008/11/04 19:31:05 [generic queue #1:4] There are 0 ready tasks.
2008/11/04 19:31:05 [non-blocking queue #2:4] There are 0 ready tasks.
2008/11/04 19:31:10 [root:2] We must catchup 4.99 seconds!
2008/11/04 19:31:11 [/:2] Shout socket error: timeout, network
failure, server shutdown? Restarting the output in 6 seconds.
2008/11/04 19:31:11 [source:4] src_24820 gets down
2008/11/04 19:31:11 [root:2] We must catchup 2.81 seconds (we've been
late for 100 rounds)!
2008/11/04 19:31:12 [root:2] We must catchup 1.19 seconds (we've been
late for 100 rounds)!
2008/11/04 19:31:18 [/:3] Connecting mount / for [EMAIL PROTECTED]
2008/11/04 19:31:18 [/:3] Connection setup was successful.
2008/11/04 19:31:18 [/:3] Setting up an MP3 encoder...
2008/11/04 19:31:21 [generic queue #2:4] There are 0 ready tasks.
2008/11/04 19:31:21 [non-blocking queue #1:4] Left select at
1225827081.571015 (1/0/0).
2008/11/04 19:31:21 [non-blocking queue #1:4] There are 0 ready tasks.
2008/11/04 19:31:21 [non-blocking queue #1:4] Enter select at
1225827081.571133, timeout -1.000000 (6/0/0).

Any help welcome, please.

P.S. I've enclosed my conf file too.

####BEGINNING OF FILE####

#!/var/XXX/radio/liquidsoap/bin/liquidsoap

### MAIN DIRECTIVES ###

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

set("scheduler.fast_queues",1)
set("scheduler.generic_queues",2)
set("scheduler.non_blocking_queues",2)
set("harbor.bind_addr", "0.0.0.0" )
set("harbor.port", 8030 )
set("harbor.icy",true)

### LOCAL PARAMETERS ###

icecast_password = "XXX"
icecast_host = "XXX"
icecast_port = 8040

lastfm_user = "XXX"
lastfm_password="XXX"
radio_name = "XXX"
radio_url = "XXX"
radio_descr = "XXX"
radio_genre = "XXX"

suds_conf = "/var/XXX/radio/html/init"

scripts = "/var/XXX/radio/suds/scripts/"



### GENERIC FUNCTIONS ###

interlude =
  playlist.safe(mode="random",
"/var/XXX/radio/liquidsoap/var/BACKUP/BACKUP.pls")

output.shoutcast = output.shoutcast.mp3(
    restart=true,
    restart_delay=6,
    description=radio_name,
    url=radio_url
)
out = output.shoutcast(
        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 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
      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

      b >= a + margin and a >= medium and b <= high
    then
      log("Transition: crossed, fade-out.")
      add(fade.out(sa),sb)
    elsif
      b >= a + margin and a <= medium and b <= high
    then
      log("Transition: crossed, no fade-out.")
      add(sa,sb)
    elsif
      a >= b + margin and b >= medium and a <= high
    then
      log("Transition: crossed, fade-in.")
      add(sa,fade.in(sb))

    else

      log("No transition: just sequencing.")
      sequence([sa, sb])
    end
  end
  smart_cross(width=width, duration=start_next, conservative=conservative,
              transition,s)
end

def mkpop(source)
       
compress(threshold=-15.,ratio=1.5,gain=1.15,normalize(target=-13.,
source))
end

def lastfm (m) =
  if (m["type"] == "songs") then
    canal = m["canal"]
    lastfm.submit(user=lastfm_user,password=lastfm_password,m)
  end
end

### LIVE HANDLING

def live_start()
    system(
        scripts^"suds-livestarted "^quote(suds_conf)
    )
end

def live_stop()
        system(
                scripts^"suds-livestopped "^quote(suds_conf)
        )       
end

def live_auth(login,password) =
  ret = get_process_lines(
    scripts^"suds-checklivecredentials "^quote(suds_conf)^"
"^quote(login)^" "^quote(password)
    )
  ret = list.hd(ret)
  bool_of_string(ret)
end

def mklivedynamic(source)

  source = on_metadata(lastfm,source)

  rewrite_metadata(
    [("artist", "Live"),
    ("comment", "$(radio_name)"),
    ("title", '$(if $(artist),"$(artist) - $(title)","$(title)")')],
        source
  )
 
end

def live_suds(mountpoint)

  source = input.harbor(on_connect=live_start,
on_disconnect=live_stop, auth=live_auth, mountpoint)

  strip_blank(length=5., source)
end

### PROGRAMMATION HANDLING

def mktrackdynamic(source)

  source = on_metadata(lastfm,source)
 
  source = on_metadata(
    fun (meta) ->
        system(
            scripts^"suds-feedback "^quote(suds_conf)^"
"^quote(meta["canal"])^" "^quote(meta["file_id"])
        ), source)

  rewrite_metadata(
    [("artist", "$(display_artist)"),
    ("comment", "$(radio_name)"),
    ("title", "$(display_title)"),
    ("album", "$(display_album)")],
       fallback(track_sensitive=false, [source, interlude])
  )
end

def channel_suds(~skip=true,name)
  log("Creating channel #[name]")

  def request () =
    log("Request for #{name}")
    request.create(audio=true,
        get_process_output(scripts ^ "suds-getnext " ^
quote(suds_conf) ^ " " ^ quote(name)) )
  end

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

  if skip then
    source = skip_blank(source, length=3., threshold=-30.)
  end

  source = eat_blank(threshold=-20., source)

  smart_crossfade(fade_out=0.5, fade_in=0.5, source)
end

### MAIN STUFF

main = channel_suds("Global")
live = live_suds("/")

def mkoutput(live_source,prog_source,name,genre)
  out(name=name, genre=genre, mkpop(fallback(track_sensitive=false,
[mklivedynamic(live_source), mktrackdynamic(prog_source), interlude])))
end

web = mkoutput(live, main, radio_name ^ " - " ^ radio_descr, radio_genre)

####END OF FILE####


-- 
best regards,
sincèrement,

okay_awright
<okay_awrightATddcrDOTbiz>
Public PGP key on request


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Savonet-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-users

Reply via email to