ektoplayer 0.1.12 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ektoplayer/application.rb +49 -19
  3. data/lib/ektoplayer/bindings.rb +91 -87
  4. data/lib/ektoplayer/browsepage.rb +14 -27
  5. data/lib/ektoplayer/common.rb +12 -67
  6. data/lib/ektoplayer/compat.rb +5 -11
  7. data/lib/ektoplayer/config.rb +52 -17
  8. data/lib/ektoplayer/controllers/browser.rb +10 -5
  9. data/lib/ektoplayer/database.rb +7 -20
  10. data/lib/ektoplayer/download/externaldownload.rb +65 -0
  11. data/lib/ektoplayer/download/rubydownload.rb +69 -0
  12. data/lib/ektoplayer/icurses/curses.rb +18 -2
  13. data/lib/ektoplayer/icurses/{ffi_ncurses.rb → ffi-ncurses.rb} +1 -0
  14. data/lib/ektoplayer/icurses/ncurses.rb +10 -0
  15. data/lib/ektoplayer/icurses.rb +13 -5
  16. data/lib/ektoplayer/models/browser.rb +11 -11
  17. data/lib/ektoplayer/models/player.rb +4 -5
  18. data/lib/ektoplayer/operations/browser.rb +9 -1
  19. data/lib/ektoplayer/operations/playlist.rb +1 -1
  20. data/lib/ektoplayer/players/mpg_wrapper_player.rb +98 -40
  21. data/lib/ektoplayer/theme.rb +78 -63
  22. data/lib/ektoplayer/trackloader.rb +25 -74
  23. data/lib/ektoplayer/ui/colors.rb +33 -5
  24. data/lib/ektoplayer/ui/widgets/container.rb +1 -1
  25. data/lib/ektoplayer/ui/widgets/listwidget.rb +35 -34
  26. data/lib/ektoplayer/ui/widgets.rb +19 -0
  27. data/lib/ektoplayer/ui.rb +22 -23
  28. data/lib/ektoplayer/updater.rb +3 -4
  29. data/lib/ektoplayer/views/browser.rb +7 -2
  30. data/lib/ektoplayer/views/help.rb +5 -2
  31. data/lib/ektoplayer/views/info.rb +22 -27
  32. data/lib/ektoplayer/views/playinginfo.rb +20 -19
  33. data/lib/ektoplayer/views/playlist.rb +8 -3
  34. data/lib/ektoplayer/views/progressbar.rb +26 -33
  35. data/lib/ektoplayer/views/splash.rb +14 -22
  36. data/lib/ektoplayer/views/trackrenderer.rb +14 -10
  37. metadata +7 -5
@@ -24,12 +24,14 @@ module Ektoplayer
24
24
 
25
25
  def self.parse_simple_format(format)
26
26
  self._parse_markup(format).map do |fmt|
27
- attrs = []
28
- attrs << :bold if fmt[:bold]
29
- attrs << :blink if fmt[:blink]
30
- attrs << :standout if fmt[:standout]
31
- attrs << :underline if fmt[:underline]
32
- fmt[:curses_attrs] = [ (fmt[:fg] and fmt[:fg].to_sym), (fmt[:bg] and fmt[:bg].to_sym), *attrs]
27
+ fmt[:curses_attrs] = [
28
+ (fmt[:fg] and Integer(fmt[:fg]) rescue fmt[:fg].to_sym),
29
+ (fmt[:bg] and Integer(fmt[:bg]) rescue fmt[:bg].to_sym),
30
+ ]
31
+ fmt[:curses_attrs] << :bold if fmt[:bold]
32
+ fmt[:curses_attrs] << :blink if fmt[:blink]
33
+ fmt[:curses_attrs] << :standout if fmt[:standout]
34
+ fmt[:curses_attrs] << :underline if fmt[:underline]
33
35
  fmt
34
36
  end
35
37
  end
@@ -56,14 +58,28 @@ module Ektoplayer
56
58
  <album rel="30" fg="red" />
57
59
  <title rel="33" fg="yellow" />
58
60
  <styles rel="20" fg="cyan" />
59
- <bpm size="4" fg="green" justify="right" />}.squeeze(' ').freeze
61
+ <bpm size="3" fg="green" justify="right" />}.squeeze(' ').freeze
60
62
 
