ralphy wrote: 
> Yes, please and thank you.
Here you are.

Note that you need to supply all the environment variables as shown
here, included the FORMAT as WAV (uses sox) or FLAC (uses flac), and
COMPRESSION -0 to -8 (or --fast), and the HOST IP address.  

Script to kill off any existing player and start again.


Code:
--------------------
    
  pkill -SIGKILL -f playstreamMF
  pkill -SIGKILL -f Play-Stream-MF
  export BITRATE=192000
  export DEPTH=24
  export VBPORT=8082
  export COMPRESSION="-4"
  export FORMAT='FLAC'
  export HOST="192.168.1.10"                                            
  /storage/Scripts/squeezelite-streamMF.sh 2> 
/storage/Scripts/squeezeliteMF.err | /storage/Scripts/playstreamMF 2>> 
/storage/Scripts/playstreamMF.err &
  
--------------------


With WAV the player stops when it has received 2^31 bytes.  Reselecting
the stream on the player restarts it.  I'm not sure whether it is doing
something similar for FLAC (I haven't had long enough to do enough
tests).

With FLAC, if you pause playing using the LMS web interface you seem to
need to restart the player.  This isn't true with WAV.  Starting the
FLAC stream is also somewhat temperamental  on both my players.  I think
this is to do with the player software rather than the python program. 
If you select the stream and leave it alone it seems to run reliably for
at least a couple of hours.

The python program.


Code:
--------------------
    
  #!/usr/bin/python
  
  import BaseHTTPServer
  import SocketServer
  import subprocess                                     # For running flac, sox 
or whatever
  import sys                                            # For writing to stderr
  import os                                             # For environment 
variables
  
  HOST = os.environ.get('HOST')                         # The server host.  Can 
also be set to ""
  PORT = int(os.environ.get('VBPORT'))                    # An http port
  BITRATE = int(os.environ.get('BITRATE'))              # Bitrate 44100, 48000, 
96000 or 192000
  DEPTH = int(os.environ.get('DEPTH'))                  # A valid depth - 16, 
24 or 32
  COMPRESSION = os.environ.get('COMPRESSION')             # Set to -4, or 
--fast or similar for flac
  FORMAT = os.environ.get('FORMAT')                     # Format must be FLAC 
or WAV
  
  FLACMIMETYPE = 'audio/flac'
  WAVMIMETYPE = 'audio/x-wav'
  BUFFER = 65536
  
  
  class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
  
  def do_HEAD(s):
  sys.stderr.write (str(s.client_address) + str(', ') + str(s.path) + str(', ') 
+ str(s.command) + '\n')
  s.send_response(200)                          # OK
  if FORMAT == "FLAC":                                # A Flac or WAV audio 
format
        MIMETYPE = FLACMIMETYPE
  else:
        MIMETYPE = WAVMIMETYPE
  s.send_header('Content-Type', MIMETYPE)               # Wav/flac
  
  # We don't, and can't know the length. However, sending a Content-Length 
header with flac doesn't work, so I don't.
  # I also tried 'chunked' output, but that didn't work with one of my 
renderers and flac.
  
  s.end_headers()    
  
  def do_GET(s):
  
  s.do_HEAD()                                           # Send the headers
  
  # Use flac or sox to transform raw data to flac or wav, using the environment 
variables for bitrate and depth (bits) and compression.
  # All input is raw from stdin, and out to stdout (default for -c).  Warnings 
are errors.  No info/error messages.
  
  if FORMAT == "FLAC": 
  engine = 'flac - -w --totally-silent --force-raw-format --channels 2 --bps ' 
+  str(DEPTH) + ' --sample-rate ' + str(BITRATE) + ' --endian little --sign 
signed ' + str(COMPRESSION)
  elif FORMAT == "WAV":
        engine = 'sox -t raw -r ' + str(BITRATE) + ' -b ' +  str(DEPTH) + ' -L 
-e signed -c 2 - -t wav - '
  else:
        sys.stderr.write(str('Assuming WAV format') + '\n')
        engine = 'sox -t raw -r ' + str(BITRATE) + ' -b ' +  str(DEPTH) + ' -L 
-e signed -c 2 - -t wav - '
  
  pa = subprocess.Popen (engine, shell = True, bufsize = BUFFER, stdout = 
subprocess.PIPE)
  
  # Loop until no data or an error, reading and writing.
  
  try:
  while True:
  data = pa.stdout.read(1024)
            if len(data) == 0: break
  s.wfile.write(data)
        sys.stderr.write(str('No more data') + '\n')
  
  except:                                               # Any error is bad news 
for real time data
  sys.stderr.write(str('Exception whilst reading audio stream') + '\n')
  raise
  
  # Done.  Report and kill off the subprocess.
  
  finally:
  pa.kill()
  
  # Execution starts here....
  
  # Allow the port to be re-used.  If there's a failure but the client keeps 
the port open, restarting the server can fail
  # unless this is set.
  
  SocketServer.TCPServer.allow_reuse_address = True
  
  # Define the server, using the above host and port, executing the Handler 
class
  
  httpd = SocketServer.TCPServer((HOST, PORT), Handler)
  sys.stderr.write(str('listening on port ') + str(PORT) + '\n')
  
  # And now handle requests one by one. When one request finishes, usually with 
an error 32 (Broken pipe), the request finishes.
  # Log the fact and try again.
  
  try:
  while True:
  httpd.handle_request()
  sys.stderr.write(str('Finished request') + '\n')
  
  # Close if run from terminal and closed, or a sigkill/term is received.
  
  except (KeyboardInterrupt, SystemExit):
  pass                                          # Nothing
  
  # Something odd is going on.  I never see the following, but it does stop on 
a SIGKILL.
  
  sys.stderr.write(str('Exit') + '\n')
  httpd.server_close()
  httpd.shutdown()
  
--------------------



LMS 7.9 on VortexBox Midi running Xubuntu 14.04, FLACs 16->24 bit,
44.1->192kbps. Wired Touch + EDO, coax to Musical Fidelity M1 CLiC.
Wireless Xubuntu 14.04 laptop controls LMS via Chromium.   Meridian
Explorer USB DAC to listen via Squeezelite on Vortexbox & other PCs as
required.  Spare Touch in loft.
------------------------------------------------------------------------
PasTim's Profile: http://forums.slimdevices.com/member.php?userid=41642
View this thread: http://forums.slimdevices.com/showthread.php?t=101622

_______________________________________________
discuss mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/discuss

Reply via email to