mikeplayer 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/MikePlayer.rb +4 -3
- data/lib/mikeplayer/display.rb +53 -5
- data/lib/mikeplayer/play_thread.rb +12 -16
- data/lib/mikeplayer/playlist.rb +1 -1
- data/lib/mikeplayer/settings.rb +7 -2
- data/lib/mikeplayer/song.rb +9 -4
- data/lib/mikeplayer/version.rb +1 -1
- data/lib/mikeplayer.rb +30 -14
- data/mikeplayer.gemspec +1 -2
- metadata +5 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b38d5b7fef4b5141b1f884d386ca6d8cbc17b4890aacaac2a649b06aefd84674
|
|
4
|
+
data.tar.gz: 1f38509a5e275b35d9adbb83c4cf09b23c739f999afe71c7d8ffc16ffbd865d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0216f0b2f19389ce060bd48fb1ce7bbfbd13a8e9ff3ae461c16830b745c5eaa463e9f4f1c6706e2085338cc44848d11b855e32e0454a98e5f8cdd96ec916939c
|
|
7
|
+
data.tar.gz: a72f9a0446bcc94e87229812029b7de95bfb1d881450d665fce45e8161c0aa9ee83c762bf42d392e08491e68f10c03244819efa8e94499725d767c7be6f02338
|
data/bin/MikePlayer.rb
CHANGED
|
@@ -14,14 +14,15 @@ OptionParser.new do |opt|
|
|
|
14
14
|
|
|
15
15
|
EOF
|
|
16
16
|
opt.on('-s', '--shuffle', 'Shuffle playlist.') { |o| options[:shuffle] = true }
|
|
17
|
-
opt.on('-r', '--random n', 'Create playlist with randomly picked n songs.') { |o| options[:random] = o
|
|
17
|
+
opt.on('-r', '--random n', Integer, 'Create playlist with randomly picked n songs.') { |o| options[:random] = o }
|
|
18
18
|
opt.on('-o', '--overwrite', 'Overwrite playlist.') { |o| options[:overwrite] = true }
|
|
19
|
-
opt.on('-v', '--volume n', 'Changes default volume.') { |o| options[:volume] = o }
|
|
19
|
+
opt.on('-v', '--volume n', Float, 'Changes default volume.') { |o| options[:volume] = o }
|
|
20
20
|
opt.on('-p', '--playlist name', 'Play playlist name.') { |o| options[:playlist] = o }
|
|
21
21
|
opt.on('-l', '--list', 'List songs in playlist.') { |o| options[:list] = true; }
|
|
22
22
|
opt.on('-d', '--directory name', 'Directory to find mp3s.') { |o| options[:directory] = o }
|
|
23
|
-
opt.on('-t', '--time minutes', 'Limit time to number of minutes.') { |o| options[:minutes] = o }
|
|
23
|
+
opt.on('-t', '--time minutes', Integer, 'Limit time to number of minutes.') { |o| options[:minutes] = o }
|
|
24
24
|
opt.on('-x', '--debug', 'Turn on debug.') { |o| options[:debug] = true }
|
|
25
|
+
opt.on('-f', '--fullscreen', 'Use an alternate full-screen buffer while playing.') { |o| options[:fullscreen] = true }
|
|
25
26
|
end.parse!
|
|
26
27
|
|
|
27
28
|
MikePlayer::Player.new(options, ARGV).play
|
data/lib/mikeplayer/display.rb
CHANGED
|
@@ -3,24 +3,57 @@ module MikePlayer
|
|
|
3
3
|
PAUSE_INDICATOR = '||'.freeze
|
|
4
4
|
INDICATOR_SIZE = 4
|
|
5
5
|
|
|
6
|
+
RESET = "\e[0m".freeze
|
|
7
|
+
TITLE_COLOR = "\e[1;36m".freeze # bold cyan
|
|
8
|
+
DIM_COLOR = "\e[2m".freeze # dim gray
|
|
9
|
+
BANNER_COLOR = "\e[1;37m".freeze # bold white
|
|
10
|
+
ELAPSED_COLOR = "\e[37m".freeze # white
|
|
11
|
+
COUNTDOWN_COLOR = "\e[33m".freeze # yellow
|
|
12
|
+
PLAY_COLOR = "\e[32m".freeze # green
|
|
13
|
+
PAUSE_COLOR = "\e[1;31m".freeze # bold red
|
|
14
|
+
|
|
15
|
+
ENTER_ALT_SCREEN = "\e[?1049h\e[2J\e[H".freeze
|
|
16
|
+
EXIT_ALT_SCREEN = "\e[?1049l".freeze
|
|
17
|
+
|
|
18
|
+
def self.colorize(text, color)
|
|
19
|
+
return text unless $stdout.tty?
|
|
20
|
+
|
|
21
|
+
"#{color}#{text}#{RESET}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.enter_fullscreen
|
|
25
|
+
print(ENTER_ALT_SCREEN)
|
|
26
|
+
$stdout.flush
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.exit_fullscreen
|
|
30
|
+
print(EXIT_ALT_SCREEN)
|
|
31
|
+
$stdout.flush
|
|
32
|
+
end
|
|
33
|
+
|
|
6
34
|
def initialize
|
|
7
35
|
@width = 0
|
|
8
36
|
@indicator = ''
|
|
37
|
+
@paused = false
|
|
9
38
|
@changed = false
|
|
39
|
+
@color = $stdout.tty?
|
|
10
40
|
end
|
|
11
41
|
|
|
12
42
|
def song_info=(v)
|
|
13
|
-
@
|
|
43
|
+
@position = v[:position].freeze
|
|
44
|
+
@title = v[:title].freeze
|
|
14
45
|
end
|
|
15
46
|
|
|
16
47
|
def elapsed=(v)
|
|
17
48
|
@indicator = "#{'>' * (v % INDICATOR_SIZE)}".ljust(INDICATOR_SIZE)
|
|
49
|
+
@paused = false
|
|
18
50
|
@changed = true
|
|
19
51
|
end
|
|
20
52
|
|
|
21
53
|
def paused
|
|
22
|
-
if (false == @
|
|
54
|
+
if (false == @paused)
|
|
23
55
|
@indicator = PAUSE_INDICATOR.ljust(INDICATOR_SIZE)
|
|
56
|
+
@paused = true
|
|
24
57
|
@changed = true
|
|
25
58
|
end
|
|
26
59
|
end
|
|
@@ -30,13 +63,20 @@ module MikePlayer
|
|
|
30
63
|
|
|
31
64
|
mindicator = "(#{countdown}↓) " if countdown
|
|
32
65
|
|
|
33
|
-
|
|
66
|
+
position = colorize(@position, DIM_COLOR)
|
|
67
|
+
title = colorize(@title, TITLE_COLOR)
|
|
68
|
+
elapsed = colorize(elapsed_info, ELAPSED_COLOR)
|
|
69
|
+
indicator = colorize(@indicator, @paused ? PAUSE_COLOR : PLAY_COLOR)
|
|
70
|
+
count = countdown ? colorize(mindicator, COUNTDOWN_COLOR) : ''
|
|
34
71
|
|
|
35
|
-
|
|
72
|
+
plain_info = "Playing #{@position}: #{@title} #{elapsed_info} #{mindicator}#{@indicator}"
|
|
73
|
+
info = "\rPlaying #{position}: #{title} #{elapsed} #{count}#{indicator}"
|
|
74
|
+
|
|
75
|
+
print("\r" << ' '.ljust(@width))
|
|
36
76
|
|
|
37
77
|
print(info)
|
|
38
78
|
|
|
39
|
-
@width =
|
|
79
|
+
@width = plain_info.size
|
|
40
80
|
@changed = false
|
|
41
81
|
|
|
42
82
|
$stdout.flush
|
|
@@ -45,5 +85,13 @@ module MikePlayer
|
|
|
45
85
|
def changed?
|
|
46
86
|
true == @changed
|
|
47
87
|
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def colorize(text, color)
|
|
92
|
+
return text unless @color
|
|
93
|
+
|
|
94
|
+
"#{color}#{text}#{RESET}"
|
|
95
|
+
end
|
|
48
96
|
end
|
|
49
97
|
end
|
|
@@ -3,11 +3,12 @@ module MikePlayer
|
|
|
3
3
|
def initialize(volume: 1.0)
|
|
4
4
|
check_system
|
|
5
5
|
|
|
6
|
-
@pid
|
|
7
|
-
@
|
|
8
|
-
@
|
|
9
|
-
@
|
|
10
|
-
@
|
|
6
|
+
@pid = nil
|
|
7
|
+
@wait_thread = nil
|
|
8
|
+
@volume = volume
|
|
9
|
+
@start_t = 0
|
|
10
|
+
@elapsed = 0
|
|
11
|
+
@paused = false
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def play(file)
|
|
@@ -38,25 +39,19 @@ module MikePlayer
|
|
|
38
39
|
@elapsed += Time.now.to_i - @start_t
|
|
39
40
|
@start_t = 0
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
break unless alive?
|
|
43
|
-
|
|
44
|
-
sleep 0.1
|
|
45
|
-
end
|
|
42
|
+
@wait_thread&.join(1)
|
|
46
43
|
|
|
47
44
|
kill('KILL')
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
break unless alive?
|
|
51
|
-
|
|
52
|
-
sleep 0.1
|
|
53
|
-
end
|
|
46
|
+
@wait_thread&.join
|
|
54
47
|
|
|
55
48
|
@paused = true
|
|
56
49
|
end
|
|
57
50
|
|
|
58
51
|
def kill(signal)
|
|
59
52
|
Process.kill(signal, @pid) if alive?
|
|
53
|
+
rescue Errno::ESRCH
|
|
54
|
+
nil
|
|
60
55
|
end
|
|
61
56
|
|
|
62
57
|
def alive?
|
|
@@ -117,7 +112,8 @@ module MikePlayer
|
|
|
117
112
|
|
|
118
113
|
stdin, stdother, thread_info = Open3.popen2e(*args)
|
|
119
114
|
|
|
120
|
-
@pid
|
|
115
|
+
@pid = thread_info.pid
|
|
116
|
+
@wait_thread = thread_info
|
|
121
117
|
|
|
122
118
|
10.times do
|
|
123
119
|
break if alive?
|
data/lib/mikeplayer/playlist.rb
CHANGED
|
@@ -70,7 +70,7 @@ module MikePlayer
|
|
|
70
70
|
def song_info(i)
|
|
71
71
|
song_i_str = "#{i + 1}".rjust(self.size.to_s.size)
|
|
72
72
|
|
|
73
|
-
return "
|
|
73
|
+
return { position: "(#{song_i_str}/#{self.size})", title: get(i).info }
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def size
|
data/lib/mikeplayer/settings.rb
CHANGED
|
@@ -16,8 +16,9 @@ module MikePlayer
|
|
|
16
16
|
@music_dir = options[:directory] || File.join(@home, DEFAULT_DIRECTORY)
|
|
17
17
|
@settings_dir = options[:settings] || File.join(@home, SETTINGS_DIRECTORY)
|
|
18
18
|
@minutes = options[:minutes].to_i
|
|
19
|
-
@debug
|
|
20
|
-
@random
|
|
19
|
+
@debug = options[:debug]
|
|
20
|
+
@random = options[:random].to_i
|
|
21
|
+
@fullscreen = options[:fullscreen]
|
|
21
22
|
|
|
22
23
|
if (false == Dir.exist?(@settings_dir))
|
|
23
24
|
Dir.mkdir(@settings_dir)
|
|
@@ -48,6 +49,10 @@ module MikePlayer
|
|
|
48
49
|
return true == @list
|
|
49
50
|
end
|
|
50
51
|
|
|
52
|
+
def fullscreen?
|
|
53
|
+
return true == @fullscreen
|
|
54
|
+
end
|
|
55
|
+
|
|
51
56
|
private
|
|
52
57
|
|
|
53
58
|
def find_playlist(user_option)
|
data/lib/mikeplayer/song.rb
CHANGED
|
@@ -4,12 +4,17 @@ module MikePlayer
|
|
|
4
4
|
|
|
5
5
|
def initialize(filename)
|
|
6
6
|
@filename = filename
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
Mp3Info.open(filename) do |mp3info|
|
|
9
|
+
@artist = mp3info.tag.artist.to_s
|
|
10
|
+
@title = mp3info.tag.title.to_s
|
|
11
|
+
@length = mp3info.length || 0
|
|
12
|
+
end
|
|
8
13
|
end
|
|
9
14
|
|
|
10
15
|
def info
|
|
11
|
-
artist =
|
|
12
|
-
title =
|
|
16
|
+
artist = @artist
|
|
17
|
+
title = @title
|
|
13
18
|
|
|
14
19
|
if (true == artist.empty?) && (true == title.empty?)
|
|
15
20
|
return File.basename(@filename, '.mp3')
|
|
@@ -23,7 +28,7 @@ module MikePlayer
|
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
def length
|
|
26
|
-
return @
|
|
31
|
+
return @length
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
def length_str(elapsed_time)
|
data/lib/mikeplayer/version.rb
CHANGED
data/lib/mikeplayer.rb
CHANGED
|
@@ -27,6 +27,7 @@ module MikePlayer
|
|
|
27
27
|
@timer_start = Time.now if (@minutes > 0)
|
|
28
28
|
@state = STOPPED
|
|
29
29
|
@player = PlayThread.new(volume: @settings.volume)
|
|
30
|
+
@song_mutex = Mutex.new
|
|
30
31
|
|
|
31
32
|
if (true == @settings.list?)
|
|
32
33
|
@songs.map { |song| File.basename(song) }.sort.each {|song| puts "#{File.basename(song)}"}
|
|
@@ -48,8 +49,13 @@ module MikePlayer
|
|
|
48
49
|
def play
|
|
49
50
|
@playlist.shuffle! if @settings.shuffle?
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
if @settings.fullscreen?
|
|
53
|
+
Display.enter_fullscreen
|
|
54
|
+
at_exit { Display.exit_fullscreen }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
puts Display.colorize("Mike Player v#{MikePlayer::VERSION}", Display::BANNER_COLOR)
|
|
58
|
+
puts "#{Display.colorize("Playlist #{@playlist.info}", Display::DIM_COLOR)}\n"
|
|
53
59
|
|
|
54
60
|
if (0 == @playlist.size)
|
|
55
61
|
puts "No songs in playlist."
|
|
@@ -81,6 +87,8 @@ module MikePlayer
|
|
|
81
87
|
if playing? && @player.stopped?
|
|
82
88
|
next_song
|
|
83
89
|
elsif paused?
|
|
90
|
+
@display.display!(song.length_str(@player.elapsed), minutes_remaining)
|
|
91
|
+
|
|
84
92
|
while paused?
|
|
85
93
|
sleep(sleep_time)
|
|
86
94
|
end
|
|
@@ -158,27 +166,35 @@ module MikePlayer
|
|
|
158
166
|
end
|
|
159
167
|
|
|
160
168
|
def next_song
|
|
161
|
-
|
|
169
|
+
@song_mutex.synchronize do
|
|
170
|
+
return if changing?
|
|
162
171
|
|
|
163
|
-
|
|
172
|
+
debug('n')
|
|
164
173
|
|
|
165
|
-
|
|
174
|
+
@state = SONG_CHANGE
|
|
175
|
+
|
|
176
|
+
@player.stop
|
|
166
177
|
|
|
167
|
-
|
|
178
|
+
@song_i += 1
|
|
179
|
+
end
|
|
168
180
|
end
|
|
169
181
|
|
|
170
182
|
def previous_song
|
|
171
|
-
|
|
183
|
+
@song_mutex.synchronize do
|
|
184
|
+
return if changing?
|
|
172
185
|
|
|
173
|
-
|
|
186
|
+
debug('p')
|
|
174
187
|
|
|
175
|
-
|
|
176
|
-
@song_i -= 1 if @song_i.positive?
|
|
177
|
-
else
|
|
178
|
-
debug('x')
|
|
179
|
-
end
|
|
188
|
+
@state = SONG_CHANGE
|
|
180
189
|
|
|
181
|
-
|
|
190
|
+
if (@player.elapsed < 10)
|
|
191
|
+
@song_i -= 1 if @song_i.positive?
|
|
192
|
+
else
|
|
193
|
+
debug('x')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
@player.stop
|
|
197
|
+
end
|
|
182
198
|
end
|
|
183
199
|
|
|
184
200
|
def pause_if_over_time_limit
|
data/mikeplayer.gemspec
CHANGED
|
@@ -34,6 +34,5 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
spec.add_dependency 'json', '~> 2.5'
|
|
35
35
|
spec.add_dependency 'ruby-mp3info', '~> 0.8'
|
|
36
36
|
spec.add_dependency 'minitest', '~> 5'
|
|
37
|
-
spec.add_development_dependency 'rake', '~>
|
|
38
|
-
spec.add_development_dependency 'byebug', '~> 11'
|
|
37
|
+
spec.add_development_dependency 'rake', '~> 13'
|
|
39
38
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mikeplayer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Crockett
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: json
|
|
@@ -58,28 +57,14 @@ dependencies:
|
|
|
58
57
|
requirements:
|
|
59
58
|
- - "~>"
|
|
60
59
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
60
|
+
version: '13'
|
|
62
61
|
type: :development
|
|
63
62
|
prerelease: false
|
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
64
|
requirements:
|
|
66
65
|
- - "~>"
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: byebug
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '11'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '11'
|
|
67
|
+
version: '13'
|
|
83
68
|
description: |
|
|
84
69
|
Wraps Sox's `play` command, allowing playslists, find, random and time limit.
|
|
85
70
|
Once a song is playing you can:
|
|
@@ -113,7 +98,6 @@ homepage: https://github.com/mmcrockett/mikeplayer
|
|
|
113
98
|
licenses:
|
|
114
99
|
- MIT
|
|
115
100
|
metadata: {}
|
|
116
|
-
post_install_message:
|
|
117
101
|
rdoc_options: []
|
|
118
102
|
require_paths:
|
|
119
103
|
- lib
|
|
@@ -128,8 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
128
112
|
- !ruby/object:Gem::Version
|
|
129
113
|
version: '0'
|
|
130
114
|
requirements: []
|
|
131
|
-
rubygems_version: 3.
|
|
132
|
-
signing_key:
|
|
115
|
+
rubygems_version: 3.6.9
|
|
133
116
|
specification_version: 4
|
|
134
117
|
summary: Wraps Sox's `play` command, allowing playslists, find, random and time limit.
|
|
135
118
|
test_files: []
|