# Decoders, enabled when the binary is detected and the os is not Win32. # Get_mime is not always defined # so we define a default in this case.. my_get_mime = fun (_) -> "" %ifdef get_mime my_get_mime = get_mime %endif get_mime = my_get_mime %ifdef add_decoder if test_process("which flac") then log(level=3,"Found flac binary: enabling flac external decoder.") flac_p = "flac -d -c - 2>/dev/null" def test_flac(file) = if test_process("which metaflac") then channels = list.hd(get_process_lines("metaflac \ --show-channels #{quote(file)} \ 2>/dev/null")) # If the value is not an int, this returns 0 and we are ok :) int_of_string(channels) else # Try to detect using mime test.. mime = get_mime(file) if string.match(pattern="flac",file) then # We do not know the number of audio channels # so setting to -1 (-1) else # All tests failed: no audio decodable using flac.. 0 end end end add_decoder(name="FLAC",description="Decode files using the flac \ decoder binary.", test=test_flac,flac_p) else log(level=3,"Did not find flac binary: flac decoder disabled.") end %endif if os.type != "Win32" then if test_process("which metaflac") then log(level=3,"Found metaflac binary: enabling flac external metadata \ resolver.") def flac_meta(file) ret = get_process_lines("metaflac --export-tags-to=- \ #{quote(file)} 2>/dev/null") ret = list.map(string.split(separator="="),ret) # Could be made better.. def f(l',l)= if list.length(l) >= 2 then list.append([(list.hd(l),list.nth(l,1))],l') else if list.length(l) >= 1 then list.append([(list.hd(l),"")],l') else l' end end end list.fold(f,[],ret) end add_metadata_resolver("FLAC",flac_meta) else log(level=3,"Did not find metaflac binary: flac metadata resolver disabled.") end end # A list of know extensions and content-type for AAC. # Values from http://en.wikipedia.org/wiki/Advanced_Audio_Coding # TODO: can we register a setting for that ?? aac_mimes = ["audio/aac", "audio/aacp", "audio/3gpp", "audio/3gpp2", "audio/mp4", "audio/MP4A-LATM", "audio/mpeg4-generic", "audio/x-hx-aac-adts"] aac_filexts = ["m4a", "m4b", "m4p", "m4v", "m4r", "3gp", "mp4", "aac"] # Faad is not very selective so # We are checking only file that # end with a known extension or mime type def faad_test(file) = # Get the file's mime mime = get_mime(file) # Test mime if list.mem(mime,aac_mimes) then true else # Otherwise test file extension ret = string.extract(pattern='\.(.+)$',file) if list.length(ret) != 0 then ext = ret["1"] list.mem(ext,aac_filexts) else false end end end if os.type != "Win32" then if test_process("which faad") then log(level=3,"Found faad binary: enabling external faad decoder and \ metadata resolver.") faad_p = (fun (f) -> "faad -w #{quote(f)} 2>/dev/null") def test_faad(file) = if faad_test(file) then channels = list.hd(get_process_lines("faad -i #{quote(file)} 2>&1 | \ grep 'ch,'")) ret = string.extract(pattern=", (\d) ch,",channels) ret = if list.length(ret) == 0 then # If we pass the faad_test, chances are # high that the file will contain aac audio data.. "-1" else ret["1"] end int_of_string(default=(-1),ret) else 0 end end %ifdef add_oblivious_decoder add_oblivious_decoder(name="FAAD",description="Decode files using \ the faad binary.", test=test_faad, faad_p) %endif def faad_meta(file) = if faad_test(file) then ret = get_process_lines("faad -i \ #{quote(file)} 2>&1") # Yea, this is tuff programming (again) ! def get_meta(l,s)= ret = string.extract(pattern="^(\w+):\s(.+)$",s) if list.length(ret) > 0 then list.append([(ret["1"],ret["2"])],l) else l end end list.fold(get_meta,[],ret) else [] end end add_metadata_resolver("FAAD",faad_meta) else log(level=3,"Did not find faad binary: faad decoder disabled.") end end # Standard function for displaying metadata. # Shows artist and title, using "Unknown" when a field is empty. # @param m Metadata packet to be displayed. def string_of_metadata(m) artist = m["artist"] title = m["title"] artist = if ""==artist then "Unknown" else artist end title = if ""==title then "Unknown" else title end "#{artist} -- #{title}" end # Use X On Screen Display to display metadata info. # @param ~color Color of the text. # @param ~position Position of the text (top|middle|bottom). # @param ~font Font used (xfontsel is your friend...) # @param ~display Function used to display a metadata packet. def osd_metadata(~color="green",~position="top", ~font="-*-courier-*-r-*-*-*-240-*-*-*-*-*-*", ~display=string_of_metadata, s) osd = 'osd_cat -p #{position} --font #{quote(font)}' ^ ' --color #{color}' def feedback(m) system("echo #{quote(display(m))} | #{osd} &") end on_metadata(feedback,s) end # Use notify to display metadata info. # @param ~urgency Urgency (low|normal|critical). # @param ~icon Icon filename or stock icon to display. # @param ~time Timeout in milliseconds. # @param ~display Function used to display a metadata packet. # @param ~title Title of the notification message. def notify_metadata(~urgency="low",~icon="stock_smiley-22",~time=3000, ~display=string_of_metadata, ~title="Liquidsoap: new track",s) send = 'notify-send -i #{icon} -u #{urgency}' ^ ' -t #{time} #{quote(title)} ' on_metadata(fun (m) -> system(send^quote(display(m))),s) end