61
- DEFAULT_PLAYINGINFO_FORMAT1 =
63
+ DEFAULT_PLAYINGINFO_FORMAT_TOP =
62
64
  '<text fg="black">&lt;&lt; </text><title bold="on" fg="yellow" /><text fg="black"> &gt;&gt;</text>'.freeze
63
65
 
64
- DEFAULT_PLAYINGINFO_FORMAT2 =
66
+ DEFAULT_PLAYINGINFO_FORMAT_BOTTOM =
65
67
  '<artist bold="on" fg="blue" /><text> - </text><album bold="on" fg="red" /><text> (</text><year fg="cyan" /><text>)</text>'.freeze
66
68
 
69
+ DEFAULT_PLAYLIST_FORMAT_256 = %{
70
+ <number size="3" fg="97" />
71
+ <artist rel="25" fg="24" />
72
+ <album rel="30" fg="160" />
73
+ <title rel="33" fg="178" />
74
+ <styles rel="20" fg="37" />
75
+ <bpm size="3" fg="28" justify="right" />}.squeeze(' ').freeze
76
+
77
+ DEFAULT_PLAYINGINFO_FORMAT_TOP_256 =
78
+ '<text fg="236">&lt;&lt; </text><title bold="on" fg="178" /><text fg="236"> &gt;&gt;</text>'.freeze
79
+
80
+ DEFAULT_PLAYINGINFO_FORMAT_BOTTOM_256 =
81
+ '<artist bold="on" fg="24" /><text> - </text><album bold="on" fg="160" /><text> (</text><year fg="37" /><text>)</text>'.freeze
82
+
67
83
  def register(key, description, default, method=nil)
68
84
  # parameter `description` is used by tools/mkconfig.rb, but not here
69
85
 
@@ -118,7 +134,7 @@ module Ektoplayer
118
134
 
119
135
  reg :playlist_load_newest,
120
136
  %{How many tracks from database should be added to
121
- the playlist on application start.}, 300
137
+ the playlist on application start.}, 1000
122
138
 
123
139
  reg :use_cache,
