partygoer-player 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8de5eedf33fdf8d92d9a529e7e388c2e73fa2f1a
4
+ data.tar.gz: 2203335b57f79b2a9ae9209e0cb71377e6fa8047
5
+ SHA512:
6
+ metadata.gz: ae09b7f31645833b5b3193ad0fdbf34730690de1591169ffd0935faee6152d55e926cee90fc224fd5ba80805554e3a04d7f177137471e1f45faf957fdfedee6f
7
+ data.tar.gz: 587e28e8f27bd002c21b185fb0129b2d22ff200c0732a3a858612e6f676794939d2152a5b41fc682777b589678d2679b6cd6ad2cee7149fd8b2826c96320483e
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ **/.DS_Store
2
+ **/spotify_appkey.key
3
+ **/*.log*
4
+ **/.spotify
5
+ **/config.yml
@@ -0,0 +1,47 @@
1
+ require 'logger'
2
+
3
+ require 'spotify'
4
+
5
+ module Support
6
+ module_function
7
+
8
+ @@logger = Logger.new('support.log', 2, 1_000_000)
9
+ @@logger.formatter = proc do |severity, datetime, _progname, msg|
10
+ "\n\n#{datetime} #{severity}:\n\t#{msg}"
11
+ end
12
+ @@logger.level = Logger::DEBUG
13
+
14
+ DEFAULT_CONFIG = {
15
+ api_version: Spotify::API_VERSION.to_i,
16
+ application_key: File.binread('spotify_appkey.key'),
17
+ cache_location: '.spotify/',
18
+ settings_location: '.spotify/',
19
+ user_agent: 'Partygoer',
20
+ callbacks: Spotify::SessionCallbacks.new
21
+ }
22
+
23
+ def initialize_spotify!(username, password, config = DEFAULT_CONFIG)
24
+ error, session = Spotify.session_create(config)
25
+ raise error if error.is_a?(Spotify::APIError)
26
+
27
+ if Spotify.session_remembered_user(session)
28
+ @@logger.info { "Using remembered login for: #{Spotify.session_remembered_user(session)}." }
29
+ Spotify.try(:session_relogin, session)
30
+ else
31
+ @@logger.info "Attempting login under #{username}."
32
+ Spotify.try(:session_login, session, username, password, true, nil)
33
+ end
34
+
35
+ @@logger.info 'Log in requested. Waiting forever until logged in.'
36
+ until (Spotify.session_connectionstate(session) == :logged_in)
37
+ Spotify.session_process_events(session)
38
+ end
39
+
40
+ at_exit do
41
+ @@logger.info { 'Logging out.' }
42
+ Spotify.session_logout(session)
43
+ Spotify.session_process_events(session) until (Spotify.session_connectionstate(session) != :logged_in )
44
+ end
45
+ session
46
+ end
47
+ end
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'yaml'
5
+ require 'logger'
6
+
7
+ require 'plaything'
8
+ require 'partygoer-client'
9
+
10
+ require_relative 'partygoer-player/support'
11
+
12
+
13
+
14
+ module PartyGoerPlayer
15
+
16
+ @@logger = Logger.new('partygoer-player.log', 2, 1_000_000)
17
+ @@logger.formatter = proc do |severity, datetime, _progname, msg|
18
+ "\n\n#{datetime} #{severity}:\n\t#{msg}"
19
+ end
20
+ @@logger.level = Logger::DEBUG
21
+
22
+ client = PartyGoerClient.new('http://partygoer.io')
23
+
24
+ @@playign = false
25
+
26
+
27
+ def self.play_track(session, uri)
28
+ track = Spotify.link_as_track(Spotify.link_create_from_string(uri))
29
+ Spotify.session_process_events(session) until Spotify.track_is_loaded(track)
30
+
31
+ # Pause before we load a new track. Fixes a quirk in libspotify.
32
+ Spotify.try(:session_player_play, session, false)
33
+ Spotify.try(:session_player_load, session, track)
34
+ Spotify.try(:session_player_play, session, true)
35
+ @@playing = true
36
+ @@logger.info {"Playing next track: #{uri}"}
37
+ rescue
38
+ # Log something
39
+ @@playing = false
40
+ end
41
+
42
+ class FrameReader
43
+ include Enumerable
44
+
45
+ def initialize(channels, sample_type, frames_count, frames_ptr)
46
+ @channels = channels
47
+ @sample_type = sample_type
48
+ @size = frames_count * @channels
49
+ @pointer = FFI::Pointer.new(@sample_type, frames_ptr)
50
+ end
51
+
52
+ attr_reader :size
53
+
54
+ def each
55
+ return enum_for(__method__) unless block_given?
56
+
57
+ ffi_read = :"read_#{@sample_type}"
58
+
59
+ (0...size).each do |index|
60
+ yield @pointer[index].public_send(ffi_read)
61
+ end
62
+ end
63
+ end
64
+
65
+ plaything = Plaything.new
66
+
67
+ $session_callbacks = {
68
+ log_message: proc do |_session, message|
69
+ @@logger.info { "Message from spotify: #{message}" }
70
+ end,
71
+
72
+ logged_in: proc do |_session, error|
73
+ @@logger.debug { "Logged in: #{error}" }
74
+ end,
75
+
76
+ logged_out: proc do |_session|
77
+ @@logger.debug { 'Logged out!' }
78
+ end,
79
+
80
+ streaming_error: proc do |_session, error|
81
+ @@logger.error { "Streaming error #{error.message}" }
82
+ end,
83
+
84
+ connection_error: proc do |_session, error|
85
+ @@logger.error { "Connection error: #{error}" }
86
+ end,
87
+
88
+ play_token_lost: proc do |_session|
89
+ @@logger.error { 'Play token lost. Stopping playback.' }
90
+ plaything.stop
91
+ @@playing = false
92
+ end,
93
+
94
+ streaming_error: proc do |_session, error|
95
+ @@logger.error { "Streaming error #{error}. Stopping playback" }
96
+ plaything.stop
97
+ @@playing = false
98
+ end,
99
+
100
+ start_playback: proc do |_session|
101
+ @@logger.debug { 'Starting playback' }
102
+ plaything.play
103
+ end,
104
+
105
+ stop_playback: proc do |_session|
106
+ @@logger.debug { 'Stopping playback' }
107
+ plaything.stop
108
+ end,
109
+
110
+ get_audio_buffer_stats: proc do |_session, stats|
111
+ stats[:samples] = plaything.queue_size
112
+ stats[:stutter] = plaything.drops
113
+ end,
114
+
115
+ music_delivery: proc do |_session, format, frames, num_frames|
116
+ if num_frames == 0
117
+ @@logger.error { 'Music delivery audio discontuity' }
118
+ plaything.stop
119
+ 0
120
+ else
121
+ @@logger.error { "#{num_frames} frames delivered. #{format.to_h.inspect}" }
122
+ frames = FrameReader.new(
123
+ format[:channels], format[:sample_type], num_frames, frames)
124
+ consumed_frames = plaything.stream(frames, format.to_h)
125
+ consumed_frames
126
+ end
127
+ end,
128
+
129
+ end_of_track: proc do |session|
130
+ @@logger.info { 'End of track' }
131
+ plaything.stop
132
+ if client.up_next
133
+ play_track(session, client.up_next['spotify_uri'])
134
+ client.playing = client.up_next
135
+ @@playing = true
136
+ else
137
+ @@playing = false
138
+ end
139
+ end
140
+ }
141
+
142
+
143
+ Support::DEFAULT_CONFIG[:callbacks] = Spotify::SessionCallbacks.new(
144
+ $session_callbacks)
145
+
146
+ CONFIG = YAML.load_file('config.yml')
147
+
148
+ session = Support.initialize_spotify!(CONFIG['username'], CONFIG['password'])
149
+
150
+ play_track(session, client.playing['spotify_uri']) if client.playing
151
+
152
+ loop do
153
+ Spotify.session_process_events(session)
154
+ if client.skip?
155
+ @@logger.info { 'Skipping track' }
156
+ if client.up_next
157
+ play_track(session, client.up_next['spotify_uri'])
158
+ client.playing = client.up_next
159
+ else
160
+ @@playing = false
161
+ end
162
+ end
163
+ unless @@playing
164
+ @@logger.info { 'Nothing playing, attempting to play next track' }
165
+ if client.up_next
166
+ play_track(session, client.up_next['spotify_uri'])
167
+ client.playing = client.up_next
168
+ else
169
+ @@playing = false
170
+ end
171
+ end
172
+ sleep(0.05)
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: partygoer-player
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Hamon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: spotify
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '12.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '12.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: plaything
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: partygoer-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.4
55
+ description: Uses the spotify gem and partygoer-client to play your partygoer queue
56
+ email: andrew@hamon.cc
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".gitignore"
62
+ - lib/partygoer-player.rb
63
+ - lib/partygoer-player/support.rb
64
+ homepage: http://github.com/andrewhamon/partygoer-player
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.9.2
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.4.2
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Play your partygoer queue!
88
+ test_files: []
89
+ has_rdoc: