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