124
140
  %{Enable/disable local mp3 cache.
@@ -143,12 +159,20 @@ module Ektoplayer
143
159
  'Number of donwload threads during database update',
144
160
  20, lambda { |v| fail if Integer(v) < 1; Integer(v) }
145
161
 
146
- reg 'browser.format', 'Format of browser columns',
162
+ # - Playlist
163
+ reg 'playlist.format', 'Format of playlist columns',
147
164
  DEFAULT_PLAYLIST_FORMAT, ColumnFormat.method(:parse_column_format)
148
165
 
149
- reg 'playlist.format', 'Format of playlist columns',
166
+ reg 'playlist.format_256', 'Format of playlist columns (256 colors)',
167
+ DEFAULT_PLAYLIST_FORMAT_256, ColumnFormat.method(:parse_column_format)
168
+
169
+ # - Browser
170
+ reg 'browser.format', 'Format of browser columns',
150
171
  DEFAULT_PLAYLIST_FORMAT, ColumnFormat.method(:parse_column_format)
151
172
 
173
+ reg 'browser.format_256', 'Format of browser columns (256 colors)',
174
+ DEFAULT_PLAYLIST_FORMAT_256, ColumnFormat.method(:parse_column_format)
175
+
152
176
  # - Progressbar
153
177
  reg 'progressbar.display',
154
178
  'Enable/disable progressbar', true
@@ -163,12 +187,24 @@ module Ektoplayer
163
187
  reg 'playinginfo.display',
164
188
  'Enable/display playinginfo', true
165
189
 
166
- reg 'playinginfo.format1',
167
- 'Format of first line in playinginfo', DEFAULT_PLAYINGINFO_FORMAT1,
190
+ reg 'playinginfo.format_top',
191
+ 'Format of first line in playinginfo',
192
+ DEFAULT_PLAYINGINFO_FORMAT_TOP,
193
+ ColumnFormat.method(:parse_simple_format)
194
+
195
+ reg 'playinginfo.format_top_256',
196
+ 'Format of first line in playinginfo (256 colors)',
197
+ DEFAULT_PLAYINGINFO_FORMAT_TOP_256,
198
+ ColumnFormat.method(:parse_simple_format)
199
+
200
+ reg 'playinginfo.format_bottom',
201
+ 'Format of second line in playinginfo',
202
+ DEFAULT_PLAYINGINFO_FORMAT_BOTTOM,
168
203
  ColumnFormat.method(:parse_simple_format)
169
204
 
170
- reg 'playinginfo.format2',
171
- 'Format of second line in playinginfo', DEFAULT_PLAYINGINFO_FORMAT2,
205
+ reg 'playinginfo.format_bottom_256',
206
+ 'Format of second line in playinginfo (256 colors)',
207
+ DEFAULT_PLAYINGINFO_FORMAT_BOTTOM_256,
172
208
  ColumnFormat.method(:parse_simple_format)
173
209
 
174
210
  # - Tabbar
@@ -232,7 +268,6 @@ module Ektoplayer
232
268
  begin
233
269
  cb = callbacks[command.to_sym]
234
270
  cb.call(*args)
235
- #fail "Command '#{command}' given args: #{args.size}, wanted #{cb.arity}" if args.size != cb.arity
236
271
  rescue
237
272
  fail "#{file}:#{$.}: #{command}: #{$!}"
238
273
  end
@@ -16,19 +16,24 @@ module Ektoplayer
16
16
  each { |op| register.(op, &view.method(op)) }
17
17
 
18
18
  register.(:enter) do
19
- operations.send(:'browser.enter', view.selected)
19
+ selection = view.get_selection
20
+
21
+ operations.send(:'browser.enter', selection[0])
22
+
23
+ if selection.size > 1
24
+ selection[1..-1].each do |index|
25
+ operations.send(:'browser.add_to_playlist', index)
26
+ end
27
+ end
20
28
  end
21
29
 
22
30
  register.(:add_to_playlist) do
23
- #if tracks = browser.tracks(view.selected)
24
31
  view.get_selection.each do |index|
25
32
  operations.send(:'browser.add_to_playlist', index)
26
33
  end
27
- #end
28
34
  end
29
35
 
30
- # TODO: mouse?
31
- view.mouse.on(65536) do view.up(5) end
36
+ view.mouse.on(65536) do view.up(5) end
32
37
  view.mouse.on(2097152) do view.down(5) end
33
38
 
34
39
  [ICurses::BUTTON1_DOUBLE_CLICKED, ICurses::BUTTON3_CLICKED].each do |btn|
@@ -25,12 +25,7 @@ module Ektoplayer
25
25
 
26
26
  a.artist AS album_artist,
27
27
  a.title AS album,
28
- a.released_by AS released_by,
29
- a.released_by_url AS released_by_url,
30
- a.posted_by AS posted_by,
31
- a.posted_by_url AS posted_by_url,
32
28
  a.cover_url AS cover_url,
33
- a.category AS category,
34
29
  a.description AS description,
35
30
  a.date AS date,
36
31
  a.rating AS rating,
@@ -75,12 +70,7 @@ module Ektoplayer
75
70
  url TEXT NOT NULL,
76
71
  title TEXT NOT NULL,
77
72
  artist TEXT,
78
- released_by TEXT,
79
- released_by_url TEXT,
80
- posted_by TEXT,
81
- posted_by_url TEXT,
82
73
  cover_url TEXT,
83
- category TEXT,
84
74
  description TEXT,
85
75
  date DATE,
86
76
  rating FLOAT NOT NULL DEFAULT -1,
@@ -144,10 +134,8 @@ module Ektoplayer
144
134
  insert_into(table, hash, mode: :replace)
145
135
  end
146
136
 
147
- def execute(query, params=nil)
148
- stm = @db.prepare query
149
- stm.bind_params(*params) if params
150
- stm.execute.to_a
137
+ def execute(query, params=[])
138
+ @db.execute(query, *params)
151
139
  rescue
152
140
  Application.log(self, $!)
153
141
  end
@@ -156,7 +144,7 @@ module Ektoplayer
156
144
  columns: ?*,
157
145
  filters: [],
158
146
  group_by: 'url',
159
- order_by: 'album, number',
147
+ order_by: 'album,number',
160
148
  limit: nil
161
149
  )
162
150
  where_clauses, where_params = [], []
@@ -182,7 +170,7 @@ module Ektoplayer
182
170
 
183
171
  limit = "LIMIT #{limit}" if limit
184
172
 
