lib/mikeplayer.rb in mikeplayer-1.0.6 vs lib/mikeplayer.rb in mikeplayer-1.0.7
- old
+ new
@@ -2,34 +2,34 @@
require 'json'
require 'open3'
require 'io/console'
require 'mp3info'
require 'mikeplayer/version'
-require 'mikeplayer/settings'
+require 'mikeplayer/display'
require 'mikeplayer/playlist'
+require 'mikeplayer/play_thread'
+require 'mikeplayer/settings'
require 'mikeplayer/song'
module MikePlayer
class Player
- PAUSE_INDICATOR = "||".freeze
- INDICATOR_SIZE = 4
- SLEEP_SETTING = 0.5
+ PLAY_SLEEP = 0.5
+ PAUSE_SLEEP = 1.0
STOPPED = :stopped
PLAYING = :playing
PAUSED = :paused
+ SONG_CHANGE = :song_change
def initialize(options, *args)
@settings = Settings.new(options)
@playlist = Playlist.new(@settings.playlist)
@minutes = @settings.minutes
@command = ''
- @pid = nil
- @timer_start = nil
+ @timer_start = Time.now if (@minutes > 0)
@state = STOPPED
+ @player = PlayThread.new(volume: @settings.volume)
- check_system
-
if (true == @settings.list?)
@songs.map { |song| File.basename(song) }.sort.each {|song| puts "#{File.basename(song)}"}
exit 0
end
@@ -56,116 +56,63 @@
exit 1
end
@thread = Thread.new do
- @song_i = 0
- display_width = 0
+ @display = Display.new
+ @song_i = 0
while (@song_i < @playlist.size)
- song = @playlist.get(@song_i)
- @song_start = Time.now
- @pause_time = nil
- info_prefix = "\r#{@playlist.song_info(@song_i)}".freeze
+ @display.song_info = @playlist.song_info(@song_i)
- stdin, stdother, thread_info = Open3.popen2e('play', '--no-show-progress', '--volume', @settings.volume, song.filename)
+ @player.play(song.filename)
@state = PLAYING
- @pid = thread_info.pid
- indicator = ''
- info_changed = false
- while (true == pid_alive?)
+ while @player.playing?
pause_if_over_time_limit
- if (true == playing?)
- indicator = "#{'>' * (playing_time % INDICATOR_SIZE)}".ljust(INDICATOR_SIZE)
- info_changed = true
- elsif (true == paused?) && (false == indicator.include?(PAUSE_INDICATOR))
- indicator = PAUSE_INDICATOR.ljust(INDICATOR_SIZE)
- info_changed = true
- end
+ @display.elapsed = @player.elapsed if playing?
- if (true == info_changed)
- mindicator = ""
+ @display.display!(song.length_str(@player.elapsed), minutes_remaining)
- if (0 < minutes_remaining)
- mindicator = "(#{minutes_remaining}↓) "
- end
-
- print("\r" << ' '.ljust(display_width))
-
- info = "#{info_prefix} #{song.length_str(playing_time)} #{mindicator}#{indicator}"
-
- print(info)
-
- display_width = info.size
-
- info_changed = false
- $stdout.flush
- end
-
- sleep SLEEP_SETTING
+ sleep(sleep_time)
end
- stdin.close
- stdother.close
-
- @pid = nil
-
- if (true == playing?) && (playing_time >= (song.length - 1))
+ if playing? && @player.stopped?
next_song
+ elsif paused?
+ while paused?
+ sleep(sleep_time)
+ end
end
end
- @pid = nil
+ @player.stop
print("\r\n")
exit
end
wait_on_user
print("\r\n")
end
- def cmd_exist?(cmd)
- if (true != system('command'))
- raise "Missing 'command' command, which is used to test compatibility."
- end
-
- if (true != system("command -v #{cmd} >/dev/null 2>&1"))
- return false
- end
-
- return true
- end
-
private
- def check_system
- %w(play).each do |cmd|
- if (false == cmd_exist?(cmd))
- raise "#{cmd} failed, do you have sox installed?"
- end
- end
-
- return nil
- end
-
def wait_on_user
while ('q' != @command)
@command = STDIN.getch
if ('c' == @command)
press_pause
elsif ('v' == @command)
next_song
elsif ('z' == @command)
previous_song
- elsif ('q' == @command) && (false == @pid.nil?)
- stop_song
- @thread.kill
+ elsif ('q' == @command)
+ press_stop
elsif ('t' == @command)
@timer_start = Time.now
elsif (false == @timer_start.nil?) && ("#{@command.to_i}" == @command)
if (0 == @minutes)
@minutes = @command.to_i
@@ -183,96 +130,82 @@
def paused?
return (PAUSED == @state)
end
+ def changing?
+ return (SONG_CHANGE == @state)
+ end
+
+ def press_stop
+ @player.stop
+ @state = STOPPED
+ end
+
def press_pause
- if (true == playing?)
- kill("STOP")
- @pause_time = Time.now
+ debug('|')
+
+ if playing?
+ debug('>')
@state = PAUSED
- elsif (true == paused?)
- kill("CONT")
- @song_start += (Time.now - @pause_time)
- @pause_time = nil
+ @display.paused
+ @player.pause
+ elsif paused?
+ debug('|')
@state = PLAYING
else
print("Confused state #{@state}.")
end
end
- def stop_song
- kill("INT")
-
- sleep 0.2
-
- if (true == pid_alive?)
- kill("KILL")
- end
-
- @state = STOPPED
- end
-
- def pid_alive?(pid = @pid)
- if (false == pid.nil?)
- return system("ps -p #{pid} > /dev/null")
- end
-
- return false
- end
-
def next_song
debug('n')
- stop_song
+ @state = SONG_CHANGE
+
+ @player.stop
+
@song_i += 1
end
def previous_song
debug('p')
- stop_song
- if (playing_time < 10)
- @song_i -= 1 unless @song_i <= 0
+ @state = SONG_CHANGE
+
+ if (@player.elapsed < 10)
+ @song_i -= 1 if @song_i.positive?
else
debug('x')
end
- end
- def kill(signal)
- if (false == @pid.nil?)
- Process.kill(signal, @pid)
- end
+ @player.stop
end
def pause_if_over_time_limit
if (false == @timer_start.nil?) && (0 < @minutes) && (true == playing?)
- if (0 > minutes_remaining)
+ if (minutes_remaining && 0 >= minutes_remaining)
press_pause
@timer_start = nil
@minutes = 0
end
end
end
- def playing_time
- return (Time.now - @song_start).to_i - pause_time
+ def minutes_remaining
+ return if ((0 == @minutes) || (@timer_start.nil?))
+
+ (@minutes - ((Time.now - @timer_start).to_i / 60).to_i)
end
- def pause_time
- if (@pause_time.nil?)
- return 0
- else
- return (Time.now - @pause_time).to_i
- end
+ def sleep_time
+ return PLAY_SLEEP if playing?
+
+ PAUSE_SLEEP
end
- def minutes_remaining
- if ((0 == @minutes) || (@timer_start.nil?))
- return -1
- else
- return (@minutes - ((Time.now - @timer_start).to_i / 60).to_i)
- end
+ def song
+ @playlist.get(@song_i)
end
def debug(str)
print(str) if @settings.debug?
end