User:Mjb/Winamp & SHOUTcast

From Offset
< User:Mjb
Revision as of 01:10, 25 March 2019 by Mjb (talk | contribs) (Liquidsoap)
Jump to navigationJump to search

Winamp playlist regeneration on Windows

Every day, I want to:

  1. Regenerate a UTF-8-encoded playlist, picking up any changes made on my file system
  2. Load the new playlist in Winamp

I used to have a clever Python script for this purpose, but installing Python on Windows is an awfully steep prequisite. As it turns out, a single Windows command-shell command does the trick. This all goes on one line:

cmd.exe /C "chcp 65001 && dir Z:\music /b /s | findstr /e /l ".mp3 .flac .m4a .wav .wma .ogg .mp2"
| findstr /e /l /v ".lnk" > playlist.m3u8" && start /b playlist.m3u8

Here's an explanation:

  • && = if the previous command completed without error, do what comes next.
  • | = pipe the text output of the previous command as input to the next.
  • > … = put the output of the previous command into the designated file.
  • cmd.exe /C "" = open a command shell window and run the quoted command(s).
  • chcp 65001 = set the active code page to UTF-8
  • dir /b /s = recursively list the files in the given folder(s), only listing their full paths.
  • findstr /e /l "" = output only lines ending with any of these literal strings.
  • findstr /e /l /v "" = output lines not ending with any of these literal strings.
  • start /b … = open the designated file as a background process (no window).

To get it to run every day, you need to add it to the Task Scheduler, where you also tell it what directory to run from (i.e. where you want the playlist file to go, if you didn't specify a path in the command line). You access the Task Scheduler GUI through the Management Console or with a command-line command (schtasks), the syntax of which is too painful to deal with. Just use the GUI.

SHOUTcast stream transcoding

In 2008, I was looking into offering a low-bitrate MP3 version of an audio stream by connecting to it as a client, transcoding it, and feeding it to another server.

I didn't get very far in my research, but did find several options for grabbing a stream to a file on Unix:

mpg123 -b 4096 -s streamURL > out.mp3
gnetcat -l -p 8081 streamIP streamPort | lame --mp3input -b 64 - out.mp3
mpg123 -b 4096 -s streamURL | lame --mp3input -b 64 - out.mp3

And then there was also fIcy: an icecast/shoutcast stream grabber suite.

I don't remember if I tried any of these. The idea, though, was that if I could send the data to a file, the file could actually be a named pipe into icecast or something. However it didn't occur to me that I'd probably lose the protocol data (stream info and song titles). So it was starting to look like the only real option was going to be streamTranscoder, last updated in 2004.

Liquidsoap

In December 2015, I began using the Liquidsoap command-line scripting language to generate crossfaded AAC streams for my SHOUTcast and Icecast servers. It works a little better with Icecast.

I installed the standard Windows build, modified the test.liq script as shown below (but with working hosts, ports, and passwords), and ran "liquidsoap mytest.liq" on the command line.

# configure logging
set("log.stdout",true)
set("log.file",false)
set("log.level",4)

# allow sending commands to server while it's running
#   sample commands: playlist(dot)m3u8.reload
set("server.telnet",true)
set("server.telnet.port", 2425)

# create a source from a playlist
s = playlist(mime_type="application/x-mpegURL","/docs/private/Desktop/playlist.m3u8")

# set song name for ICY metadata. no idea if this works.
#s = rewrite_metadata([("song",'$(if $(song),"$(filename)","$(filename)")')],s)
#s = rewrite_metadata([("song",'$(if $(song)=="","hello","hi there")')],s)

# make the source go to next track when raw volume dips below -78 dBFS for more than 2s
s = skip_blank(threshold=-78.,max_blank=2.,s)

# make the source adjust output volume based on ReplayGain Track Gain tag
s = amplify(1.,override="REPLAYGAIN_TRACK_GAIN",s)

# smart_crossfade is difficult to tune, so I'm not using this yet.
# look into conservative=true and replacing fade_out with fade_final.
# s = smart_crossfade(start_next=20.,fade_in=10.,width=20.,fade_out=20.,margin=0.,s)

# simple crossfade is easier to use, but all tracks fade the same way
#  start_next = crossfade duration, i.e. how far before end of current track to start playing next track
#  fade_in = fade-in duration of next track
#  fade_out = fade-out duration of current track
s = crossfade(start_next=15.,fade_in=10.,fade_out=15.,s)

# Output to the local soundcard
#output.ao(fallible=true,s)

# Output raw 128 kbps AAC-LC to a file
#output.file(fallible=true, %fdkaac(channels=2, samplerate=44100, bitrate=128, afterburner=false, aot="mpeg2_aac_lc", transmux="adts", sbr_mode=false), "out.aac", s)

# Output 128 kbps AAC-LC to skew's Icecast server
#output.icecast(fallible=true, %fdkaac(channels=2, samplerate=44100, bitrate=128, afterburner=false, aot="mpeg2_aac_lc", transmux="adts", sbr_mode=false), host="kapow.skew.org", port=7778, password="howsoonisnow", mount="/", encoding="UTF-8", description="PKPN - Electronic Oriented Freeform", url="https://skew.org/pkpn/", public=false, s)

# Output 256 kbps AAC-LC to a local SHOUTcast server
output.icecast(fallible=true, %fdkaac(channels=2, samplerate=44100, bitrate=256, afterburner=false, aot="mpeg2_aac_lc", transmux="adts", sbr_mode=false), protocol="icy", icy_metadata="true", host="localhost", port=17778, password="howsoonisnow", mount="stream", encoding="UTF-8", description="PKPN - Electronic Oriented Freeform", url="https://skew.org/pkpn/", public=false, s)

If I recall correctly, there were a number of problems:

  • Windows builds were no longer supported.
  • No title info was streamed for files without artist & title metadata.
  • Non-ASCII characters in filenames weren't supported.
  • Non-ASCII characters in metadata were problematic too.

As of 2019, it seems they're now doing Windows builds regularly again, so I'm giving it another shot.

Well, no never mind. It works with MP3 sources, but add this to the list of problems:

  • External decoders (e.g. to enable playing FLAC sources) are not supported on Windows.

I filed a feature request on GitHub but am not hopeful it will result in anything.