185
- stm = @db.prepare SELECT % {
173
+ query = SELECT % {
186
174
  SELECT_COLUMNS: columns,
187
175
  WHERE: where_clauses.join(' '),
188
176
  GROUP_BY: group_by,
@@ -190,8 +178,7 @@ module Ektoplayer
190
178
  LIMIT: limit
191
179
  }
192
180
 
193
- stm.bind_params(*where_params)
194
- stm.execute.to_a
181
+ @db.execute(query, *where_params)
195
182
  rescue
196
183
  Application.log(self, $!)
197
184
  end
@@ -201,11 +188,11 @@ module Ektoplayer
201
188
  end
202
189
 
203
190
  def track_count
204
- @db.execute('SELECT COUNT(*) FROM tracks')[0][0]
191
+ @db.get_first_value('SELECT COUNT(*) FROM tracks')
205
192
  end
206
193
 
207
194
  def album_count
208
- @db.execute('SELECT COUNT(*) FROM albums')[0][0]
195
+ @db.get_first_value('SELECT COUNT(*) FROM albums')
209
196
  end
210
197
  end
211
198
  end
@@ -0,0 +1,65 @@
1
+ require 'open3'
2
+ require 'uri'
3
+
4
+ require_relative '../events'
5
+
6
+ class ExternalDownload
7
+ attr_reader :events, :url, :progress, :filename, :error
8
+
9
+ def initialize(url, filename)
10
+ @events = Events.new(:completed, :failed)
11
+ @url = URI.parse(url)
12
+ @filename = filename
13
+ @progress = 0
14
+ @error = nil
15
+ @tries = 3
16
+ end
17
+
18
+ def self.get_wget_cmd(url, file)
19
+ %w(wget -nv --show-progress --progress=dot:binary -O) + [file, url]
20
+ end
21
+
22
+ def self.get_curl_cmd(url, file)
23
+ %w(curl -# -o) + [file, url]
24
+ end
25
+
26
+ def start!
27
+ Thread.new do
28
+ args = CMD.(@url.to_s, @filename)
29
+ dl_in, dl_out, dl_err, @dl_proc = Open3.popen3(*args)
30
+
31
+ begin
32
+ while (line = dl_err.readpartial(1024))
33
+ @last_line = line
34
+
35
+ if (progress = line.scan(/(\d+(\.\d+)?%)/)[0][0].delete(?%).to_f rescue nil)
36
+ @progress = progress
37
+ end
38
+ end
39
+ rescue
40
+ nil
41
+ end
42
+
43
+ begin
44
+ @dl_proc.join
45
+ raise if @dl_proc.value.exitstatus > 0
46
+ @progress = 100.0
47
+ @events.trigger(:completed)
48
+ rescue
49
+ @events.trigger(:failed, (@error = @last_line))
50
+ end
51
+ end
52
+
53
+ sleep 0.1 while @dl_proc.nil?
54
+ sleep 0.2
55
+ self
56
+ end
57
+
58
+ if system('wget --version >/dev/null 2>/dev/null')
59
+ CMD = method :get_wget_cmd
60
+ elsif system('curl --version >/dev/null 2>/dev/null')
61
+ CMD = method :get_curl_cmd
62
+ else
63
+ fail LoadError, 'wget/curl not installed'
64
+ end
65
+ end
@@ -0,0 +1,69 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+
4
+ require_relative '../events'
5
+
6
+ class RubyDownload
7
+ attr_reader :events, :url, :filename, :error
8
+
9
+ def initialize(url, filename)
10
+ @events = Events.new(:completed, :failed)
11
+ @url = URI.parse(url)
12
+ @filename = filename
13
+ @bytes_read = 0
14
+ @error, @total = nil, nil
15
+ @tries = 3
16
+ end
17
+
18
+ def progress
19
+ (@bytes_read.to_f / @total * 100) rescue 0).clamp(0, 100).to_f
20
+ end
21
+
22
+ def start!
23
+ Thread.new do
24
+ success = false
25
+
26
+ @tries.times do |try|
27
+ begin
28
+ do_download
29
+ @events.trigger(:completed)
30
+ success = true
31
+ break
32
+ rescue
33
+ @_lasterror = $!
34
+ sleep 3
35
+ end
36
+ end
37
+
38
+ unless success
39
+ @events.trigger(:failed, @_lasterror)
40
+ end
41
+ end
42
+
43
+ sleep 0.1 while @total.nil?
44
+ sleep 0.2
45
+ self
46
+ end
47
+
48
+ private def do_download
49
+ @file = File.open(filename, ?w)
50
+ @bytes_read, @total, @error = 0, nil, nil
51
+
52
+ http = Net::HTTP.new(@url.host, @url.port)
53
+
54
+ http.request(Net::HTTP::Get.new(@url.request_uri)) do |res|
55
+ fail res.body unless res.code == '200'
56
+
57
+ @total = res.header['Content-Length'].to_i
58
+
59
+ res.read_body do |chunk|
60
+ @bytes_read += chunk.size
61
+ @file << chunk
62
+ end
63
+ end
64
+
65
+ fail 'filesize mismatch' if @bytes_read != @total
66
+ ensure
67
+ (@file.close rescue nil) if @file
68
+ end
69
+ end
@@ -17,10 +17,25 @@ module Curses
17
17
  alias_method :"get#{method}", method.to_sym
18
18
  end
19
19
 
20
+ def leaveok(*_); end # Curses does not
21
+ def notimeout(*_); end # provide these functions
22
+
20
23
  alias :timeout :timeout=
21
- alias :notimeout :nodelay= #todo
22
24
  alias :nodelay :nodelay=
23
25
 
26
+ def bkgd(attr)
27
+ @bkgd_color = attr
28
+ end
29
+ alias :bkgdset :bkgd
30
+
31
+ def erase
32
+ setpos(0, 0)
33
+ attrset((@bkgd_color or 0))
34
+ addstr(' ' * (maxx * maxy))
35
+ attroff((@bkgd_color or 0))
36
+ setpos(0, 0)
37
+ end
38
+
24
39
  alias :mvwin :move # 'fix' this Gem
25
40
  def move(y, x)
26
41
  setpos(y, x)
@@ -28,7 +43,8 @@ module Curses
28
43
  end
29
44
 
30
45
  class Pad < Window
31
- alias :pnoutrefresh :refresh
46
+ alias :pnoutrefresh :noutrefresh
47
+ alias :prefresh :refresh
32
48
  end
33
49
  end
34
50
 
@@ -55,6 +55,7 @@ module FFI::NCurses
55
55
  end
56
56
 
57
57
  %w(getcurx getcury getmaxx getmaxy getbegx getbegy
58
+ clearok idlok idcok immedok leaveok setscrreg scrollok nl nonl
58
59
  keypad nodelay notimeout prefresh pnoutrefresh).each do |meth|
59
60
 
60
61
  define_method(meth) do |*args|
@@ -17,6 +17,7 @@ module Ncurses
17
17
  end
18
18
 
19
19
  %w(getcurx getcury getmaxx getmaxy getbegx getbegy
20
+ clearok idlok idcok immedok leaveok setscrreg scrollok nl nonl
20
21
  keypad nodelay notimeout prefresh pnoutrefresh).each do |meth|
21
22
  define_method(meth) do |*args|
22
23
  Ncurses.send(meth, @w, *args)
@@ -36,6 +37,15 @@ module Ncurses
36
37
  end
37
38
  end
38
39
  end
40
+
41
+ if $USING_CURSES == 'ncurses'
42
+ ### FIX: 'attrset' in ncurses is broken!
43
+ def attrset(attributes)
44
+ Ncurses.send(:wattr_get, @w, old_a=[], old_c=[], nil)
45
+ Ncurses.send(:wattroff, @w, old_a[0] | old_c[0])
46
+ Ncurses.send(:wattron, @w, attributes)
47
+ end
48
+ end
39
49
  end
40
50
  end
41
51
 
@@ -9,13 +9,21 @@
9
9
  end
10
10
 
11
11
  fail %{
12
- No interface for ncurses found. Please install one of the following gems
13
- - curses
14
- - ffi-ncurses
15
- - ncurses-ruby
16
- - ncursesw
12
+ No module for ncurses found. Please install one of the following gems:
13
+ - ffi-ncurses (preferred)
14
+ - ncursesw (good)
15
+ - ncurses-ruby (good)
16
+ - curses (works...)
17
17
 
18
18
  Maybe your distribution ships one of these already as a package.
19
+
20
+ Arch Linux:
21
+ yaourt -S ruby-curses # or
22
+ yaourt -S ruby-ncursesw
23
+
24
+ Debian / Ubuntu:
25
+ apt-get install ruby-ncurses
26
+
19
27
  } unless $USING_CURSES
20
28
 
21
29
  require_relative 'icurses/sugar'
@@ -6,13 +6,11 @@ module Ektoplayer
6
6
  PARENT_DIRECTORY = '..'.freeze
7
7
 
8
8
  PATHS = {
9
- artist: [:artist ].freeze,
10
- album: [:album ].freeze,
11
- style: [:style ].freeze,
12
- year: [:year ].freeze,
13
- title: [].freeze,
14
- released_by: [:released_by].freeze,
15
- posted_by: [:posted_by ].freeze
9
+ artist: [:artist].freeze,
10
+ album: [:album ].freeze,
11
+ style: [:style ].freeze,
12
+ year: [:year ].freeze,
13
+ title: [].freeze
16
14
  }.freeze
17
15
 
18
16
  def initialize(client)
@@ -36,16 +34,18 @@ module Ektoplayer
36
34
  end
37
35
 
38
36
  def enter(index)
39
- return unless (sub = current.enter(index))
37
+ return false unless (sub = current.enter(index))
40
38
  return back() if sub == :parent
41
39
  @stack.push(sub)
42
40
  @events.trigger(:changed)
41
+ true
43
42
  end
44
43
 
45
44
  def back
46
- return unless @stack.size > 1
45
+ return false unless @stack.size > 1
47
46
  @stack.pop
48
47
  @events.trigger(:changed)
48
+ true
49
49
  end
50
50
 
51
51
  class BrowsableCollection
@@ -91,7 +91,7 @@ module Ektoplayer
91
91
  return [] if index == 0
92
92
  return [ @contents[index] ]
93
93
  else
94
- @database.select(filters: new_filters(index)).map.to_a
94
+ @database.select(filters: new_filters(index))
95
95
  end
96
96
  end
97
97
 
@@ -121,7 +121,7 @@ module Ektoplayer
121
121
 
122
122
  def tracks(index)
123
123
  @database.select(
124
- order_by: CONTENTS[index].to_s + ",album,year,number".sub(",#{CONTENTS[index]}", '')
124
+ order_by: 'album,' + CONTENTS[index].to_s + ",album,number"
125
125
  )
126
126
  end
127
127
  end
@@ -8,11 +8,12 @@ module Ektoplayer
8
8
  super()
9
9
  @client = client
10
10
  @player = MpgWrapperPlayer.new
11
- @events.register(:position_change, :track_completed, :pause, :stop, :play)
12
- @player.events.on_all(&@events.method(:trigger))
11
+ @events = @player.events
12
+ #@events.register(:position_change, :track_completed, :pause, :stop, :play)
13
+ #@player.events.on_all(&@events.method(:trigger))
13
14
 
14
15
  %w(pause toggle stop forward backward seek
15
- length position position_percent level).each do |m|
16
+ length position position_percent can_http?).each do |m|
16
17
  self.define_singleton_method(m, &@player.method(m))
