def start_streamer()
s = create_streamer(@config)
converters = []
file = nil
filename = nil
partial_command = nil
state = :state_handle_command
converter = create_converter()
Signal.trap("TERM") { converter.terminate(); exit! }
while true
case state
when :state_handle_command then
if partial_command == nil then
begin
partial_command = Outcry.read_message_nonblock(@readpipe)
rescue Exception => ex
end
end
if partial_command != nil then
if partial_command.complete? then
begin
handle_command(partial_command.data) if partial_command.length > 0
rescue Exception => ex
print "Handling command #{command} caused an exception: #{ex}\n"
end
partial_command = nil
else
partial_command = Outcry.continue_read(partial_command, @readpipe)
end
end
state = :state_run_convert
when :state_run_convert then
converter.run()
state = :state_play
when :state_play then
state = if file == nil then :state_find_next else :state_try_stream end
when :state_find_next then
if (filename = next_track()) != nil then
state = :state_start_convert
else
state = :state_handle_command
sleep(1)
end
when :state_start_convert then
converter.start(@playlist, @position)
converter.run()
sleep(0.3)
state = :state_try_stream
when :state_try_stream then
state = if @skip_rest then :state_nil_file
elsif file == nil then :state_open_file
else :state_read_file
end
@skip_rest = false
when :state_nil_file then
if file != nil and not file.closed? then file.close end
file = nil
state = :state_handle_command
when :state_open_file then
name = create_converter.find_converted(filename)
if name != nil
print "state_open_file: opening #{name}\n"
file = File.open(name)
metadata = ShoutMetadata.new
metadata.add 'song', File.basename(filename).gsub(/\.[^\.]*\Z/, "")
s.metadata = metadata
state = :state_read_file
else
print "state_open_file: skipping #{filename} because converted version wasn't found\n"
state = :state_nil_file
end
when :state_read_file then
begin
filedata = file.sysread(SHOUT_BLOCKSIZE)
state = :state_stream_sync
rescue EOFError => ex
state = if converter.converted_status(filename) ==
:converting then
sleep(0.3)
:state_read_file
else
:state_nil_file
end
end
when :state_stream_sync then
begin
s.send filedata
s.sync
state = :state_handle_command
rescue Exception => ex
print "Streaming failure, trying to reconnect: #{ex}\n"
state = :state_reconnect
end
when :state_reconnect then
begin
if s.connected? then
s.disconnect
end
s.connect
state = :state_stream_sync
rescue Exception => ex
print "Reconnect failure, trying again: #{ex}\n"
sleep(0.2)
end
else
print "Unknown state: #{state}\n"
state = :state_handle_command
end
end
end