17
18
  end
18
19
  end
@@ -21,8 +22,6 @@ module Ektoplayer
21
22
  Application.log(self, 'playing', file)
22
23
  @player.play(file) rescue Application.log(self, $!)
23
24
  end
24
-
25
- def close; @player.close end
26
25
  end
27
26
  end
28
27
  end
@@ -7,8 +7,16 @@ module Ektoplayer
7
7
  # +add_to_playlist+:: see
8
8
  def initialize(operations, browser, playlist)
9
9
  register = operations.with_register('browser.')
10
- register.(:enter, &browser.method(:enter))
11
10
  register.(:back, &browser.method(:back))
11
+
12
+ register.(:enter) do |index|
13
+ unless browser.enter(index)
14
+ tracks = browser.tracks(index)
15
+ playlist.add(*tracks)
16
+ operations.send(:'playlist.play', playlist.size - tracks.size)
17
+ end
18
+ end
19
+
12
20
  register.(:add_to_playlist) do |index|
13
21
  tracks = browser.tracks(index)
14
22
  playlist.add(*tracks)
@@ -35,7 +35,7 @@ module Ektoplayer
35
35
  return unless track = @playlist[index]
36
36
  @playlist.current_playing=(index)
37
37
  Thread.new do
38
- @player.play(@trackloader.get_track_file(track['url']))
38
+ @player.play(@trackloader.get_track_file(track['url'], http_okay: @player.can_http?))
39
39
  end.join(0.3) # prevent too many hits
40
40
  end
41
41