spotify 12.0.3 → 12.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,3 @@
1
1
  rvm:
2
- - 1.8.7
3
2
  - 1.9.2
4
3
  - 1.9.3
@@ -1,3 +1,7 @@
1
+ [v12.2.0][]
2
+ -----------
3
+ - fix SessionConfig missing ca_certs_filename struct field on Linux
4
+
1
5
  __v12.1.0__
2
6
  -----------
3
7
  - erroneously released (wrong version number, does not follow version policy)
@@ -126,6 +130,7 @@ v0.0.0
126
130
  ------
127
131
  - release to register rubygems.org name
128
132
 
133
+ [v12.2.0]: https://github.com/Burgestrand/libspotify-ruby/compare/v12.0.3...v12.2.0
129
134
  [v12.0.3]: https://github.com/Burgestrand/libspotify-ruby/compare/v12.0.2...v12.0.3
130
135
  [v12.0.2]: https://github.com/Burgestrand/libspotify-ruby/compare/v12.0.1...v12.0.2
131
136
  [v12.0.1]: https://github.com/Burgestrand/libspotify-ruby/compare/v12.0.0...v12.0.1
data/Rakefile CHANGED
@@ -5,10 +5,6 @@ rescue LoadError
5
5
  # do not require bundler rake tasks
6
6
  end
7
7
 
8
- require 'rake/testtask'
9
- Rake::TestTask.new do |spec|
10
- spec.pattern = 'spec/*_spec.rb'
11
- end
12
8
 
13
9
  require 'yard'
14
10
  YARD::Rake::YardocTask.new
@@ -22,5 +18,16 @@ task :console do
22
18
  exec "irb", "-Ilib", "-rspotify"
23
19
  end
24
20
 
25
- task :spec => :test
26
- task :default => :test
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test_mac) do |spec|
23
+ spec.pattern = 'spec/*_spec.rb'
24
+ spec.ruby_opts = ['-r ./spec/mac-platform']
25
+ end
26
+
27
+ Rake::TestTask.new(:test_linux) do |spec|
28
+ spec.pattern = 'spec/*_spec.rb'
29
+ spec.ruby_opts = ['-r ./spec/linux-platform']
30
+ end
31
+
32
+ desc "Run the tests for both Linux and Mac OS"
33
+ task :default => [:test_mac, :test_linux]
@@ -22,31 +22,52 @@ module Spotify
22
22
  raise
23
23
  end
24
24
 
25
- # Fetches the associated value of an enum from a given symbol.
26
- #
27
- # @example retrieving a value
28
- # Spotify.enum_value!(:ok, "error value") # => 0
29
- #
30
- # @example failing to retrieve a value
31
- # Spotify.enum_value!(:moo, "connection rule") # => ArgumentError, invalid connection rule: :moo
32
- #
33
- # @param [Symbol] symbol
34
- # @param [#to_s] type used as error message when the symbol does not resolve
35
- # @raise ArgumentError on failure
36
- def self.enum_value!(symbol, type)
37
- enum_value(symbol) or raise ArgumentError, "invalid #{type}: #{symbol}"
38
- end
25
+ class << self
26
+ # Fetches the associated value of an enum from a given symbol.
27
+ #
28
+ # @example retrieving a value
29
+ # Spotify.enum_value!(:ok, "error value") # => 0
30
+ #
31
+ # @example failing to retrieve a value
32
+ # Spotify.enum_value!(:moo, "connection rule") # => ArgumentError, invalid connection rule: :moo
33
+ #
34
+ # @param [Symbol] symbol
35
+ # @param [#to_s] type used as error message when the symbol does not resolve
36
+ # @raise ArgumentError on failure
37
+ def enum_value!(symbol, type)
38
+ enum_value(symbol) or raise ArgumentError, "invalid #{type}: #{symbol}"
39
+ end
39
40
 
40
- # Override FFI::Library#attach_function to always add the `:blocking` option.
41
- #
42
- # The reason for this is that which libspotify functions may call callbacks
43
- # is unspecified. And really… I don’t know of any drawbacks with this method.
44
- def self.attach_function(*arguments, &block)
45
- options = arguments.pop if arguments.last.is_a?(Hash)
46
- options ||= {}
47
- options = { :blocking => true }.merge(options)
48
- arguments << options
49
- super(*arguments, &block)
41
+ # Override FFI::Library#attach_function to always add the `:blocking` option.
42
+ #
43
+ # The reason for this is that which libspotify functions may call callbacks
44
+ # is unspecified. And really… I don’t know of any drawbacks with this method.
45
+ def attach_function(*arguments, &block)
46
+ options = arguments.pop if arguments.last.is_a?(Hash)
47
+ options ||= {}
48
+ options = { :blocking => true }.merge(options)
49
+ arguments << options
50
+ super(*arguments, &block)
51
+ end
52
+
53
+ # @return [Boolean] true if on Linux
54
+ def linux?
55
+ platform == :linux
56
+ end
57
+
58
+ # @return [Boolean] true if on Mac OS
59
+ def mac?
60
+ platform == :mac
61
+ end
62
+
63
+ # @return [Symbol] platform as either :mac or :linux
64
+ def platform
65
+ case RUBY_PLATFORM
66
+ when /darwin/ then :mac
67
+ when /linux/ then :linux
68
+ else :unknown
69
+ end
70
+ end
50
71
  end
51
72
 
52
73
  # libspotify API version
@@ -133,9 +154,9 @@ module Spotify
133
154
  # @attr [Fixnum] sample_rate
134
155
  # @attr [Fixnum] channels
135
156
  class AudioFormat < FFI::Struct
136
- layout :sample_type, :sampletype,
137
- :sample_rate, :int,
138
- :channels, :int
157
+ layout :sample_type => :sampletype,
158
+ :sample_rate => :int,
159
+ :channels => :int
139
160
  end
140
161
 
141
162
  # FFI::Struct for Audio Buffer Stats.
@@ -143,8 +164,8 @@ module Spotify
143
164
  # @attr [Fixnum] samples
144
165
  # @attr [Fixnum] stutter
145
166
  class AudioBufferStats < FFI::Struct
146
- layout :samples, :int,
147
- :stutter, :int
167
+ layout :samples => :int,
168
+ :stutter => :int
148
169
  end
149
170
 
150
171
  #
@@ -171,27 +192,27 @@ module Spotify
171
192
  # @attr [callback(:session, AudioBufferStats):void] get_audio_buffer_stats
172
193
  # @attr [callback(:session)::void] offline_status_updated
173
194
  class SessionCallbacks < FFI::Struct
174
- layout :logged_in, callback([ :session, :error ], :void),
175
- :logged_out, callback([ :session ], :void),
176
- :metadata_updated, callback([ :session ], :void),
177
- :connection_error, callback([ :session, :error ], :void),
178
- :message_to_user, callback([ :session, :utf8_string ], :void),
179
- :notify_main_thread, callback([ :session ], :void),
180
- :music_delivery, callback([ :session, AudioFormat, :frames, :int ], :int),
181
- :play_token_lost, callback([ :session ], :void),
182
- :log_message, callback([ :session, :utf8_string ], :void),
183
- :end_of_track, callback([ :session ], :void),
184
- :streaming_error, callback([ :session, :error ], :void),
185
- :userinfo_updated, callback([ :session ], :void),
186
- :start_playback, callback([ :session ], :void),
187
- :stop_playback, callback([ :session ], :void),
188
- :get_audio_buffer_stats, callback([ :session, AudioBufferStats ], :void),
189
- :offline_status_updated, callback([ :session ], :void),
190
- :offline_error, callback([ :session, :error ], :void),
191
- :credentials_blob_updated, callback([ :session, :string ], :void),
192
- :connectionstate_updated, callback([ :session ], :void),
193
- :scrobble_error, callback([ :session, :error ], :void),
194
- :private_session_mode_changed, callback([ :session, :bool ], :void)
195
+ layout :logged_in => callback([ :session, :error ], :void),
196
+ :logged_out => callback([ :session ], :void),
197
+ :metadata_updated => callback([ :session ], :void),
198
+ :connection_error => callback([ :session, :error ], :void),
199
+ :message_to_user => callback([ :session, :utf8_string ], :void),
200
+ :notify_main_thread => callback([ :session ], :void),
201
+ :music_delivery => callback([ :session, AudioFormat, :frames, :int ], :int),
202
+ :play_token_lost => callback([ :session ], :void),
203
+ :log_message => callback([ :session, :utf8_string ], :void),
204
+ :end_of_track => callback([ :session ], :void),
205
+ :streaming_error => callback([ :session, :error ], :void),
206
+ :userinfo_updated => callback([ :session ], :void),
207
+ :start_playback => callback([ :session ], :void),
208
+ :stop_playback => callback([ :session ], :void),
209
+ :get_audio_buffer_stats => callback([ :session, AudioBufferStats ], :void),
210
+ :offline_status_updated => callback([ :session ], :void),
211
+ :offline_error => callback([ :session, :error ], :void),
212
+ :credentials_blob_updated => callback([ :session, :string ], :void),
213
+ :connectionstate_updated => callback([ :session ], :void),
214
+ :scrobble_error => callback([ :session, :error ], :void),
215
+ :private_session_mode_changed => callback([ :session, :bool ], :void)
195
216
  end
196
217
 
197
218
  # FFI::Struct for Session configuration.
@@ -206,22 +227,25 @@ module Spotify
206
227
  # @attr [Fixnum] dont_save_metadata_for_playlists
207
228
  # @attr [Fixnum] initially_unload_playlists
208
229
  class SessionConfig < FFI::Struct
209
- layout :api_version, :int,
210
- :cache_location, :string_pointer,
211
- :settings_location, :string_pointer,
212
- :application_key, :pointer,
213
- :application_key_size, :size_t,
214
- :user_agent, :string_pointer,
215
- :callbacks, SessionCallbacks.by_ref,
216
- :userdata, :userdata,
217
- :compress_playlists, :bool,
218
- :dont_save_metadata_for_playlists, :bool,
219
- :initially_unload_playlists, :bool,
220
- :device_id, :string_pointer,
221
- :proxy, :string_pointer,
222
- :proxy_username, :string_pointer,
223
- :proxy_password, :string_pointer,
224
- :tracefile, :string_pointer
230
+ it = {}
231
+ it[:api_version] = :int
232
+ it[:cache_location] = :string_pointer
233
+ it[:settings_location] = :string_pointer
234
+ it[:application_key] = :pointer
235
+ it[:application_key_size] = :size_t
236
+ it[:user_agent] = :string_pointer
237
+ it[:callbacks] = SessionCallbacks.by_ref
238
+ it[:userdata] = :userdata
239
+ it[:compress_playlists] = :bool
240
+ it[:dont_save_metadata_for_playlists] = :bool
241
+ it[:initially_unload_playlists] = :bool
242
+ it[:device_id] = :string_pointer
243
+ it[:proxy] = :string_pointer
244
+ it[:proxy_username] = :string_pointer
245
+ it[:proxy_password] = :string_pointer
246
+ it[:ca_certs_filename] = :string_pointer if Spotify.linux?
247
+ it[:tracefile] = :string_pointer
248
+ layout(it)
225
249
  end
226
250
 
227
251
  # FFI::Struct for Offline Sync Status
@@ -236,15 +260,15 @@ module Spotify
236
260
  # @attr [Fixnum] error_tracks
237
261
  # @attr [Fixnum] syncing
238
262
  class OfflineSyncStatus < FFI::Struct
239
- layout :queued_tracks, :int,
240
- :queued_bytes, :uint64,
241
- :done_tracks, :int,
242
- :done_bytes, :uint64,
243
- :copied_tracks, :int,
244
- :copied_bytes, :uint64,
245
- :willnotcopy_tracks, :int,
246
- :error_tracks, :int,
247
- :syncing, :bool
263
+ layout :queued_tracks => :int,
264
+ :queued_bytes => :uint64,
265
+ :done_tracks => :int,
266
+ :done_bytes => :uint64,
267
+ :copied_tracks => :int,
268
+ :copied_bytes => :uint64,
269
+ :willnotcopy_tracks => :int,
270
+ :error_tracks => :int,
271
+ :syncing => :bool
248
272
  end
249
273
 
250
274
  #
@@ -542,19 +566,19 @@ module Spotify
542
566
  # @attr [callback(:playlist, :int, :utf8_string, :userdata):void] track_message_changed
543
567
  # @attr [callback(:playlist, :userdata):void] subscribers_changed
544
568
  class PlaylistCallbacks < FFI::Struct
545
- layout :tracks_added, callback([ :playlist, :array, :int, :int, :userdata ], :void),
546
- :tracks_removed, callback([ :playlist, :array, :int, :userdata ], :void),
547
- :tracks_moved, callback([ :playlist, :array, :int, :int, :userdata ], :void),
548
- :playlist_renamed, callback([ :playlist, :userdata ], :void),
549
- :playlist_state_changed, callback([ :playlist, :userdata ], :void),
550
- :playlist_update_in_progress, callback([ :playlist, :bool, :userdata ], :void),
551
- :playlist_metadata_updated, callback([ :playlist, :userdata ], :void),
552
- :track_created_changed, callback([ :playlist, :int, :user, :int, :userdata ], :void),
553
- :track_seen_changed, callback([ :playlist, :int, :bool, :userdata ], :void),
554
- :description_changed, callback([ :playlist, :utf8_string, :userdata ], :void),
555
- :image_changed, callback([ :playlist, :image_id, :userdata ], :void),
556
- :track_message_changed, callback([ :playlist, :int, :utf8_string, :userdata ], :void),
557
- :subscribers_changed, callback([ :playlist, :userdata ], :void)
569
+ layout :tracks_added => callback([ :playlist, :array, :int, :int, :userdata ], :void),
570
+ :tracks_removed => callback([ :playlist, :array, :int, :userdata ], :void),
571
+ :tracks_moved => callback([ :playlist, :array, :int, :int, :userdata ], :void),
572
+ :playlist_renamed => callback([ :playlist, :userdata ], :void),
573
+ :playlist_state_changed => callback([ :playlist, :userdata ], :void),
574
+ :playlist_update_in_progress => callback([ :playlist, :bool, :userdata ], :void),
575
+ :playlist_metadata_updated => callback([ :playlist, :userdata ], :void),
576
+ :track_created_changed => callback([ :playlist, :int, :user, :int, :userdata ], :void),
577
+ :track_seen_changed => callback([ :playlist, :int, :bool, :userdata ], :void),
578
+ :description_changed => callback([ :playlist, :utf8_string, :userdata ], :void),
579
+ :image_changed => callback([ :playlist, :image_id, :userdata ], :void),
580
+ :track_message_changed => callback([ :playlist, :int, :utf8_string, :userdata ], :void),
581
+ :subscribers_changed => callback([ :playlist, :userdata ], :void)
558
582
  end
559
583
 
560
584
  # FFI::Struct for Subscribers of a Playlist.
@@ -562,8 +586,8 @@ module Spotify
562
586
  # @attr [Fixnum] count
563
587
  # @attr [Array<Pointer<String>>] subscribers
564
588
  class Subscribers < FFI::Struct
565
- layout :count, :uint,
566
- :subscribers, [:pointer, 1] # array of pointers to strings
589
+ layout :count => :uint,
590
+ :subscribers => [:pointer, 1] # array of pointers to strings
567
591
 
568
592
  # Redefined, as the layout of the Struct can only be determined
569
593
  # at run-time.
@@ -1,5 +1,3 @@
1
- require 'set'
2
-
3
1
  module Spotify
4
2
  # The Pointer is a kind of AutoPointer specially tailored for Spotify
5
3
  # objects, that releases the raw pointer on GC.
@@ -1,4 +1,4 @@
1
1
  module Spotify
2
2
  # See README for versioning policy.
3
- VERSION = [12, 0, 3].join('.')
3
+ VERSION = [12, 2, 0].join('.')
4
4
  end
@@ -0,0 +1,3966 @@
1
+ /*
2
+ * Copyright (c) 2006-2012 Spotify Ltd
3
+ *
4
+ * The terms of use for this and related files can be read in
5
+ * the associated LICENSE file, usually stored in share/doc/libspotify/LICENSE.
6
+ */
7
+
8
+ /**
9
+ * @file api.h Public API for libspotify
10
+ *
11
+ * @note All input strings are expected to be in UTF-8
12
+ * @note All output strings are in UTF-8.
13
+ *
14
+ * @note All usernames are valid XMPP nodeprep identifiers:
15
+ * http://tools.ietf.org/html/rfc3920#appendix-A
16
+ * If you need to store user data, we strongly advise you
17
+ * to use the canonical form of the username.
18
+ */
19
+
20
+ #ifndef PUBLIC_API_H
21
+ #define PUBLIC_API_H
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ #ifndef SP_CALLCONV
28
+ #ifdef _WIN32
29
+ #define SP_CALLCONV __stdcall
30
+ #else
31
+ #define SP_CALLCONV
32
+ #endif
33
+ #endif
34
+
35
+ #ifndef SP_LIBEXPORT
36
+ #ifdef _WIN32
37
+ #define SP_LIBEXPORT(x) x __stdcall
38
+ #else
39
+ #define SP_LIBEXPORT(x) x
40
+ #endif
41
+ #endif
42
+
43
+ /* Includes */
44
+ #include <stddef.h>
45
+
46
+ #ifdef _WIN32
47
+ typedef unsigned __int64 sp_uint64;
48
+ #else
49
+ #include <stdint.h>
50
+ typedef uint64_t sp_uint64;
51
+ #endif
52
+
53
+ /* General types */
54
+
55
+ #if !defined(__cplusplus) && !defined(__bool_true_false_are_defined)
56
+ typedef unsigned char bool;
57
+ #endif
58
+
59
+ typedef unsigned char byte;
60
+
61
+ /**
62
+ * @defgroup types Spotify types & structs
63
+ *
64
+ * @{
65
+ */
66
+
67
+ typedef struct sp_session sp_session; ///< Representation of a session
68
+ typedef struct sp_track sp_track; ///< A track handle
69
+ typedef struct sp_album sp_album; ///< An album handle
70
+ typedef struct sp_artist sp_artist; ///< An artist handle
71
+ typedef struct sp_artistbrowse sp_artistbrowse; ///< A handle to an artist browse result
72
+ typedef struct sp_albumbrowse sp_albumbrowse; ///< A handle to an album browse result
73
+ typedef struct sp_toplistbrowse sp_toplistbrowse; ///< A handle to a toplist browse result
74
+ typedef struct sp_search sp_search; ///< A handle to a search result
75
+ typedef struct sp_link sp_link; ///< A handle to the libspotify internal representation of a URI
76
+ typedef struct sp_image sp_image; ///< A handle to an image
77
+ typedef struct sp_user sp_user; ///< A handle to a user
78
+ typedef struct sp_playlist sp_playlist; ///< A playlist handle
79
+ typedef struct sp_playlistcontainer sp_playlistcontainer; ///< A playlist container (playlist containing other playlists) handle
80
+ typedef struct sp_inbox sp_inbox; ///< Add to inbox request handle
81
+ /** @} */
82
+
83
+ /**
84
+ * @defgroup error Error Handling
85
+ *
86
+ * All functions in libspotify use the same set of error codes. Most of them return
87
+ * an error code, and let the result of the operation be stored in an out-parameter.
88
+ *
89
+ * @{
90
+ */
91
+
92
+ /**
93
+ * Error codes returned by various functions
94
+ */
95
+ typedef enum sp_error {
96
+ SP_ERROR_OK = 0, ///< No errors encountered
97
+ SP_ERROR_BAD_API_VERSION = 1, ///< The library version targeted does not match the one you claim you support
98
+ SP_ERROR_API_INITIALIZATION_FAILED = 2, ///< Initialization of library failed - are cache locations etc. valid?
99
+ SP_ERROR_TRACK_NOT_PLAYABLE = 3, ///< The track specified for playing cannot be played
100
+ SP_ERROR_BAD_APPLICATION_KEY = 5, ///< The application key is invalid
101
+ SP_ERROR_BAD_USERNAME_OR_PASSWORD = 6, ///< Login failed because of bad username and/or password
102
+ SP_ERROR_USER_BANNED = 7, ///< The specified username is banned
103
+ SP_ERROR_UNABLE_TO_CONTACT_SERVER = 8, ///< Cannot connect to the Spotify backend system
104
+ SP_ERROR_CLIENT_TOO_OLD = 9, ///< Client is too old, library will need to be updated
105
+ SP_ERROR_OTHER_PERMANENT = 10, ///< Some other error occurred, and it is permanent (e.g. trying to relogin will not help)
106
+ SP_ERROR_BAD_USER_AGENT = 11, ///< The user agent string is invalid or too long
107
+ SP_ERROR_MISSING_CALLBACK = 12, ///< No valid callback registered to handle events
108
+ SP_ERROR_INVALID_INDATA = 13, ///< Input data was either missing or invalid
109
+ SP_ERROR_INDEX_OUT_OF_RANGE = 14, ///< Index out of range
110
+ SP_ERROR_USER_NEEDS_PREMIUM = 15, ///< The specified user needs a premium account
111
+ SP_ERROR_OTHER_TRANSIENT = 16, ///< A transient error occurred.
112
+ SP_ERROR_IS_LOADING = 17, ///< The resource is currently loading
113
+ SP_ERROR_NO_STREAM_AVAILABLE = 18, ///< Could not find any suitable stream to play
114
+ SP_ERROR_PERMISSION_DENIED = 19, ///< Requested operation is not allowed
115
+ SP_ERROR_INBOX_IS_FULL = 20, ///< Target inbox is full
116
+ SP_ERROR_NO_CACHE = 21, ///< Cache is not enabled
117
+ SP_ERROR_NO_SUCH_USER = 22, ///< Requested user does not exist
118
+ SP_ERROR_NO_CREDENTIALS = 23, ///< No credentials are stored
119
+ SP_ERROR_NETWORK_DISABLED = 24, ///< Network disabled
120
+ SP_ERROR_INVALID_DEVICE_ID = 25, ///< Invalid device ID
121
+ SP_ERROR_CANT_OPEN_TRACE_FILE = 26, ///< Unable to open trace file
122
+ SP_ERROR_APPLICATION_BANNED = 27, ///< This application is no longer allowed to use the Spotify service
123
+ SP_ERROR_OFFLINE_TOO_MANY_TRACKS = 31, ///< Reached the device limit for number of tracks to download
124
+ SP_ERROR_OFFLINE_DISK_CACHE = 32, ///< Disk cache is full so no more tracks can be downloaded to offline mode
125
+ SP_ERROR_OFFLINE_EXPIRED = 33, ///< Offline key has expired, the user needs to go online again
126
+ SP_ERROR_OFFLINE_NOT_ALLOWED = 34, ///< This user is not allowed to use offline mode
127
+ SP_ERROR_OFFLINE_LICENSE_LOST = 35, ///< The license for this device has been lost. Most likely because the user used offline on three other device
128
+ SP_ERROR_OFFLINE_LICENSE_ERROR = 36, ///< The Spotify license server does not respond correctly
129
+ SP_ERROR_LASTFM_AUTH_ERROR = 39, ///< A LastFM scrobble authentication error has occurred
130
+ SP_ERROR_INVALID_ARGUMENT = 40, ///< An invalid argument was specified
131
+ SP_ERROR_SYSTEM_FAILURE = 41, ///< An operating system error
132
+ } sp_error;
133
+
134
+ /**
135
+ * Convert a numeric libspotify error code to a text string. The error message is in
136
+ * English. This function is useful for logging purposes.
137
+ *
138
+ * @param[in] error The error code to lookup
139
+ */
140
+ SP_LIBEXPORT(const char*) sp_error_message(sp_error error);
141
+
142
+ /** @} */
143
+
144
+
145
+
146
+ /**
147
+ * @defgroup session Session handling
148
+ *
149
+ * The concept of a session is fundamental for all communication with the Spotify ecosystem - it is the
150
+ * object responsible for communicating with the Spotify service. You will need to instantiate a
151
+ * session that then can be used to request artist information, perform searches etc.
152
+ *
153
+ * @{
154
+ */
155
+
156
+ /**
157
+ * Current version of the application interface, that is, the API described by this file.
158
+ *
159
+ * This value should be set in the sp_session_config struct passed to sp_session_create().
160
+ *
161
+ * If an (upgraded) library is no longer compatible with this version the error #SP_ERROR_BAD_API_VERSION will be
162
+ * returned from sp_session_create(). Future versions of the library will provide you with some kind of mechanism
163
+ * to request an updated version of the library.
164
+ */
165
+ #define SPOTIFY_API_VERSION 12
166
+
167
+ /**
168
+ * Describes the current state of the connection
169
+ */
170
+ typedef enum sp_connectionstate {
171
+ SP_CONNECTION_STATE_LOGGED_OUT = 0, ///< User not yet logged in
172
+ SP_CONNECTION_STATE_LOGGED_IN = 1, ///< Logged in against a Spotify access point
173
+ SP_CONNECTION_STATE_DISCONNECTED = 2, ///< Was logged in, but has now been disconnected
174
+ SP_CONNECTION_STATE_UNDEFINED = 3, ///< The connection state is undefined
175
+ SP_CONNECTION_STATE_OFFLINE = 4 ///< Logged in in offline mode
176
+ } sp_connectionstate;
177
+
178
+
179
+ /**
180
+ * Sample type descriptor
181
+ */
182
+ typedef enum sp_sampletype {
183
+ SP_SAMPLETYPE_INT16_NATIVE_ENDIAN = 0, ///< 16-bit signed integer samples
184
+ } sp_sampletype;
185
+
186
+ /**
187
+ * Audio format descriptor
188
+ */
189
+ typedef struct sp_audioformat {
190
+ sp_sampletype sample_type; ///< Sample type enum,
191
+ int sample_rate; ///< Audio sample rate, in samples per second.
192
+ int channels; ///< Number of channels. Currently 1 or 2.
193
+ } sp_audioformat;
194
+
195
+ /**
196
+ * Bitrate definitions for music streaming
197
+ */
198
+ typedef enum sp_bitrate {
199
+ SP_BITRATE_160k = 0, ///< Bitrate 160kbps
200
+ SP_BITRATE_320k = 1, ///< Bitrate 320kbps
201
+ SP_BITRATE_96k = 2, ///< Bitrate 96kbps
202
+ } sp_bitrate;
203
+
204
+ /**
205
+ * Playlist types
206
+ */
207
+ typedef enum sp_playlist_type {
208
+ SP_PLAYLIST_TYPE_PLAYLIST = 0, ///< A normal playlist.
209
+ SP_PLAYLIST_TYPE_START_FOLDER = 1, ///< Marks a folder starting point,
210
+ SP_PLAYLIST_TYPE_END_FOLDER = 2, ///< and ending point.
211
+ SP_PLAYLIST_TYPE_PLACEHOLDER = 3, ///< Unknown entry.
212
+ } sp_playlist_type;
213
+
214
+
215
+
216
+ /**
217
+ * Search types
218
+ */
219
+ typedef enum sp_search_type {
220
+ SP_SEARCH_STANDARD = 0,
221
+ SP_SEARCH_SUGGEST = 1,
222
+ } sp_search_type;
223
+
224
+ /**
225
+ * Playlist offline status
226
+ */
227
+ typedef enum sp_playlist_offline_status {
228
+ SP_PLAYLIST_OFFLINE_STATUS_NO = 0, ///< Playlist is not offline enabled
229
+ SP_PLAYLIST_OFFLINE_STATUS_YES = 1, ///< Playlist is synchronized to local storage
230
+ SP_PLAYLIST_OFFLINE_STATUS_DOWNLOADING = 2, ///< This playlist is currently downloading. Only one playlist can be in this state any given time
231
+ SP_PLAYLIST_OFFLINE_STATUS_WAITING = 3, ///< Playlist is queued for download
232
+ } sp_playlist_offline_status;
233
+
234
+ /**
235
+ * Track availability
236
+ */
237
+ typedef enum sp_availability {
238
+ SP_TRACK_AVAILABILITY_UNAVAILABLE = 0, ///< Track is not available
239
+ SP_TRACK_AVAILABILITY_AVAILABLE = 1, ///< Track is available and can be played
240
+ SP_TRACK_AVAILABILITY_NOT_STREAMABLE = 2, ///< Track can not be streamed using this account
241
+ SP_TRACK_AVAILABILITY_BANNED_BY_ARTIST = 3, ///< Track not available on artist's reqeust
242
+ } sp_track_availability;
243
+
244
+ /**
245
+ * Track offline status
246
+ */
247
+ typedef enum sp_track_offline_status {
248
+ SP_TRACK_OFFLINE_NO = 0, ///< Not marked for offline
249
+ SP_TRACK_OFFLINE_WAITING = 1, ///< Waiting for download
250
+ SP_TRACK_OFFLINE_DOWNLOADING = 2, ///< Currently downloading
251
+ SP_TRACK_OFFLINE_DONE = 3, ///< Downloaded OK and can be played
252
+ SP_TRACK_OFFLINE_ERROR = 4, ///< Error during download
253
+ SP_TRACK_OFFLINE_DONE_EXPIRED = 5, ///< Downloaded OK but not playable due to expiery
254
+ SP_TRACK_OFFLINE_LIMIT_EXCEEDED = 6, ///< Waiting because device have reached max number of allowed tracks
255
+ SP_TRACK_OFFLINE_DONE_RESYNC = 7, ///< Downloaded OK and available but scheduled for re-download
256
+ } sp_track_offline_status;
257
+
258
+ /**
259
+ * Image size
260
+ */
261
+ typedef enum sp_image_size {
262
+ SP_IMAGE_SIZE_NORMAL = 0, ///< Normal image size
263
+ SP_IMAGE_SIZE_SMALL = 1, ///< Small image size
264
+ SP_IMAGE_SIZE_LARGE = 2, ///< Large image size
265
+ } sp_image_size;
266
+
267
+ /**
268
+ * Buffer stats used by get_audio_buffer_stats callback
269
+ */
270
+ typedef struct sp_audio_buffer_stats {
271
+ int samples; ///< Samples in buffer
272
+ int stutter; ///< Number of stutters (audio dropouts) since last query
273
+ } sp_audio_buffer_stats;
274
+
275
+ /**
276
+ * List of subscribers returned by sp_playlist_subscribers()
277
+ */
278
+ typedef struct sp_subscribers {
279
+ unsigned int count; ///< Number of elements in 'subscribers'
280
+ char *subscribers[1]; ///< Actual size is 'count'. Array of pointers to canonical usernames
281
+ } sp_subscribers;
282
+
283
+
284
+ /**
285
+ * Current connection type set using sp_session_set_connection_type()
286
+ */
287
+ typedef enum sp_connection_type {
288
+ SP_CONNECTION_TYPE_UNKNOWN = 0, ///< Connection type unknown (Default)
289
+ SP_CONNECTION_TYPE_NONE = 1, ///< No connection
290
+ SP_CONNECTION_TYPE_MOBILE = 2, ///< Mobile data (EDGE, 3G, etc)
291
+ SP_CONNECTION_TYPE_MOBILE_ROAMING = 3, ///< Roamed mobile data (EDGE, 3G, etc)
292
+ SP_CONNECTION_TYPE_WIFI = 4, ///< Wireless connection
293
+ SP_CONNECTION_TYPE_WIRED = 5, ///< Ethernet cable, etc
294
+ } sp_connection_type;
295
+
296
+
297
+ /**
298
+ * Connection rules, bitwise OR of flags
299
+ *
300
+ * The default is SP_CONNECTION_RULE_NETWORK | SP_CONNECTION_RULE_ALLOW_SYNC
301
+ */
302
+ typedef enum sp_connection_rules {
303
+ SP_CONNECTION_RULE_NETWORK = 0x1, ///< Allow network traffic. When not set libspotify will force itself into offline mode
304
+ SP_CONNECTION_RULE_NETWORK_IF_ROAMING = 0x2, ///< Allow network traffic even if roaming
305
+ SP_CONNECTION_RULE_ALLOW_SYNC_OVER_MOBILE = 0x4, ///< Set to allow syncing of offline content over mobile connections
306
+ SP_CONNECTION_RULE_ALLOW_SYNC_OVER_WIFI = 0x8, ///< Set to allow syncing of offline content over WiFi
307
+ } sp_connection_rules;
308
+
309
+
310
+ /**
311
+ * Controls the type of data that will be included in artist browse queries
312
+ */
313
+ typedef enum sp_artistbrowse_type {
314
+ SP_ARTISTBROWSE_FULL, /**< All information except tophit tracks
315
+ This mode is deprecated and will removed in a future release */
316
+ SP_ARTISTBROWSE_NO_TRACKS, /**< Only albums and data about them, no tracks.
317
+ In other words, sp_artistbrowse_num_tracks() will return 0
318
+ */
319
+ SP_ARTISTBROWSE_NO_ALBUMS, /**< Only return data about the artist (artist name, similar artist
320
+ biography, etc
321
+ No tracks or album will be abailable.
322
+ sp_artistbrowse_num_tracks() and sp_artistbrowse_num_albums()
323
+ will both return 0
324
+ */
325
+ } sp_artistbrowse_type;
326
+
327
+ typedef enum sp_social_provider {
328
+ SP_SOCIAL_PROVIDER_SPOTIFY,
329
+ SP_SOCIAL_PROVIDER_FACEBOOK,
330
+ SP_SOCIAL_PROVIDER_LASTFM,
331
+ } sp_social_provider;
332
+
333
+ typedef enum sp_scrobbling_state {
334
+ SP_SCROBBLING_STATE_USE_GLOBAL_SETTING = 0,
335
+ SP_SCROBBLING_STATE_LOCAL_ENABLED = 1,
336
+ SP_SCROBBLING_STATE_LOCAL_DISABLED = 2,
337
+ SP_SCROBBLING_STATE_GLOBAL_ENABLED = 3,
338
+ SP_SCROBBLING_STATE_GLOBAL_DISABLED = 4,
339
+ } sp_scrobbling_state;
340
+
341
+
342
+ /**
343
+ * Offline sync status
344
+ */
345
+ typedef struct sp_offline_sync_status {
346
+ /**
347
+ * Queued tracks/bytes is things left to sync in current sync
348
+ * operation
349
+ */
350
+ int queued_tracks;
351
+ sp_uint64 queued_bytes;
352
+
353
+ /**
354
+ * Done tracks/bytes is things marked for sync that existed on
355
+ * device before current sync operation
356
+ */
357
+ int done_tracks;
358
+ sp_uint64 done_bytes;
359
+
360
+ /**
361
+ * Copied tracks/bytes is things that has been copied in
362
+ * current sync operation
363
+ */
364
+ int copied_tracks;
365
+ sp_uint64 copied_bytes;
366
+
367
+ /**
368
+ * Tracks that are marked as synced but will not be copied
369
+ * (for various reasons)
370
+ */
371
+ int willnotcopy_tracks;
372
+
373
+ /**
374
+ * A track is counted as error when something goes wrong while
375
+ * syncing the track
376
+ */
377
+ int error_tracks;
378
+
379
+ /**
380
+ * Set if sync operation is in progress
381
+ */
382
+ bool syncing;
383
+
384
+ } sp_offline_sync_status;
385
+
386
+
387
+ /**
388
+ * Session callbacks
389
+ *
390
+ * Registered when you create a session.
391
+ * If some callbacks should not be of interest, set them to NULL.
392
+ */
393
+ typedef struct sp_session_callbacks {
394
+
395
+ /**
396
+ * Called when login has been processed and was successful
397
+ *
398
+ * @param[in] session Session
399
+ * @param[in] error One of the following errors, from ::sp_error
400
+ * SP_ERROR_OK
401
+ * SP_ERROR_CLIENT_TOO_OLD
402
+ * SP_ERROR_UNABLE_TO_CONTACT_SERVER
403
+ * SP_ERROR_BAD_USERNAME_OR_PASSWORD
404
+ * SP_ERROR_USER_BANNED
405
+ * SP_ERROR_USER_NEEDS_PREMIUM
406
+ * SP_ERROR_OTHER_TRANSIENT
407
+ * SP_ERROR_OTHER_PERMANENT
408
+ */
409
+ void (SP_CALLCONV *logged_in)(sp_session *session, sp_error error);
410
+
411
+ /**
412
+ * Called when logout has been processed. Either called explicitly
413
+ * if you initialize a logout operation, or implicitly if there
414
+ * is a permanent connection error
415
+ *
416
+ * @param[in] session Session
417
+ */
418
+ void (SP_CALLCONV *logged_out)(sp_session *session);
419
+ /**
420
+ * Called whenever metadata has been updated
421
+ *
422
+ * If you have metadata cached outside of libspotify, you should purge
423
+ * your caches and fetch new versions.
424
+ *
425
+ * @param[in] session Session
426
+ */
427
+ void (SP_CALLCONV *metadata_updated)(sp_session *session);
428
+
429
+ /**
430
+ * Called when there is a connection error, and the library has problems
431
+ * reconnecting to the Spotify service. Could be called multiple times (as
432
+ * long as the problem is present)
433
+ *
434
+ *
435
+ * @param[in] session Session
436
+ * @param[in] error One of the following errors, from ::sp_error
437
+ * SP_ERROR_OK
438
+ * SP_ERROR_CLIENT_TOO_OLD
439
+ * SP_ERROR_UNABLE_TO_CONTACT_SERVER
440
+ * SP_ERROR_BAD_USERNAME_OR_PASSWORD
441
+ * SP_ERROR_USER_BANNED
442
+ * SP_ERROR_USER_NEEDS_PREMIUM
443
+ * SP_ERROR_OTHER_TRANSIENT
444
+ * SP_ERROR_OTHER_PERMANENT
445
+ */
446
+ void (SP_CALLCONV *connection_error)(sp_session *session, sp_error error);
447
+
448
+ /**
449
+ * Called when the access point wants to display a message to the user
450
+ *
451
+ * In the desktop client, these are shown in a blueish toolbar just below the
452
+ * search box.
453
+ *
454
+ * @param[in] session Session
455
+ * @param[in] message String in UTF-8 format.
456
+ */
457
+ void (SP_CALLCONV *message_to_user)(sp_session *session, const char *message);
458
+
459
+ /**
460
+ * Called when processing needs to take place on the main thread.
461
+ *
462
+ * You need to call sp_session_process_events() in the main thread to get
463
+ * libspotify to do more work. Failure to do so may cause request timeouts,
464
+ * or a lost connection.
465
+ *
466
+ * @param[in] session Session
467
+ *
468
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
469
+ */
470
+ void (SP_CALLCONV *notify_main_thread)(sp_session *session);
471
+
472
+ /**
473
+ * Called when there is decompressed audio data available.
474
+ *
475
+ * @param[in] session Session
476
+ * @param[in] format Audio format descriptor sp_audioformat
477
+ * @param[in] frames Points to raw PCM data as described by \p format
478
+ * @param[in] num_frames Number of available samples in \p frames.
479
+ * If this is 0, a discontinuity has occurred (such as after a seek). The application
480
+ * should flush its audio fifos, etc.
481
+ *
482
+ * @return Number of frames consumed.
483
+ * This value can be used to rate limit the output from the library if your
484
+ * output buffers are saturated. The library will retry delivery in about 100ms.
485
+ *
486
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
487
+ *
488
+ * @note This function must never block. If your output buffers are full you must return 0 to signal
489
+ * that the library should retry delivery in a short while.
490
+ */
491
+ int (SP_CALLCONV *music_delivery)(sp_session *session, const sp_audioformat *format, const void *frames, int num_frames);
492
+
493
+ /**
494
+ * Music has been paused because an account only allows music
495
+ * to be played from one location simultaneously.
496
+ *
497
+ * @note When this callback is invoked the application should
498
+ * behave just as if the user pressed the pause
499
+ * button. The application should also display a message
500
+ * to the user indicating the playback has been paused
501
+ * because another application is playing using the same
502
+ * account.
503
+ *
504
+ * @note IT MUST NOT automatically resume playback but must
505
+ * instead wait for the user to press play.
506
+ *
507
+ * @param[in] session Session
508
+ */
509
+ void (SP_CALLCONV *play_token_lost)(sp_session *session);
510
+
511
+ /**
512
+ * Logging callback.
513
+ *
514
+ * @param[in] session Session
515
+ * @param[in] data Log data
516
+ */
517
+ void (SP_CALLCONV *log_message)(sp_session *session, const char *data);
518
+
519
+ /**
520
+ * End of track.
521
+ * Called when the currently played track has reached its end.
522
+ *
523
+ * @note This function is invoked from the main thread
524
+ *
525
+ * @param[in] session Session
526
+ */
527
+ void (SP_CALLCONV *end_of_track)(sp_session *session);
528
+
529
+ /**
530
+ * Streaming error.
531
+ * Called when streaming cannot start or continue.
532
+ *
533
+ * @note This function is invoked from the main thread
534
+ *
535
+ * @param[in] session Session
536
+ * @param[in] error One of the following errors, from ::sp_error
537
+ * SP_ERROR_NO_STREAM_AVAILABLE
538
+ * SP_ERROR_OTHER_TRANSIENT
539
+ * SP_ERROR_OTHER_PERMANENT
540
+ */
541
+ void (SP_CALLCONV *streaming_error)(sp_session *session, sp_error error);
542
+
543
+ /**
544
+ * Called after user info (anything related to sp_user objects) have been updated.
545
+ *
546
+ * @param[in] session Session
547
+ */
548
+ void (SP_CALLCONV *userinfo_updated)(sp_session *session);
549
+
550
+ /**
551
+ * Called when audio playback should start
552
+ *
553
+ * @note For this to work correctly the application must also implement get_audio_buffer_stats()
554
+ *
555
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
556
+ *
557
+ * @note This function must never block.
558
+ *
559
+ * @param[in] session Session
560
+ */
561
+ void (SP_CALLCONV *start_playback)(sp_session *session);
562
+
563
+
564
+ /**
565
+ * Called when audio playback should stop
566
+ *
567
+ * @note For this to work correctly the application must also implement get_audio_buffer_stats()
568
+ *
569
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
570
+ *
571
+ * @note This function must never block.
572
+ *
573
+ * @param[in] session Session
574
+ */
575
+ void (SP_CALLCONV *stop_playback)(sp_session *session);
576
+
577
+ /**
578
+ * Called to query application about its audio buffer
579
+ *
580
+ * @note This function is called from an internal session thread - you need to have proper synchronization!
581
+ *
582
+ * @note This function must never block.
583
+ *
584
+ * @param[in] session Session
585
+ * @param[out] stats Stats struct to be filled by application
586
+ */
587
+ void (SP_CALLCONV *get_audio_buffer_stats)(sp_session *session, sp_audio_buffer_stats *stats);
588
+
589
+ /**
590
+ * Called when offline synchronization status is updated
591
+ *
592
+ * @param[in] session Session
593
+ */
594
+ void (SP_CALLCONV *offline_status_updated)(sp_session *session);
595
+
596
+ /**
597
+ * Called when offline synchronization status is updated
598
+ *
599
+ * @param[in] session Session
600
+ * @param[in] error Offline error. Will be SP_ERROR_OK if the offline synchronization
601
+ * error state has cleared
602
+ */
603
+ void (SP_CALLCONV *offline_error)(sp_session *session, sp_error error);
604
+
605
+ /**
606
+ * Called when storable credentials have been updated, usually called when
607
+ * we have connected to the AP.
608
+ *
609
+ * @param[in] session Session
610
+ * @param[in] blob Blob is a null-terminated string which contains
611
+ * an encrypted token that can be stored safely on disk
612
+ * instead of storing plaintext passwords.
613
+ */
614
+ void (SP_CALLCONV *credentials_blob_updated)(sp_session *session, const char *blob);
615
+
616
+ /**
617
+ * Called when the connection state has updated - such as when logging in, going offline, etc.
618
+ *
619
+ * @param[in] session Session
620
+ */
621
+ void (SP_CALLCONV *connectionstate_updated)(sp_session *session);
622
+
623
+ /**
624
+ * Called when there is a scrobble error event
625
+ *
626
+ * @param[in] session Session
627
+ * @param[in] error Scrobble error. Currently SP_ERROR_LASTFM_AUTH_ERROR.
628
+ */
629
+ void (SP_CALLCONV *scrobble_error)(sp_session *session, sp_error error);
630
+
631
+ /**
632
+ * Called when there is a change in the private session mode
633
+ *
634
+ * @param[in] session Session
635
+ * @param[in] isPrivate True if in private session, false otherwhise
636
+ */
637
+ void (SP_CALLCONV *private_session_mode_changed)(sp_session *session, bool is_private);
638
+ } sp_session_callbacks;
639
+
640
+ /**
641
+ * Session config
642
+ */
643
+ typedef struct sp_session_config {
644
+ int api_version; ///< The version of the Spotify API your application is compiled with. Set to #SPOTIFY_API_VERSION
645
+ const char *cache_location; /**< The location where Spotify will write cache files.
646
+ * This cache include tracks, cached browse results and coverarts.
647
+ * Set to empty string ("") to disable cache
648
+ */
649
+ const char *settings_location; /**< The location where Spotify will write setting files and per-user
650
+ * cache items. This includes playlists, track metadata, etc.
651
+ * 'settings_location' may be the same path as 'cache_location'.
652
+ * 'settings_location' folder will not be created (unlike 'cache_location'),
653
+ * if you don't want to create the folder yourself, you can set 'settings_location' to 'cache_location'.
654
+ */
655
+ const void *application_key; ///< Your application key
656
+ size_t application_key_size; ///< The size of the application key in bytes
657
+ const char *user_agent; /**< "User-Agent" for your application - max 255 characters long
658
+ The User-Agent should be a relevant, customer facing identification of your application
659
+ */
660
+
661
+ const sp_session_callbacks *callbacks; ///< Delivery callbacks for session events, or NULL if you are not interested in any callbacks (not recommended!)
662
+ void *userdata; ///< User supplied data for your application
663
+
664
+ /**
665
+ * Compress local copy of playlists, reduces disk space usage
666
+ */
667
+ bool compress_playlists;
668
+
669
+ /**
670
+ * Don't save metadata for local copies of playlists
671
+ * Reduces disk space usage at the expense of needing
672
+ * to request metadata from Spotify backend when loading list
673
+ */
674
+ bool dont_save_metadata_for_playlists;
675
+
676
+ /**
677
+ * Avoid loading playlists into RAM on startup.
678
+ * See sp_playlist_is_in_ram() for more details.
679
+ */
680
+ bool initially_unload_playlists;
681
+
682
+ /**
683
+ * Device ID for offline synchronization and logging purposes. The Device Id must be unique to the particular device instance,
684
+ * i.e. no two units must supply the same Device ID. The Device ID must not change between sessions or power cycles.
685
+ * Good examples is the device's MAC address or unique serial number.
686
+ */
687
+ const char *device_id;
688
+
689
+ /**
690
+ * Url to the proxy server that should be used.
691
+ * The format is protocol://<host>:port (where protocal is http/https/socks4/socks5)
692
+ */
693
+ const char *proxy;
694
+ /**
695
+ * Username to authenticate with proxy server
696
+ */
697
+ const char *proxy_username;
698
+ /**
699
+ * Password to authenticate with proxy server
700
+ */
701
+ const char *proxy_password;
702
+
703
+ /**
704
+ * Path to a file containing the root ca certificates that the peer should be verified with.
705
+ * The file must be a concatenation of all certificates in PEM format. Provided with libspotify
706
+ * is a sample pem file in examples. It is recommended that the application export a similar file from
707
+ * the local certificate store.
708
+ */
709
+ const char *ca_certs_filename;
710
+
711
+ /**
712
+ * Path to API trace file
713
+ */
714
+ const char *tracefile;
715
+
716
+ } sp_session_config;
717
+
718
+ /**
719
+ * Initialize a session. The session returned will be initialized, but you will need
720
+ * to log in before you can perform any other operation
721
+ * Currently it is not supported to have multiple active sessions, and it's recommended to only call this once per process.
722
+ *
723
+ * Here is a snippet from \c spshell.c:
724
+ * @dontinclude spshell.c
725
+ * @skip config.api_version
726
+ * @until }
727
+ *
728
+ * @param[in] config The configuration to use for the session
729
+ * @param[out] sess If successful, a new session - otherwise NULL
730
+ *
731
+ * @return One of the following errors, from ::sp_error
732
+ * SP_ERROR_OK
733
+ * SP_ERROR_BAD_API_VERSION
734
+ * SP_ERROR_BAD_USER_AGENT
735
+ * SP_ERROR_BAD_APPLICATION_KEY
736
+ * SP_ERROR_API_INITIALIZATION_FAILED
737
+ * SP_ERROR_INVALID_DEVICE_ID
738
+ */
739
+ SP_LIBEXPORT(sp_error) sp_session_create(const sp_session_config *config, sp_session **sess);
740
+
741
+ /**
742
+ * Release the session. This will clean up all data and connections associated with the session
743
+ *
744
+ * @param[in] sess Session object returned from sp_session_create()
745
+ * @return One of the following errors, from ::sp_error
746
+ * SP_ERROR_OK
747
+ */
748
+ SP_LIBEXPORT(sp_error) sp_session_release(sp_session *sess);
749
+
750
+
751
+ /**
752
+ * Logs in the specified username/password combo. This initiates the login in the background.
753
+ * A callback is called when login is complete
754
+ *
755
+ * An application MUST NEVER store the user's password in clear text.
756
+ * If automatic relogin is required, use sp_session_relogin()
757
+ *
758
+ * Here is a snippet from \c spshell.c:
759
+ * @dontinclude spshell.c
760
+ * @skip sp_session_login
761
+ * @until }
762
+ *
763
+ * @param[in] session Your session object
764
+ * @param[in] username The username to log in
765
+ * @param[in] password The password for the specified username
766
+ * @param[in] remember_me If set, the username / password will be remembered by libspotify
767
+ * @param[in] blob If you have received a blob in the #credentials_blob_updated
768
+ * you can pas this here instead of password
769
+ * @return One of the following errors, from ::sp_error
770
+ * SP_ERROR_OK
771
+ */
772
+ SP_LIBEXPORT(sp_error) sp_session_login(sp_session *session, const char *username, const char *password, bool remember_me, const char *blob);
773
+
774
+
775
+ /**
776
+ * Log in the remembered user if last user that logged in logged in with remember_me set.
777
+ * If no credentials are stored, this will return SP_ERROR_NO_CREDENTIALS.
778
+ *
779
+ * @param[in] session Your session object
780
+ *
781
+ * @return One of the following errors, from ::sp_error
782
+ * SP_ERROR_OK
783
+ * SP_ERROR_NO_CREDENTIALS
784
+ */
785
+ SP_LIBEXPORT(sp_error) sp_session_relogin(sp_session *session);
786
+
787
+
788
+ /**
789
+ * Get username of the user that will be logged in via sp_session_relogin()
790
+ *
791
+ * @param[in] session Your session object
792
+ * @param[out] buffer The buffer to hold the username
793
+ * @param[in] buffer_size The max size of the buffer that will hold the username.
794
+ * The resulting string is guaranteed to always be null terminated if
795
+ * buffer_size > 0
796
+ *
797
+ * @return The number of characters in the username.
798
+ * If value is greater or equal than \p buffer_size, output was truncated.
799
+ * If returned value is -1 no credentials are stored in libspotify.
800
+ */
801
+ SP_LIBEXPORT(int) sp_session_remembered_user(sp_session *session, char *buffer, size_t buffer_size);
802
+
803
+
804
+ /**
805
+ * Get a pointer to a string representing the user's login username.
806
+ *
807
+ * @param[in] session Your session object
808
+ *
809
+ * @return A string representing the login username.
810
+ */
811
+ SP_LIBEXPORT(const char *) sp_session_user_name(sp_session *session);
812
+
813
+
814
+ /**
815
+ * Remove stored credentials in libspotify. If no credentials are currently stored, nothing will happen.
816
+ *
817
+ * @param[in] session Your session object
818
+ * @return One of the following errors, from ::sp_error
819
+ * SP_ERROR_OK
820
+ */
821
+ SP_LIBEXPORT(sp_error) sp_session_forget_me(sp_session *session);
822
+
823
+
824
+ /**
825
+ * Fetches the currently logged in user
826
+ *
827
+ * @param[in] session Your session object
828
+ *
829
+ * @return The logged in user (or NULL if not logged in)
830
+ */
831
+ SP_LIBEXPORT(sp_user *) sp_session_user(sp_session *session);
832
+
833
+ /**
834
+ * Logs out the currently logged in user
835
+ *
836
+ * Always call this before terminating the application and libspotify is currently
837
+ * logged in. Otherwise, the settings and cache may be lost.
838
+ *
839
+ * @param[in] session Your session object
840
+ * @return One of the following errors, from ::sp_error
841
+ * SP_ERROR_OK
842
+ */
843
+ SP_LIBEXPORT(sp_error) sp_session_logout(sp_session *session);
844
+
845
+
846
+ /**
847
+ * Flush the caches
848
+ *
849
+ * This will make libspotify write all data that is meant to be stored
850
+ * on disk to the disk immediately. libspotify does this periodically
851
+ * by itself and also on logout. So under normal conditions this
852
+ * should never need to be used.
853
+ *
854
+ * @param[in] session Your session object
855
+ * @return One of the following errors, from ::sp_error
856
+ * SP_ERROR_OK
857
+ */
858
+ SP_LIBEXPORT(sp_error) sp_session_flush_caches(sp_session *session);
859
+
860
+ /**
861
+ * The connection state of the specified session.
862
+ *
863
+ * @param[in] session Your session object
864
+ *
865
+ * @return The connection state - see the sp_connectionstate enum for possible values
866
+ */
867
+ SP_LIBEXPORT(sp_connectionstate) sp_session_connectionstate(sp_session *session);
868
+
869
+ /**
870
+ * The userdata associated with the session
871
+ *
872
+ * @param[in] session Your session object
873
+ *
874
+ * @return The userdata that was passed in on session creation
875
+ */
876
+ SP_LIBEXPORT(void *) sp_session_userdata(sp_session *session);
877
+
878
+ /**
879
+ * Set maximum cache size.
880
+ *
881
+ * @param[in] session Your session object
882
+ * @param[in] size Maximum cache size in megabytes.
883
+ * Setting it to 0 (the default) will let libspotify automatically
884
+ * resize the cache (10% of disk free space)
885
+ * @return One of the following errors, from ::sp_error
886
+ * SP_ERROR_OK
887
+ */
888
+ SP_LIBEXPORT(sp_error) sp_session_set_cache_size(sp_session *session, size_t size);
889
+
890
+ /**
891
+ * Make the specified session process any pending events
892
+ *
893
+ * @param[in] session Your session object
894
+ * @param[out] next_timeout Stores the time (in milliseconds) until you should call this function again
895
+ * @return One of the following errors, from ::sp_error
896
+ * SP_ERROR_OK
897
+ */
898
+ SP_LIBEXPORT(sp_error) sp_session_process_events(sp_session *session, int *next_timeout);
899
+
900
+ /**
901
+ * Loads the specified track
902
+ *
903
+ * After successfully loading the track, you have the option of running
904
+ * sp_session_player_play() directly, or using sp_session_player_seek() first.
905
+ * When this call returns, the track will have been loaded, unless an error occurred.
906
+ *
907
+ * @param[in] session Your session object
908
+ * @param[in] track The track to be loaded
909
+ *
910
+ * @return One of the following errors, from ::sp_error
911
+ * SP_ERROR_OK
912
+ * SP_ERROR_MISSING_CALLBACK
913
+ * SP_ERROR_TRACK_NOT_PLAYABLE
914
+ *
915
+ */
916
+ SP_LIBEXPORT(sp_error) sp_session_player_load(sp_session *session, sp_track *track);
917
+
918
+ /**
919
+ * Seek to position in the currently loaded track
920
+ *
921
+ * @param[in] session Your session object
922
+ * @param[in] offset Track position, in milliseconds.
923
+ * @return One of the following errors, from ::sp_error
924
+ * SP_ERROR_OK
925
+ */
926
+ SP_LIBEXPORT(sp_error) sp_session_player_seek(sp_session *session, int offset);
927
+
928
+ /**
929
+ * Play or pause the currently loaded track
930
+ *
931
+ * @param[in] session Your session object
932
+ * @param[in] play If set to true, playback will occur. If set to false, the playback will be paused.
933
+ * @return One of the following errors, from ::sp_error
934
+ * SP_ERROR_OK
935
+ */
936
+ SP_LIBEXPORT(sp_error) sp_session_player_play(sp_session *session, bool play);
937
+
938
+ /**
939
+ * Stops the currently playing track
940
+ *
941
+ * This frees some resources held by libspotify to identify the currently
942
+ * playing track.
943
+ *
944
+ * @param[in] session Your session object
945
+ * @return One of the following errors, from ::sp_error
946
+ * SP_ERROR_OK
947
+ */
948
+ SP_LIBEXPORT(sp_error) sp_session_player_unload(sp_session *session);
949
+
950
+ /**
951
+ * Prefetch a track
952
+ *
953
+ * Instruct libspotify to start loading of a track into its cache.
954
+ * This could be done by an application just before the current track ends.
955
+ *
956
+ * @param[in] session Your session object
957
+ * @param[in] track The track to be prefetched
958
+ *
959
+ * @return One of the following errors, from ::sp_error
960
+ * SP_ERROR_NO_CACHE
961
+ * SP_ERROR_OK
962
+ *
963
+ * @note Prefetching is only possible if a cache is configured
964
+ *
965
+ */
966
+ SP_LIBEXPORT(sp_error) sp_session_player_prefetch(sp_session *session, sp_track *track);
967
+
968
+ /**
969
+ * Returns the playlist container for the currently logged in user.
970
+ *
971
+ * @param[in] session Your session object
972
+ *
973
+ * @return Playlist container object, NULL if not logged in
974
+ */
975
+ SP_LIBEXPORT(sp_playlistcontainer *) sp_session_playlistcontainer(sp_session *session);
976
+
977
+ /**
978
+ * Returns an inbox playlist for the currently logged in user
979
+ *
980
+ * @param[in] session Session object
981
+ *
982
+ * @return A playlist or NULL if no user is logged in
983
+ * @note You need to release the playlist when you are done with it.
984
+ * @see sp_playlist_release()
985
+ */
986
+ SP_LIBEXPORT(sp_playlist *) sp_session_inbox_create(sp_session *session);
987
+
988
+ /**
989
+ * Returns the starred list for the current user
990
+ *
991
+ * @param[in] session Session object
992
+ *
993
+ * @return A playlist or NULL if no user is logged in
994
+ * @note You need to release the playlist when you are done with it.
995
+ * @see sp_playlist_release()
996
+ */
997
+ SP_LIBEXPORT(sp_playlist *) sp_session_starred_create(sp_session *session);
998
+
999
+ /**
1000
+ * Returns the starred list for a user
1001
+ *
1002
+ * @param[in] session Session object
1003
+ * @param[in] canonical_username Canonical username
1004
+ *
1005
+ * @return A playlist or NULL if no user is logged in
1006
+ * @note You need to release the playlist when you are done with it.
1007
+ * @see sp_playlist_release()
1008
+ */
1009
+ SP_LIBEXPORT(sp_playlist *) sp_session_starred_for_user_create(sp_session *session, const char *canonical_username);
1010
+
1011
+ /**
1012
+ * Return the published container for a given @a canonical_username,
1013
+ * or the currently logged in user if @a canonical_username is NULL.
1014
+ *
1015
+ * When done with the list you should call sp_playlistconatiner_release() to
1016
+ * decrese the reference you own by having created it.
1017
+ *
1018
+ * @param[in] session Your session object.
1019
+ * @param[in] canonical_username The canonical username, or NULL.
1020
+ *
1021
+ * @return Playlist container object, NULL if not logged in.
1022
+ */
1023
+ SP_LIBEXPORT(sp_playlistcontainer *) sp_session_publishedcontainer_for_user_create(sp_session *session, const char *canonical_username);
1024
+
1025
+
1026
+ /**
1027
+ * Set preferred bitrate for music streaming
1028
+ *
1029
+ * @param[in] session Session object
1030
+ * @param[in] bitrate Preferred bitrate, see ::sp_bitrate for possible values
1031
+ * @return One of the following errors, from ::sp_error
1032
+ * SP_ERROR_OK
1033
+ * SP_ERROR_INVALID_ARGUMENT
1034
+ */
1035
+ SP_LIBEXPORT(sp_error) sp_session_preferred_bitrate(sp_session *session, sp_bitrate bitrate);
1036
+
1037
+
1038
+ /**
1039
+ * Set preferred bitrate for offline sync
1040
+ *
1041
+ * @param[in] session Session object
1042
+ * @param[in] bitrate Preferred bitrate, see ::sp_bitrate for possible values
1043
+ * @param[in] allow_resync Set to true if libspotify should resynchronize already synchronized tracks. Usually you should set this to false.
1044
+ * @return One of the following errors, from ::sp_error
1045
+ * SP_ERROR_OK
1046
+ * SP_ERROR_INVALID_ARGUMENT
1047
+ */
1048
+ SP_LIBEXPORT(sp_error) sp_session_preferred_offline_bitrate(sp_session *session, sp_bitrate bitrate, bool allow_resync);
1049
+
1050
+
1051
+ /**
1052
+ * Return status of volume normalization
1053
+ *
1054
+ * @param[in] session Session object
1055
+ *
1056
+ * @return true iff volume normalization is enabled
1057
+ *
1058
+ */
1059
+ SP_LIBEXPORT(bool) sp_session_get_volume_normalization(sp_session *session);
1060
+
1061
+
1062
+ /**
1063
+ * Set volume normalization
1064
+ *
1065
+ * @param[in] session Session object
1066
+ * @param[in] on True iff volume normalization should be enabled
1067
+ * @return One of the following errors, from ::sp_error
1068
+ * SP_ERROR_OK
1069
+ */
1070
+ SP_LIBEXPORT(sp_error) sp_session_set_volume_normalization(sp_session *session, bool on);
1071
+
1072
+
1073
+ /**
1074
+ * Set if private session is enabled. This disables sharing what the user is listening to
1075
+ * to services such as Spotify Social, Facebook and LastFM. The private session will
1076
+ * last for a time, and then libspotify will revert to the normal state. The private
1077
+ * session is prolonged by user activity.
1078
+ *
1079
+ * @param[in] session Session object
1080
+ * @param[in] enabled True iff private session should be enabled
1081
+ * @return One of the following errors, from ::sp_error
1082
+ * SP_ERROR_OK
1083
+ */
1084
+ SP_LIBEXPORT(sp_error) sp_session_set_private_session(sp_session *session, bool enabled);
1085
+
1086
+ /**
1087
+ * Return True if private session is enabled
1088
+ *
1089
+ * @param[in] session Session object
1090
+ *
1091
+ * @return True if private session is enabled
1092
+ */
1093
+ SP_LIBEXPORT(bool) sp_session_is_private_session(sp_session *session);
1094
+
1095
+ /**
1096
+ * Set if scrobbling is enabled. This api allows setting local overrides of the global scrobbling settings.
1097
+ * Changing the global settings are currently not supported.
1098
+ *
1099
+ * @param[in] session Session object
1100
+ * @param[in] provider The scrobbling provider referred to
1101
+ * @param[in] state The state to set the provider to
1102
+ *
1103
+ * @return error code
1104
+ *
1105
+ * @see sp_social_provider
1106
+ * @see sp_scrobbling_state
1107
+ */
1108
+ SP_LIBEXPORT(sp_error) sp_session_set_scrobbling(sp_session *session, sp_social_provider provider, sp_scrobbling_state state);
1109
+
1110
+ /**
1111
+ * Return the scrobbling state. This makes it possible to find out if scrobbling is locally overrided or
1112
+ * if the global setting is used.
1113
+ *
1114
+ * @param[in] session Session object
1115
+ * @param[in] provider The scrobbling provider referred to
1116
+ * @param[out] state The output variable receiving the sp_scrobbling_state state
1117
+ *
1118
+ * @return error code
1119
+ */
1120
+ SP_LIBEXPORT(sp_error) sp_session_is_scrobbling(sp_session *session, sp_social_provider provider, sp_scrobbling_state* state);
1121
+
1122
+ /**
1123
+ * Return True if scrobbling settings should be shown to the user. Currently this setting is relevant
1124
+ * only to the facebook provider.
1125
+ * The returned value may be false if the user is not connected to facebook,
1126
+ * or if the user has opted out from facebook social graph.
1127
+ *
1128
+ * @param[in] session Session object
1129
+ * @param[in] provider The scrobbling provider referred to
1130
+ * @param[out] out True iff scrobbling is possible
1131
+ *
1132
+ * @return error code
1133
+ */
1134
+ SP_LIBEXPORT(sp_error) sp_session_is_scrobbling_possible(sp_session *session, sp_social_provider provider, bool* out);
1135
+
1136
+ /**
1137
+ * Set the user's credentials with a social provider.
1138
+ * Currently this is only relevant for LastFm
1139
+ * Call sp_session_set_scrobbling to force an authentication attempt
1140
+ * with the LastFm server. If authentication fails a scrobble_error callback will be
1141
+ * sent.
1142
+ *
1143
+ * @param[in] session Session object
1144
+ * @param[in] provider The scrobbling provider referred to
1145
+ * @param[in] username The user name
1146
+ * @param[in] password The password
1147
+ *
1148
+ * @return error code
1149
+
1150
+ * @see sp_session_set_scrobbling
1151
+ * @see sp_session_callbacks#scrobble_error
1152
+ * @return One of the following errors, from ::sp_error
1153
+ * SP_ERROR_OK
1154
+ */
1155
+ SP_LIBEXPORT(sp_error) sp_session_set_social_credentials(sp_session *session, sp_social_provider provider, const char* username, const char* password);
1156
+
1157
+ /**
1158
+ * Set to true if the connection is currently routed over a roamed connectivity
1159
+ *
1160
+ * @param[in] session Session object
1161
+ * @param[in] type Connection type
1162
+ *
1163
+ * @note Used in conjunction with sp_session_set_connection_rules() to control
1164
+ * how libspotify should behave in respect to network activity and offline
1165
+ * synchronization.
1166
+ * @see sp_connection_type
1167
+ * @return One of the following errors, from ::sp_error
1168
+ * SP_ERROR_OK
1169
+ */
1170
+ SP_LIBEXPORT(sp_error) sp_session_set_connection_type(sp_session *session, sp_connection_type type);
1171
+
1172
+
1173
+ /**
1174
+ * Set rules for how libspotify connects to Spotify servers and synchronizes offline content
1175
+ *
1176
+ * @param[in] session Session object
1177
+ * @param[in] rules Connection rules
1178
+ *
1179
+ * @note Used in conjunction with sp_session_set_connection_type() to control
1180
+ * how libspotify should behave in respect to network activity and offline
1181
+ * synchronization.
1182
+ * @see sp_connection_rules
1183
+ * @return One of the following errors, from ::sp_error
1184
+ * SP_ERROR_OK
1185
+ */
1186
+ SP_LIBEXPORT(sp_error) sp_session_set_connection_rules(sp_session *session, sp_connection_rules rules);
1187
+
1188
+
1189
+
1190
+ /**
1191
+ * Get total number of tracks that needs download before everything
1192
+ * from all playlists that is marked for offline is fully synchronized
1193
+ *
1194
+ * @param[in] session Session object
1195
+ *
1196
+ * @return Number of tracks
1197
+ */
1198
+ SP_LIBEXPORT(int) sp_offline_tracks_to_sync(sp_session *session);
1199
+
1200
+ /**
1201
+ * Return number of playlisys that is marked for offline synchronization
1202
+ *
1203
+ * @param[in] session Session object
1204
+ *
1205
+ * @return Number of playlists
1206
+ */
1207
+ SP_LIBEXPORT(int) sp_offline_num_playlists(sp_session *session);
1208
+
1209
+ /**
1210
+ * Return offline synchronization status. When the internal status is
1211
+ * updated the offline_status_updated() callback will be invoked.
1212
+ *
1213
+ * @param[in] session Session object
1214
+ * @param[out] status Status object that will be filled with info
1215
+ *
1216
+ * @return false if no synching is in progress (in which case the contents
1217
+ * of status is undefined)
1218
+ *
1219
+ */
1220
+ SP_LIBEXPORT(bool) sp_offline_sync_get_status(sp_session *session, sp_offline_sync_status *status);
1221
+
1222
+ /**
1223
+ * Return remaining time (in seconds) until the offline key store expires
1224
+ * and the user is required to relogin
1225
+ *
1226
+ * @param[in] session Session object
1227
+ * @return Seconds until expiration
1228
+ *
1229
+ */
1230
+ SP_LIBEXPORT(int) sp_offline_time_left(sp_session *session);
1231
+
1232
+ /**
1233
+ * Get currently logged in users country
1234
+ * updated the offline_status_updated() callback will be invoked.
1235
+ *
1236
+ * @param[in] session Session object
1237
+ *
1238
+ * @return Country encoded in an integer 'SE' = 'S' << 8 | 'E'
1239
+ */
1240
+ SP_LIBEXPORT(int) sp_session_user_country(sp_session *session);
1241
+
1242
+
1243
+ /** @} */
1244
+
1245
+
1246
+ /**
1247
+ * @defgroup link Links (Spotify URIs)
1248
+ *
1249
+ * These functions handle links to Spotify entities in a way that allows you to
1250
+ * not care about the textual representation of the link.
1251
+ * @{
1252
+ */
1253
+
1254
+ /**
1255
+ * Link types
1256
+ */
1257
+ typedef enum {
1258
+ SP_LINKTYPE_INVALID = 0, ///< Link type not valid - default until the library has parsed the link, or when parsing failed
1259
+ SP_LINKTYPE_TRACK = 1, ///< Link type is track
1260
+ SP_LINKTYPE_ALBUM = 2, ///< Link type is album
1261
+ SP_LINKTYPE_ARTIST = 3, ///< Link type is artist
1262
+ SP_LINKTYPE_SEARCH = 4, ///< Link type is search
1263
+ SP_LINKTYPE_PLAYLIST = 5, ///< Link type is playlist
1264
+ SP_LINKTYPE_PROFILE = 6, ///< Link type is profile
1265
+ SP_LINKTYPE_STARRED = 7, ///< Link type is starred
1266
+ SP_LINKTYPE_LOCALTRACK = 8, ///< Link type is a local file
1267
+ SP_LINKTYPE_IMAGE = 9, ///< Link type is an image
1268
+ } sp_linktype;
1269
+
1270
+ /**
1271
+ * Create a Spotify link given a string
1272
+ *
1273
+ * @param[in] link A string representation of a Spotify link
1274
+ *
1275
+ * @return A link representation of the given string representation.
1276
+ * If the link could not be parsed, this function returns NULL.
1277
+ *
1278
+ * @note You need to release the link when you are done with it.
1279
+ * @see sp_link_type()
1280
+ * @see sp_link_release()
1281
+ */
1282
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_string(const char *link);
1283
+
1284
+ /**
1285
+ * Generates a link object from a track
1286
+ *
1287
+ * @param[in] track A track object
1288
+ * @param[in] offset Offset in track in ms.
1289
+ *
1290
+ * @return A link representing the track
1291
+ *
1292
+ * @note You need to release the link when you are done with it.
1293
+ * @see sp_link_release()
1294
+ */
1295
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_track(sp_track *track, int offset);
1296
+
1297
+ /**
1298
+ * Create a link object from an album
1299
+ *
1300
+ * @param[in] album An album object
1301
+ *
1302
+ * @return A link representing the album
1303
+ *
1304
+ * @note You need to release the link when you are done with it.
1305
+ * @see sp_link_release()
1306
+ */
1307
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_album(sp_album *album);
1308
+
1309
+ /**
1310
+ * Create an image link object from an album
1311
+ *
1312
+ * @param[in] album An album object
1313
+ * @param[in] size The desired size of the image
1314
+ *
1315
+ * @return A link representing the album cover. Type is set to SP_LINKTYPE_IMAGE
1316
+ *
1317
+ * @note You need to release the link when you are done with it.
1318
+ * @see sp_link_release()
1319
+ */
1320
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_album_cover(sp_album *album, sp_image_size size);
1321
+
1322
+ /**
1323
+ * Creates a link object from an artist
1324
+ *
1325
+ * @param[in] artist An artist object
1326
+ *
1327
+ * @return A link object representing the artist
1328
+ *
1329
+ * @note You need to release the link when you are done with it.
1330
+ * @see sp_link_release()
1331
+ */
1332
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_artist(sp_artist *artist);
1333
+
1334
+ /**
1335
+ * Creates a link object pointing to an artist portrait
1336
+ *
1337
+ * @param[in] artist Artist browse object
1338
+ * @param[in] size The desired size of the image
1339
+ *
1340
+ * @return A link object representing an image
1341
+ *
1342
+ * @note You need to release the link when you are done with it.
1343
+ * @see sp_link_release()
1344
+ * @see sp_artistbrowse_num_portraits()
1345
+ */
1346
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_artist_portrait(sp_artist *artist, sp_image_size size);
1347
+
1348
+
1349
+ /**
1350
+ * Creates a link object from an artist portrait
1351
+ *
1352
+ * @param[in] arb Artist browse object
1353
+ * @param[in] index The index of the portrait. Should be in the interval [0, sp_artistbrowse_num_portraits() - 1]
1354
+ *
1355
+ * @return A link object representing an image
1356
+ *
1357
+ * @note You need to release the link when you are done with it.
1358
+ * @see sp_link_release()
1359
+ * @see sp_artistbrowse_num_portraits()
1360
+ *
1361
+ * @note The difference from sp_link_create_from_artist_portrait() is
1362
+ * that the artist browse object may contain multiple portraits.
1363
+ *
1364
+ */
1365
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_artistbrowse_portrait(sp_artistbrowse *arb, int index);
1366
+
1367
+
1368
+ /**
1369
+ * Generate a link object representing the current search
1370
+ *
1371
+ * @param[in] search Search object
1372
+ *
1373
+ * @return A link representing the search
1374
+ *
1375
+ * @note You need to release the link when you are done with it.
1376
+ * @see sp_link_release()
1377
+ */
1378
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_search(sp_search *search);
1379
+
1380
+ /**
1381
+ * Create a link object representing the given playlist
1382
+ *
1383
+ * @param[in] playlist Playlist object
1384
+ *
1385
+ * @return A link representing the playlist
1386
+ *
1387
+ * @note You need to release the link when you are done with it.
1388
+ * @see sp_link_release()
1389
+ *
1390
+ * @note Due to reasons in the playlist backend design and the Spotify URI
1391
+ * scheme you need to wait for the playlist to be loaded before you can
1392
+ * successfully construct an URI. If sp_link_create_from_playlist() returns
1393
+ * NULL, try again after teh playlist_state_changed callback has fired.
1394
+ */
1395
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_playlist(sp_playlist *playlist);
1396
+
1397
+ /**
1398
+ * Create a link object representing the given playlist
1399
+ *
1400
+ * @param[in] user User object
1401
+ *
1402
+ * @return A link representing the profile.
1403
+ *
1404
+ * @note You need to release the link when you are done with it.
1405
+ * @see sp_link_release()
1406
+ */
1407
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_user(sp_user *user);
1408
+
1409
+ /**
1410
+ * Create a link object representing the given image
1411
+ *
1412
+ * @param[in] image Image object
1413
+ *
1414
+ * @return A link representing the image.
1415
+ *
1416
+ * @note You need to release the link when you are done with it.
1417
+ * @see sp_link_release()
1418
+ */
1419
+ SP_LIBEXPORT(sp_link *) sp_link_create_from_image(sp_image *image);
1420
+
1421
+ /**
1422
+ * Create a string representation of the given Spotify link
1423
+ *
1424
+ * @param[in] link The Spotify link whose string representation you are interested in
1425
+ * @param[out] buffer The buffer to hold the string representation of link
1426
+ * @param[in] buffer_size The max size of the buffer that will hold the string representation
1427
+ * The resulting string is guaranteed to always be null terminated if
1428
+ * buffer_size > 0
1429
+ *
1430
+ * @return The number of characters in the string representation of the link. If this
1431
+ * value is greater or equal than \p buffer_size, output was truncated.
1432
+ */
1433
+ SP_LIBEXPORT(int) sp_link_as_string(sp_link *link, char *buffer, int buffer_size);
1434
+
1435
+ /**
1436
+ * The link type of the specified link
1437
+ *
1438
+ * @param[in] link The Spotify link whose type you are interested in
1439
+ *
1440
+ * @return The link type of the specified link - see the sp_linktype enum for possible values
1441
+ */
1442
+ SP_LIBEXPORT(sp_linktype) sp_link_type(sp_link *link);
1443
+
1444
+ /**
1445
+ * The track representation for the given link
1446
+ *
1447
+ * @param[in] link The Spotify link whose track you are interested in
1448
+ *
1449
+ * @return The track representation of the given track link
1450
+ * If the link is not of track type then NULL is returned.
1451
+ */
1452
+ SP_LIBEXPORT(sp_track *) sp_link_as_track(sp_link *link);
1453
+
1454
+ /**
1455
+ * The track and offset into track representation for the given link
1456
+ *
1457
+ * @param[in] link The Spotify link whose track you are interested in
1458
+ * @param[out] offset Pointer to offset into track (in milliseconds). If the link
1459
+ * does not contain an offset this will be set to 0.
1460
+ *
1461
+ * @return The track representation of the given track link
1462
+ * If the link is not of track type then NULL is returned.
1463
+ */
1464
+ SP_LIBEXPORT(sp_track *) sp_link_as_track_and_offset(sp_link *link, int *offset);
1465
+
1466
+ /**
1467
+ * The album representation for the given link
1468
+ *
1469
+ * @param[in] link The Spotify link whose album you are interested in
1470
+ *
1471
+ * @return The album representation of the given album link
1472
+ * If the link is not of album type then NULL is returned
1473
+ */
1474
+ SP_LIBEXPORT(sp_album *) sp_link_as_album(sp_link *link);
1475
+
1476
+ /**
1477
+ * The artist representation for the given link
1478
+ *
1479
+ * @param[in] link The Spotify link whose artist you are interested in
1480
+ *
1481
+ * @return The artist representation of the given link
1482
+ * If the link is not of artist type then NULL is returned
1483
+ */
1484
+ SP_LIBEXPORT(sp_artist *) sp_link_as_artist(sp_link *link);
1485
+
1486
+
1487
+ /**
1488
+ * The user representation for the given link
1489
+ *
1490
+ * @param[in] link The Spotify link whose user you are interested in
1491
+ *
1492
+ * @return The user representation of the given link
1493
+ * If the link is not of user type then NULL is returned
1494
+ */
1495
+ SP_LIBEXPORT(sp_user *) sp_link_as_user(sp_link *link);
1496
+
1497
+
1498
+ /**
1499
+ * Increase the reference count of a link
1500
+ *
1501
+ * @param[in] link The link object
1502
+ * @return One of the following errors, from ::sp_error
1503
+ * SP_ERROR_OK
1504
+ */
1505
+ SP_LIBEXPORT(sp_error) sp_link_add_ref(sp_link *link);
1506
+
1507
+ /**
1508
+ * Decrease the reference count of a link
1509
+ *
1510
+ * @param[in] link The link object
1511
+ * @return One of the following errors, from ::sp_error
1512
+ * SP_ERROR_OK
1513
+ */
1514
+ SP_LIBEXPORT(sp_error) sp_link_release(sp_link *link);
1515
+
1516
+ /** @} */
1517
+
1518
+
1519
+
1520
+ /**
1521
+ * @defgroup track Track subsystem
1522
+ * @{
1523
+ */
1524
+
1525
+ /**
1526
+ * Return whether or not the track metadata is loaded.
1527
+ *
1528
+ * @param[in] track The track
1529
+ *
1530
+ * @return True if track is loaded
1531
+ *
1532
+ * @note This is equivalent to checking if sp_track_error() not returns SP_ERROR_IS_LOADING.
1533
+ */
1534
+ SP_LIBEXPORT(bool) sp_track_is_loaded(sp_track *track);
1535
+
1536
+ /**
1537
+ * Return an error code associated with a track. For example if it could not load
1538
+ *
1539
+ * @param[in] track The track
1540
+ *
1541
+ * @return One of the following errors, from ::sp_error
1542
+ * SP_ERROR_OK
1543
+ * SP_ERROR_IS_LOADING
1544
+ * SP_ERROR_OTHER_PERMANENT
1545
+ */
1546
+ SP_LIBEXPORT(sp_error) sp_track_error(sp_track *track);
1547
+
1548
+
1549
+ /**
1550
+ * Return offline status for a track. sp_session_callbacks::metadata_updated() will be invoked when
1551
+ * offline status of a track changes
1552
+ *
1553
+ * @param[in] track The track
1554
+ *
1555
+ * @return Stats as described by ::sp_track_offline_status
1556
+ *
1557
+ */
1558
+ SP_LIBEXPORT(sp_track_offline_status) sp_track_offline_get_status(sp_track *track);
1559
+
1560
+ /**
1561
+ * Return availability for a track
1562
+ *
1563
+ * @param[in] session Session
1564
+ * @param[in] track The track
1565
+ *
1566
+ * @return Availability status, see ::sp_track_availability
1567
+ *
1568
+ * @note The track must be loaded or this function will always SP_TRACK_AVAILABILITY_UNAVAILABLE
1569
+ * @see sp_track_is_loaded()
1570
+ */
1571
+ SP_LIBEXPORT(sp_track_availability) sp_track_get_availability(sp_session *session, sp_track *track);
1572
+
1573
+ /**
1574
+ * Return true if the track is a local file.
1575
+ *
1576
+ * @param[in] session Session
1577
+ * @param[in] track The track
1578
+ *
1579
+ * @return True if track is a local file.
1580
+ *
1581
+ * @note The track must be loaded or this function will always return false.
1582
+ * @see sp_track_is_loaded()
1583
+ */
1584
+ SP_LIBEXPORT(bool) sp_track_is_local(sp_session *session, sp_track *track);
1585
+
1586
+ /**
1587
+ * Return true if the track is autolinked to another track.
1588
+ *
1589
+ * @param[in] session Session
1590
+ * @param[in] track The track
1591
+ *
1592
+ * @return True if track is autolinked.
1593
+ *
1594
+ * @note The track must be loaded or this function will always return false.
1595
+ * @see sp_track_is_loaded()
1596
+ */
1597
+ SP_LIBEXPORT(bool) sp_track_is_autolinked(sp_session *session, sp_track *track);
1598
+
1599
+
1600
+ /**
1601
+ * Return the actual track that will be played if the given track is played
1602
+ *
1603
+ * @param[in] session Session
1604
+ * @param[in] track The track
1605
+ *
1606
+ * @return A track
1607
+ *
1608
+ */
1609
+ SP_LIBEXPORT(sp_track *) sp_track_get_playable(sp_session *session, sp_track *track);
1610
+
1611
+ /**
1612
+ * Return true if the track is a placeholder. Placeholder tracks are used
1613
+ * to store other objects than tracks in the playlist. Currently this is
1614
+ * used in the inbox to store artists, albums and playlists.
1615
+ *
1616
+ * Use sp_link_create_from_track() to get a link object that points
1617
+ * to the real object this "track" points to.
1618
+ *
1619
+ * @param[in] track The track
1620
+ *
1621
+ * @return True if track is a placeholder
1622
+ *
1623
+ * @note Contrary to most functions the track does not have to be
1624
+ * loaded for this function to return correct value
1625
+ */
1626
+ SP_LIBEXPORT(bool) sp_track_is_placeholder(sp_track *track);
1627
+
1628
+
1629
+ /**
1630
+ * Return true if the track is starred by the currently logged in user.
1631
+ *
1632
+ * @param[in] session Session
1633
+ * @param[in] track The track
1634
+ *
1635
+ * @return True if track is starred.
1636
+ *
1637
+ * @note The track must be loaded or this function will always return false.
1638
+ * @see sp_track_is_loaded()
1639
+ */
1640
+ SP_LIBEXPORT(bool) sp_track_is_starred(sp_session *session, sp_track *track);
1641
+
1642
+ /**
1643
+ * Star/Unstar the specified track
1644
+ *
1645
+ * @param[in] session Session
1646
+ * @param[in] tracks Array of pointer to tracks.
1647
+ * @param[in] num_tracks Length of \p tracks array
1648
+ * @param[in] star Starred status of the track
1649
+ *
1650
+ * @note This will fail silently if playlists are disabled.
1651
+ * @see sp_set_playlists_enabled()
1652
+ */
1653
+ SP_LIBEXPORT(sp_error) sp_track_set_starred(sp_session *session, sp_track *const*tracks, int num_tracks, bool star);
1654
+
1655
+ /**
1656
+ * The number of artists performing on the specified track
1657
+ *
1658
+ * @param[in] track The track whose number of participating artists you are interested in
1659
+ *
1660
+ * @return The number of artists performing on the specified track.
1661
+ * If no metadata is available for the track yet, this function returns 0.
1662
+ */
1663
+ SP_LIBEXPORT(int) sp_track_num_artists(sp_track *track);
1664
+
1665
+ /**
1666
+ * The artist matching the specified index performing on the current track.
1667
+ *
1668
+ * @param[in] track The track whose participating artist you are interested in
1669
+ * @param[in] index The index for the participating artist. Should be in the interval [0, sp_track_num_artists() - 1]
1670
+ *
1671
+ * @return The participating artist, or NULL if invalid index
1672
+ */
1673
+ SP_LIBEXPORT(sp_artist *) sp_track_artist(sp_track *track, int index);
1674
+
1675
+ /**
1676
+ * The album of the specified track
1677
+ *
1678
+ * @param[in] track A track object
1679
+ *
1680
+ * @return The album of the given track. You need to increase the refcount
1681
+ * if you want to keep the pointer around.
1682
+ * If no metadata is available for the track yet, this function returns 0.
1683
+ */
1684
+ SP_LIBEXPORT(sp_album *) sp_track_album(sp_track *track);
1685
+
1686
+ /**
1687
+ * The string representation of the specified track's name
1688
+ *
1689
+ * @param[in] track A track object
1690
+ *
1691
+ * @return The string representation of the specified track's name.
1692
+ * Returned string is valid as long as the album object stays allocated
1693
+ * and no longer than the next call to sp_session_process_events()
1694
+ * If no metadata is available for the track yet, this function returns empty string.
1695
+ */
1696
+ SP_LIBEXPORT(const char *) sp_track_name(sp_track *track);
1697
+
1698
+ /**
1699
+ * The duration, in milliseconds, of the specified track
1700
+ *
1701
+ * @param[in] track A track object
1702
+ *
1703
+ * @return The duration of the specified track, in milliseconds
1704
+ * If no metadata is available for the track yet, this function returns 0.
1705
+ */
1706
+ SP_LIBEXPORT(int) sp_track_duration(sp_track *track);
1707
+
1708
+ /**
1709
+ * Returns popularity for track
1710
+ *
1711
+ * @param[in] track A track object
1712
+ *
1713
+ * @return Popularity in range 0 to 100, 0 if undefined.
1714
+ * If no metadata is available for the track yet, this function returns 0.
1715
+ */
1716
+ SP_LIBEXPORT(int) sp_track_popularity(sp_track *track);
1717
+
1718
+ /**
1719
+ * Returns the disc number for a track
1720
+ *
1721
+ * @param[in] track A track object
1722
+ *
1723
+ * @return Disc index. Possible values are [1, total number of discs on album]
1724
+ * This function returns valid data only for tracks appearing in a browse
1725
+ * artist or browse album result (otherwise returns 0).
1726
+ */
1727
+ SP_LIBEXPORT(int) sp_track_disc(sp_track *track);
1728
+
1729
+ /**
1730
+ * Returns the position of a track on its disc
1731
+ *
1732
+ * @param[in] track A track object
1733
+ *
1734
+ * @return Track position, starts at 1 (relative the corresponding disc)
1735
+ * This function returns valid data only for tracks appearing in a browse
1736
+ * artist or browse album result (otherwise returns 0).
1737
+ */
1738
+ SP_LIBEXPORT(int) sp_track_index(sp_track *track);
1739
+
1740
+ /**
1741
+ * Returns the newly created local track
1742
+ *
1743
+ * @param[in] artist Name of the artist
1744
+ * @param[in] title Song title
1745
+ * @param[in] album Name of the album, or an empty string if not available
1746
+ * @param[in] length Length in MS, or -1 if not available.
1747
+ *
1748
+ * @return A track.
1749
+ */
1750
+ SP_LIBEXPORT(sp_track *) sp_localtrack_create(const char *artist, const char *title, const char *album, int length);
1751
+
1752
+ /**
1753
+ * Increase the reference count of a track
1754
+ *
1755
+ * @param[in] track The track object
1756
+ * @return One of the following errors, from ::sp_error
1757
+ * SP_ERROR_OK
1758
+ */
1759
+ SP_LIBEXPORT(sp_error) sp_track_add_ref(sp_track *track);
1760
+
1761
+ /**
1762
+ * Decrease the reference count of a track
1763
+ *
1764
+ * @param[in] track The track object
1765
+ * @return One of the following errors, from ::sp_error
1766
+ * SP_ERROR_OK
1767
+ */
1768
+ SP_LIBEXPORT(sp_error) sp_track_release(sp_track *track);
1769
+
1770
+ /** @} */
1771
+
1772
+
1773
+
1774
+ /**
1775
+ * @defgroup album Album subsystem
1776
+ * @{
1777
+ */
1778
+
1779
+ /**
1780
+ * Album types
1781
+ */
1782
+ typedef enum {
1783
+ SP_ALBUMTYPE_ALBUM = 0, ///< Normal album
1784
+ SP_ALBUMTYPE_SINGLE = 1, ///< Single
1785
+ SP_ALBUMTYPE_COMPILATION = 2, ///< Compilation
1786
+ SP_ALBUMTYPE_UNKNOWN = 3, ///< Unknown type
1787
+ } sp_albumtype;
1788
+
1789
+ /**
1790
+ * Check if the album object is populated with data
1791
+ *
1792
+ * @param[in] album Album object
1793
+ * @return True if metadata is present, false if not
1794
+ */
1795
+ SP_LIBEXPORT(bool) sp_album_is_loaded(sp_album *album);
1796
+
1797
+
1798
+ /**
1799
+ * Return true if the album is available in the current region.
1800
+ *
1801
+ * @param[in] album The album
1802
+ *
1803
+ * @return True if album is available for playback, otherwise false.
1804
+ *
1805
+ * @note The album must be loaded or this function will always return false.
1806
+ * @see sp_album_is_loaded()
1807
+ */
1808
+ SP_LIBEXPORT(bool) sp_album_is_available(sp_album *album);
1809
+
1810
+ /**
1811
+ * Get the artist associated with the given album
1812
+ *
1813
+ * @param[in] album Album object
1814
+ * @return A reference to the artist. NULL if the metadata has not been loaded yet
1815
+ */
1816
+ SP_LIBEXPORT(sp_artist *) sp_album_artist(sp_album *album);
1817
+
1818
+ /**
1819
+ * Return image ID representing the album's coverart.
1820
+ *
1821
+ * @param[in] album Album object
1822
+ * @param[in] size The desired size of the image
1823
+ *
1824
+ * @return ID byte sequence that can be passed to sp_image_create()
1825
+ * If the album has no image or the metadata for the album is not
1826
+ * loaded yet, this function returns NULL.
1827
+ *
1828
+ * @see sp_image_create
1829
+ */
1830
+ SP_LIBEXPORT(const byte *) sp_album_cover(sp_album *album, sp_image_size size);
1831
+
1832
+ /**
1833
+ * Return name of album
1834
+ *
1835
+ * @param[in] album Album object
1836
+ *
1837
+ * @return Name of album.
1838
+ * Returned string is valid as long as the album object stays allocated
1839
+ * and no longer than the next call to sp_session_process_events()
1840
+ */
1841
+ SP_LIBEXPORT(const char *) sp_album_name(sp_album *album);
1842
+
1843
+ /**
1844
+ * Return release year of specified album
1845
+ *
1846
+ * @param[in] album Album object
1847
+ *
1848
+ * @return Release year
1849
+ */
1850
+ SP_LIBEXPORT(int) sp_album_year(sp_album *album);
1851
+
1852
+
1853
+ /**
1854
+ * Return type of specified album
1855
+ *
1856
+ * @param[in] album Album object
1857
+ *
1858
+ * @return sp_albumtype
1859
+ */
1860
+ SP_LIBEXPORT(sp_albumtype) sp_album_type(sp_album *album);
1861
+
1862
+
1863
+ /**
1864
+ * Increase the reference count of an album
1865
+ *
1866
+ * @param[in] album The album object
1867
+ * @return One of the following errors, from ::sp_error
1868
+ * SP_ERROR_OK
1869
+ */
1870
+ SP_LIBEXPORT(sp_error) sp_album_add_ref(sp_album *album);
1871
+
1872
+ /**
1873
+ * Decrease the reference count of an album
1874
+ *
1875
+ * @param[in] album The album object
1876
+ * @return One of the following errors, from ::sp_error
1877
+ * SP_ERROR_OK
1878
+ */
1879
+ SP_LIBEXPORT(sp_error) sp_album_release(sp_album *album);
1880
+
1881
+ /** @} */
1882
+
1883
+
1884
+
1885
+ /**
1886
+ * @defgroup artist Artist subsystem
1887
+ * @{
1888
+ */
1889
+
1890
+ /**
1891
+ * Return name of artist
1892
+ *
1893
+ * @param[in] artist Artist object
1894
+ *
1895
+ * @return Name of artist.
1896
+ * Returned string is valid as long as the artist object stays allocated
1897
+ * and no longer than the next call to sp_session_process_events()
1898
+ */
1899
+ SP_LIBEXPORT(const char *) sp_artist_name(sp_artist *artist);
1900
+
1901
+ /**
1902
+ * Check if the artist object is populated with data
1903
+ *
1904
+ * @param[in] artist An artist object
1905
+ *
1906
+ * @return True if metadata is present, false if not
1907
+ *
1908
+ */
1909
+ SP_LIBEXPORT(bool) sp_artist_is_loaded(sp_artist *artist);
1910
+
1911
+ /**
1912
+ * Return portrait for artist
1913
+ *
1914
+ * @param[in] artist The artist object
1915
+ * @param[in] size The desired size of the image
1916
+ *
1917
+ * @return ID byte sequence that can be passed to sp_image_create()
1918
+ * If the artist has no image or the metadata for the album is not
1919
+ * loaded yet, this function returns NULL.
1920
+ *
1921
+ */
1922
+ SP_LIBEXPORT(const byte *) sp_artist_portrait(sp_artist *artist, sp_image_size size);
1923
+
1924
+ /**
1925
+ * Increase the reference count of a artist
1926
+ *
1927
+ * @param[in] artist The artist object
1928
+ * @return One of the following errors, from ::sp_error
1929
+ * SP_ERROR_OK
1930
+ */
1931
+ SP_LIBEXPORT(sp_error) sp_artist_add_ref(sp_artist *artist);
1932
+
1933
+ /**
1934
+ * Decrease the reference count of a artist
1935
+ *
1936
+ * @param[in] artist The artist object
1937
+ * @return One of the following errors, from ::sp_error
1938
+ * SP_ERROR_OK
1939
+ */
1940
+ SP_LIBEXPORT(sp_error) sp_artist_release(sp_artist *artist);
1941
+
1942
+ /** @} */
1943
+
1944
+
1945
+ /**
1946
+ * @defgroup albumbrowse Album browsing
1947
+ *
1948
+ * Browsing adds additional information to what an ::sp_album holds. It retrieves
1949
+ * copyrights, reviews and tracks of the album.
1950
+ *
1951
+ * @{
1952
+ */
1953
+
1954
+ /**
1955
+ * The type of a callback used in sp_albumbrowse_create()
1956
+ *
1957
+ * When the callback is called, the metadata of all tracks belonging to it will have
1958
+ * been loaded, so sp_track_is_loaded() will return non-zero. The ::sp_artist of the
1959
+ * album will also have been fully loaded.
1960
+ *
1961
+ * @param[in] result The same pointer returned by sp_albumbrowse_create()
1962
+ * @param[in] userdata The opaque pointer given to sp_albumbrowse_create()
1963
+ */
1964
+ typedef void SP_CALLCONV albumbrowse_complete_cb(sp_albumbrowse *result, void *userdata);
1965
+
1966
+ /**
1967
+ * Initiate a request for browsing an album
1968
+ *
1969
+ * The user is responsible for freeing the returned album browse using sp_albumbrowse_release(). This can be done in the callback.
1970
+ *
1971
+ * @param[in] session Session object
1972
+ * @param[in] album Album to be browsed. The album metadata does not have to be loaded
1973
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
1974
+ * @param[in] userdata Userdata passed to callback.
1975
+ *
1976
+ * @return Album browse object
1977
+ *
1978
+ * @see ::albumbrowse_complete_cb
1979
+ */
1980
+ SP_LIBEXPORT(sp_albumbrowse *) sp_albumbrowse_create(sp_session *session, sp_album *album, albumbrowse_complete_cb *callback, void *userdata);
1981
+
1982
+ /**
1983
+ * Check if an album browse request is completed
1984
+ *
1985
+ * @param[in] alb Album browse object
1986
+ *
1987
+ * @return True if browsing is completed, false if not
1988
+ */
1989
+ SP_LIBEXPORT(bool) sp_albumbrowse_is_loaded(sp_albumbrowse *alb);
1990
+
1991
+
1992
+ /**
1993
+ * Check if browsing returned an error code.
1994
+ *
1995
+ * @param[in] alb Album browse object
1996
+ *
1997
+ * @return One of the following errors, from ::sp_error
1998
+ * SP_ERROR_OK
1999
+ * SP_ERROR_IS_LOADING
2000
+ * SP_ERROR_OTHER_PERMANENT
2001
+ * SP_ERROR_OTHER_TRANSIENT
2002
+ */
2003
+ SP_LIBEXPORT(sp_error) sp_albumbrowse_error(sp_albumbrowse *alb);
2004
+
2005
+ /**
2006
+ * Given an album browse object, return the pointer to its album object
2007
+ *
2008
+ * @param[in] alb Album browse object
2009
+ *
2010
+ * @return Album object
2011
+ */
2012
+ SP_LIBEXPORT(sp_album *) sp_albumbrowse_album(sp_albumbrowse *alb);
2013
+
2014
+ /**
2015
+ * Given an album browse object, return the pointer to its artist object
2016
+ *
2017
+ * @param[in] alb Album browse object
2018
+ *
2019
+ * @return Artist object
2020
+ */
2021
+ SP_LIBEXPORT(sp_artist *) sp_albumbrowse_artist(sp_albumbrowse *alb);
2022
+
2023
+ /**
2024
+ * Given an album browse object, return number of copyright strings
2025
+ *
2026
+ * @param[in] alb Album browse object
2027
+ *
2028
+ * @return Number of copyright strings available, 0 if unknown
2029
+ */
2030
+ SP_LIBEXPORT(int) sp_albumbrowse_num_copyrights(sp_albumbrowse *alb);
2031
+
2032
+ /**
2033
+ * Given an album browse object, return one of its copyright strings
2034
+ *
2035
+ * @param[in] alb Album browse object
2036
+ * @param[in] index The index for the copyright string. Should be in the interval [0, sp_albumbrowse_num_copyrights() - 1]
2037
+ *
2038
+ * @return Copyright string in UTF-8 format, or NULL if the index is invalid.
2039
+ * Returned string is valid as long as the album object stays allocated
2040
+ * and no longer than the next call to sp_session_process_events()
2041
+ */
2042
+ SP_LIBEXPORT(const char *) sp_albumbrowse_copyright(sp_albumbrowse *alb, int index);
2043
+
2044
+ /**
2045
+ * Given an album browse object, return number of tracks
2046
+ *
2047
+ * @param[in] alb Album browse object
2048
+ *
2049
+ * @return Number of tracks on album
2050
+ */
2051
+ SP_LIBEXPORT(int) sp_albumbrowse_num_tracks(sp_albumbrowse *alb);
2052
+
2053
+ /**
2054
+ * Given an album browse object, return a pointer to one of its tracks
2055
+ *
2056
+ * @param[in] alb Album browse object
2057
+ * @param[in] index The index for the track. Should be in the interval [0, sp_albumbrowse_num_tracks() - 1]
2058
+ *
2059
+ * @return A track.
2060
+ *
2061
+ * @see track
2062
+ */
2063
+ SP_LIBEXPORT(sp_track *) sp_albumbrowse_track(sp_albumbrowse *alb, int index);
2064
+
2065
+ /**
2066
+ * Given an album browse object, return its review
2067
+ *
2068
+ * @param[in] alb Album browse object
2069
+ *
2070
+ * @return Review string in UTF-8 format.
2071
+ * Returned string is valid as long as the album object stays allocated
2072
+ * and no longer than the next call to sp_session_process_events()
2073
+ */
2074
+ SP_LIBEXPORT(const char *) sp_albumbrowse_review(sp_albumbrowse *alb);
2075
+
2076
+ /**
2077
+ * Return the time (in ms) that was spent waiting for the Spotify backend to serve the request
2078
+ *
2079
+ * @param[in] alb Album browse object
2080
+ *
2081
+ * @return -1 if the request was served from the local cache
2082
+ * If the result is not yet loaded the return value is undefined
2083
+ */
2084
+ SP_LIBEXPORT(int) sp_albumbrowse_backend_request_duration(sp_albumbrowse *alb);
2085
+
2086
+
2087
+ /**
2088
+ * Increase the reference count of an album browse result
2089
+ *
2090
+ * @param[in] alb The album browse result object
2091
+ * @return One of the following errors, from ::sp_error
2092
+ * SP_ERROR_OK
2093
+ */
2094
+ SP_LIBEXPORT(sp_error) sp_albumbrowse_add_ref(sp_albumbrowse *alb);
2095
+
2096
+ /**
2097
+ * Decrease the reference count of an album browse result
2098
+ *
2099
+ * @param[in] alb The album browse result object
2100
+ * @return One of the following errors, from ::sp_error
2101
+ * SP_ERROR_OK
2102
+ */
2103
+ SP_LIBEXPORT(sp_error) sp_albumbrowse_release(sp_albumbrowse *alb);
2104
+
2105
+ /** @} */
2106
+
2107
+
2108
+ /**
2109
+ * @defgroup artistbrowse Artist browsing
2110
+ *
2111
+ * Artist browsing initiates the fetching of information for a certain artist.
2112
+ *
2113
+ * @note There is currently no built-in functionality available for getting the albums belonging
2114
+ * to an artist. For now, just iterate over all tracks and note the album to build a list of all albums.
2115
+ * This feature will be added in a future version of the library.
2116
+ *
2117
+ * @{
2118
+ */
2119
+
2120
+ /**
2121
+ * The type of a callback used in sp_artistbrowse_create()
2122
+ *
2123
+ * When the callback is called, the metadata of all tracks belonging to it will have
2124
+ * been loaded, so sp_track_is_loaded() will return non-zero. The same goes for the
2125
+ * similar artist data.
2126
+ *
2127
+ * @param[in] result The same pointer returned by sp_artistbrowse_create()
2128
+ * @param[in] userdata The opaque pointer given to sp_artistbrowse_create()
2129
+ */
2130
+ typedef void SP_CALLCONV artistbrowse_complete_cb(sp_artistbrowse *result, void *userdata);
2131
+
2132
+ /**
2133
+ * Initiate a request for browsing an artist
2134
+ *
2135
+ * The user is responsible for freeing the returned artist browse using sp_artistbrowse_release(). This can be done in the callback.
2136
+ *
2137
+ * @param[in] session Session object
2138
+ * @param[in] artist Artist to be browsed. The artist metadata does not have to be loaded
2139
+ * @param[in] type Type of data requested, see the sp_artistbrowse_type enum for details
2140
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
2141
+ * @param[in] userdata Userdata passed to callback.
2142
+ *
2143
+ * @return Artist browse object
2144
+ *
2145
+ * @see ::artistbrowse_complete_cb
2146
+ */
2147
+ SP_LIBEXPORT(sp_artistbrowse *) sp_artistbrowse_create(sp_session *session, sp_artist *artist, sp_artistbrowse_type type, artistbrowse_complete_cb *callback, void *userdata);
2148
+
2149
+ /**
2150
+ * Check if an artist browse request is completed
2151
+ *
2152
+ * @param[in] arb Artist browse object
2153
+ *
2154
+ * @return True if browsing is completed, false if not
2155
+ */
2156
+ SP_LIBEXPORT(bool) sp_artistbrowse_is_loaded(sp_artistbrowse *arb);
2157
+
2158
+ /**
2159
+ * Check if browsing returned an error code.
2160
+ *
2161
+ * @param[in] arb Artist browse object
2162
+ *
2163
+ * @return One of the following errors, from ::sp_error
2164
+ * SP_ERROR_OK
2165
+ * SP_ERROR_IS_LOADING
2166
+ * SP_ERROR_OTHER_PERMANENT
2167
+ * SP_ERROR_OTHER_TRANSIENT
2168
+ */
2169
+ SP_LIBEXPORT(sp_error) sp_artistbrowse_error(sp_artistbrowse *arb);
2170
+
2171
+ /**
2172
+ * Given an artist browse object, return a pointer to its artist object
2173
+ *
2174
+ * @param[in] arb Artist browse object
2175
+ *
2176
+ * @return Artist object
2177
+ */
2178
+ SP_LIBEXPORT(sp_artist *) sp_artistbrowse_artist(sp_artistbrowse *arb);
2179
+
2180
+ /**
2181
+ * Given an artist browse object, return number of portraits available
2182
+ *
2183
+ * @param[in] arb Artist browse object
2184
+ *
2185
+ * @return Number of portraits for given artist
2186
+ */
2187
+ SP_LIBEXPORT(int) sp_artistbrowse_num_portraits(sp_artistbrowse *arb);
2188
+
2189
+ /**
2190
+ * Return image ID representing a portrait of the artist
2191
+ *
2192
+ * @param[in] arb Artist object
2193
+ * @param[in] index The index of the portrait. Should be in the interval [0, sp_artistbrowse_num_portraits() - 1]
2194
+ *
2195
+ * @return ID byte sequence that can be passed to sp_image_create()
2196
+ *
2197
+ * @see sp_image_create
2198
+ */
2199
+ SP_LIBEXPORT(const byte *) sp_artistbrowse_portrait(sp_artistbrowse *arb, int index);
2200
+
2201
+ /**
2202
+ * Given an artist browse object, return number of tracks
2203
+ *
2204
+ * @param[in] arb Artist browse object
2205
+ *
2206
+ * @return Number of tracks for given artist
2207
+ */
2208
+ SP_LIBEXPORT(int) sp_artistbrowse_num_tracks(sp_artistbrowse *arb);
2209
+
2210
+ /**
2211
+ * Given an artist browse object, return one of its tracks
2212
+ *
2213
+ * @param[in] arb Album browse object
2214
+ * @param[in] index The index for the track. Should be in the interval [0, sp_artistbrowse_num_tracks() - 1]
2215
+ *
2216
+ * @return A track object, or NULL if the index is out of range.
2217
+ *
2218
+ * @see track
2219
+ */
2220
+ SP_LIBEXPORT(sp_track *) sp_artistbrowse_track(sp_artistbrowse *arb, int index);
2221
+
2222
+
2223
+ /**
2224
+ * Given an artist browse object, return number of tophit tracks
2225
+ * This is a set of tracks for the artist with highest popularity
2226
+ *
2227
+ * @param[in] arb Artist browse object
2228
+ *
2229
+ * @return Number of tophit tracks for given artist
2230
+ */
2231
+ SP_LIBEXPORT(int) sp_artistbrowse_num_tophit_tracks(sp_artistbrowse *arb);
2232
+
2233
+ /**
2234
+ * Given an artist browse object, return one of its tophit tracks
2235
+ * This is a set of tracks for the artist with highest popularity
2236
+ *
2237
+ * @param[in] arb Album browse object
2238
+ * @param[in] index The index for the track. Should be in the interval [0, sp_artistbrowse_num_tophit_tracks() - 1]
2239
+ *
2240
+ * @return A track object, or NULL if the index is out of range.
2241
+ *
2242
+ * @see track
2243
+ */
2244
+ SP_LIBEXPORT(sp_track *) sp_artistbrowse_tophit_track(sp_artistbrowse *arb, int index);
2245
+
2246
+ /**
2247
+ * Given an artist browse object, return number of albums
2248
+ *
2249
+ * @param[in] arb Artist browse object
2250
+ *
2251
+ * @return Number of albums for given artist
2252
+ */
2253
+ SP_LIBEXPORT(int) sp_artistbrowse_num_albums(sp_artistbrowse *arb);
2254
+
2255
+ /**
2256
+ * Given an artist browse object, return one of its albums
2257
+ *
2258
+ * @param[in] arb Album browse object
2259
+ * @param[in] index The index for the album. Should be in the interval [0, sp_artistbrowse_num_albums() - 1]
2260
+ *
2261
+ * @return A album object, or NULL if the index is out of range.
2262
+ *
2263
+ * @see album
2264
+ */
2265
+ SP_LIBEXPORT(sp_album *) sp_artistbrowse_album(sp_artistbrowse *arb, int index);
2266
+
2267
+ /**
2268
+ * Given an artist browse object, return number of similar artists
2269
+ *
2270
+ * @param[in] arb Artist browse object
2271
+ *
2272
+ * @return Number of similar artists for given artist
2273
+ */
2274
+ SP_LIBEXPORT(int) sp_artistbrowse_num_similar_artists(sp_artistbrowse *arb);
2275
+
2276
+ /**
2277
+ * Given an artist browse object, return a similar artist by index
2278
+ *
2279
+ * @param[in] arb Album browse object
2280
+ * @param[in] index The index for the artist. Should be in the interval [0, sp_artistbrowse_num_similar_artists() - 1]
2281
+ *
2282
+ * @return A pointer to an artist object.
2283
+ *
2284
+ * @see artist
2285
+ */
2286
+ SP_LIBEXPORT(sp_artist *) sp_artistbrowse_similar_artist(sp_artistbrowse *arb, int index);
2287
+
2288
+ /**
2289
+ * Given an artist browse object, return the artists biography
2290
+ *
2291
+ * @note This function must be called from the same thread that did sp_session_create()
2292
+ * @param[in] arb Artist browse object
2293
+ *
2294
+ * @return Biography string in UTF-8 format.
2295
+ * Returned string is valid as long as the album object stays allocated
2296
+ * and no longer than the next call to sp_session_process_events()
2297
+ */
2298
+ SP_LIBEXPORT(const char *) sp_artistbrowse_biography(sp_artistbrowse *arb);
2299
+
2300
+ /**
2301
+ * Return the time (in ms) that was spent waiting for the Spotify backend to serve the request
2302
+ *
2303
+ * @param[in] arb Artist browse object
2304
+ *
2305
+ * @return -1 if the request was served from the local cache
2306
+ * If the result is not yet loaded the return value is undefined
2307
+ */
2308
+ SP_LIBEXPORT(int) sp_artistbrowse_backend_request_duration(sp_artistbrowse *arb);
2309
+
2310
+
2311
+ /**
2312
+ * Increase the reference count of an artist browse result
2313
+ *
2314
+ * @param[in] arb The artist browse result object
2315
+ * @return One of the following errors, from ::sp_error
2316
+ * SP_ERROR_OK
2317
+ */
2318
+ SP_LIBEXPORT(sp_error) sp_artistbrowse_add_ref(sp_artistbrowse *arb);
2319
+
2320
+ /**
2321
+ * Decrease the reference count of an artist browse result
2322
+ *
2323
+ * @param[in] arb The artist browse result object
2324
+ * @return One of the following errors, from ::sp_error
2325
+ * SP_ERROR_OK
2326
+ */
2327
+ SP_LIBEXPORT(sp_error) sp_artistbrowse_release(sp_artistbrowse *arb);
2328
+
2329
+ /** @} */
2330
+
2331
+
2332
+
2333
+ /**
2334
+ * @defgroup image Image handling
2335
+ * @{
2336
+ */
2337
+
2338
+ /**
2339
+ * Image format
2340
+ */
2341
+ typedef enum {
2342
+ SP_IMAGE_FORMAT_UNKNOWN = -1, ///< Unknown image format
2343
+ SP_IMAGE_FORMAT_JPEG = 0, ///< JPEG image
2344
+ } sp_imageformat;
2345
+
2346
+ /**
2347
+ * The type of a callback used to notify the application that an image
2348
+ * is done loading.
2349
+ */
2350
+ typedef void SP_CALLCONV image_loaded_cb(sp_image *image, void *userdata);
2351
+
2352
+ /**
2353
+ * Create an image object
2354
+ *
2355
+ * @param[in] session Session
2356
+ * @param[in] image_id Spotify image ID
2357
+ *
2358
+ * @return Pointer to an image object. To free the object, use
2359
+ * sp_image_release()
2360
+ *
2361
+ * @see sp_album_cover
2362
+ * @see sp_artistbrowse_portrait
2363
+ */
2364
+ SP_LIBEXPORT(sp_image *) sp_image_create(sp_session *session, const byte image_id[20]);
2365
+
2366
+ /**
2367
+ * Create an image object from a link
2368
+ *
2369
+ * @param[in] session Session
2370
+ * @param[in] l Spotify link object. This must be of SP_LINKTYPE_IMAGE type
2371
+ *
2372
+ * @return Pointer to an image object. To free the object, use
2373
+ * sp_image_release()
2374
+ *
2375
+ * @see sp_image_create
2376
+ */
2377
+ SP_LIBEXPORT(sp_image *) sp_image_create_from_link(sp_session *session, sp_link *l);
2378
+
2379
+ /**
2380
+ * Add a callback that will be invoked when the image is loaded
2381
+ *
2382
+ * If an image is loaded, and loading fails, the image will behave like an
2383
+ * empty image.
2384
+ *
2385
+ * @param[in] image Image object
2386
+ * @param[in] callback Callback that will be called when image has been
2387
+ * fetched.
2388
+ * @param[in] userdata Opaque pointer passed to \p callback
2389
+ *
2390
+ */
2391
+ SP_LIBEXPORT(sp_error) sp_image_add_load_callback(sp_image *image, image_loaded_cb *callback, void *userdata);
2392
+
2393
+ /**
2394
+ * Remove an image load callback previously added with sp_image_add_load_callback()
2395
+ *
2396
+ * @param[in] image Image object
2397
+ * @param[in] callback Callback that will not be called when image has been
2398
+ * fetched.
2399
+ * @param[in] userdata Opaque pointer passed to \p callback
2400
+ * @return One of the following errors, from ::sp_error
2401
+ * SP_ERROR_OK
2402
+ */
2403
+ SP_LIBEXPORT(sp_error) sp_image_remove_load_callback(sp_image *image, image_loaded_cb *callback, void *userdata);
2404
+
2405
+ /**
2406
+ * Check if an image is loaded. Before the image is loaded, the rest of the
2407
+ * methods will behave as if the image is empty.
2408
+ *
2409
+ * @param[in] image Image object
2410
+ *
2411
+ * @return True if image is loaded, false otherwise
2412
+ */
2413
+ SP_LIBEXPORT(bool) sp_image_is_loaded(sp_image *image);
2414
+
2415
+ /**
2416
+ * Check if image retrieval returned an error code.
2417
+ *
2418
+ * @param[in] image Image object
2419
+ *
2420
+ * @return One of the following errors, from ::sp_error
2421
+ * SP_ERROR_OK
2422
+ * SP_ERROR_IS_LOADING
2423
+ * SP_ERROR_OTHER_PERMANENT
2424
+ * SP_ERROR_OTHER_TRANSIENT
2425
+ */
2426
+ SP_LIBEXPORT(sp_error) sp_image_error(sp_image *image);
2427
+
2428
+ /**
2429
+ * Get image format
2430
+ *
2431
+ * @param[in] image Image object
2432
+ *
2433
+ * @return Image format as described by sp_imageformat
2434
+ */
2435
+ SP_LIBEXPORT(sp_imageformat) sp_image_format(sp_image *image);
2436
+
2437
+ /**
2438
+ * Get image data
2439
+ *
2440
+ * @param[in] image Image object
2441
+ * @param[out] data_size Size of raw image data
2442
+ *
2443
+ * @return Pointer to raw image data
2444
+ */
2445
+
2446
+ SP_LIBEXPORT(const void *) sp_image_data(sp_image *image, size_t *data_size);
2447
+
2448
+ /**
2449
+ * Get image ID
2450
+ *
2451
+ * @param[in] image Image object
2452
+ *
2453
+ * @return Image ID
2454
+ */
2455
+ SP_LIBEXPORT(const byte *) sp_image_image_id(sp_image *image);
2456
+
2457
+
2458
+ /**
2459
+ * Increase the reference count of an image
2460
+ *
2461
+ * @param[in] image The image object
2462
+ * @return One of the following errors, from ::sp_error
2463
+ * SP_ERROR_OK
2464
+ */
2465
+ SP_LIBEXPORT(sp_error) sp_image_add_ref(sp_image *image);
2466
+
2467
+ /**
2468
+ * Decrease the reference count of an image
2469
+ *
2470
+ * @param[in] image The image object
2471
+ * @return One of the following errors, from ::sp_error
2472
+ * SP_ERROR_OK
2473
+ */
2474
+ SP_LIBEXPORT(sp_error) sp_image_release(sp_image *image);
2475
+
2476
+ /** @} */
2477
+
2478
+
2479
+
2480
+ /**
2481
+ * @defgroup search Search subsystem
2482
+ * @{
2483
+ */
2484
+
2485
+ /**
2486
+ * The type of a callback used in sp_search_create()
2487
+ *
2488
+ * When this callback is called, the sp_track_is_loaded(), sp_album_is_loaded(),
2489
+ * and sp_artist_is_loaded() functions will return non-zero for the objects
2490
+ * contained in the search result.
2491
+ *
2492
+ * @param[in] result The same pointer returned by sp_search_create()
2493
+ * @param[in] userdata The opaque pointer given to sp_search_create()
2494
+ */
2495
+ typedef void SP_CALLCONV search_complete_cb(sp_search *result, void *userdata);
2496
+
2497
+ /**
2498
+ * Create a search object from the given query
2499
+ *
2500
+ * @param[in] session Session
2501
+ * @param[in] query Query search string, e.g. 'The Rolling Stones' or 'album:"The Black Album"'
2502
+ * @param[in] track_offset The offset among the tracks of the result
2503
+ * @param[in] track_count The number of tracks to ask for
2504
+ * @param[in] album_offset The offset among the albums of the result
2505
+ * @param[in] album_count The number of albums to ask for
2506
+ * @param[in] artist_offset The offset among the artists of the result
2507
+ * @param[in] artist_count The number of artists to ask for
2508
+ * @param[in] playlist_offset The offset among the playlists of the result
2509
+ * @param[in] playlist_count The number of playlists to ask for
2510
+ * @param[in] search_type Type of search, can be used for suggest searches
2511
+ * @param[in] callback Callback that will be called once the search operation is complete. Pass NULL if you are not interested in this event.
2512
+ * @param[in] userdata Opaque pointer passed to \p callback
2513
+ *
2514
+ * @return Pointer to a search object. To free the object, use sp_search_release()
2515
+ */
2516
+ SP_LIBEXPORT(sp_search *) sp_search_create(sp_session *session, const char *query, int track_offset, int track_count, int album_offset, int album_count, int artist_offset, int artist_count, int playlist_offset, int playlist_count, sp_search_type search_type, search_complete_cb *callback, void *userdata);
2517
+
2518
+ /**
2519
+ * Get load status for the specified search. Before it is loaded, it will behave as an empty search result.
2520
+ *
2521
+ * @param[in] search Search object
2522
+ *
2523
+ * @return True if search is loaded, otherwise false
2524
+ */
2525
+ SP_LIBEXPORT(bool) sp_search_is_loaded(sp_search *search);
2526
+
2527
+ /**
2528
+ * Check if search returned an error code.
2529
+ *
2530
+ * @param[in] search Search object
2531
+ *
2532
+ * @return One of the following errors, from ::sp_error
2533
+ * SP_ERROR_OK
2534
+ * SP_ERROR_IS_LOADING
2535
+ * SP_ERROR_OTHER_PERMANENT
2536
+ * SP_ERROR_OTHER_TRANSIENT
2537
+ */
2538
+ SP_LIBEXPORT(sp_error) sp_search_error(sp_search *search);
2539
+
2540
+ /**
2541
+ * Get the number of tracks for the specified search
2542
+ *
2543
+ * @param[in] search Search object
2544
+ *
2545
+ * @return The number of tracks for the specified search
2546
+ */
2547
+ SP_LIBEXPORT(int) sp_search_num_tracks(sp_search *search);
2548
+
2549
+ /**
2550
+ * Return the track at the given index in the given search object
2551
+ *
2552
+ * @param[in] search Search object
2553
+ * @param[in] index Index of the wanted track. Should be in the interval [0, sp_search_num_tracks() - 1]
2554
+ *
2555
+ * @return The track at the given index in the given search object
2556
+ */
2557
+ SP_LIBEXPORT(sp_track *) sp_search_track(sp_search *search, int index);
2558
+
2559
+ /**
2560
+ * Get the number of albums for the specified search
2561
+ *
2562
+ * @param[in] search Search object
2563
+ *
2564
+ * @return The number of albums for the specified search
2565
+ */
2566
+ SP_LIBEXPORT(int) sp_search_num_albums(sp_search *search);
2567
+
2568
+ /**
2569
+ * Return the album at the given index in the given search object
2570
+ *
2571
+ * @param[in] search Search object
2572
+ * @param[in] index Index of the wanted album. Should be in the interval [0, sp_search_num_albums() - 1]
2573
+ *
2574
+ * @return The album at the given index in the given search object
2575
+ */
2576
+ SP_LIBEXPORT(sp_album *) sp_search_album(sp_search *search, int index);
2577
+
2578
+ /**
2579
+ * Get the number of playlists for the specified search
2580
+ *
2581
+ * @param[in] search Search object
2582
+ *
2583
+ * @return The number of playlists for the specified search
2584
+ */
2585
+ SP_LIBEXPORT(int) sp_search_num_playlists(sp_search *search);
2586
+
2587
+ /**
2588
+ * Load the playlist at the given index in the given search object
2589
+ *
2590
+ * @param[in] search Search object
2591
+ * @param[in] index Index of the wanted playlist. Should be in the interval [0, sp_search_num_playlists() - 1]
2592
+ *
2593
+ * @return A playlist object. This reference is owned by the caller and should be released with sp_playlist_release()
2594
+ */
2595
+ SP_LIBEXPORT(sp_playlist *) sp_search_playlist(sp_search *search, int index);
2596
+
2597
+ /**
2598
+ * Return the playlist at the given index in the given search object
2599
+ *
2600
+ * @param[in] search Search object
2601
+ * @param[in] index Index of the wanted playlist. Should be in the interval [0, sp_search_num_playlists() - 1]
2602
+ *
2603
+ * @return The playlist name at the given index in the given search object
2604
+ */
2605
+ SP_LIBEXPORT(const char *) sp_search_playlist_name(sp_search *search, int index);
2606
+
2607
+ /**
2608
+ * Return the uri of a playlist at the given index in the given search object
2609
+ *
2610
+ * @param[in] search Search object
2611
+ * @param[in] index Index of the wanted playlist. Should be in the interval [0, sp_search_num_playlists() - 1]
2612
+ *
2613
+ * @return The playlist uri at the given index in the given search object
2614
+ */
2615
+ SP_LIBEXPORT(const char *) sp_search_playlist_uri(sp_search *search, int index);
2616
+
2617
+ /**
2618
+ * Return the image_uri of a playlist at the given index in the given search object
2619
+ *
2620
+ * @param[in] search Search object
2621
+ * @param[in] index Index of the wanted playlist. Should be in the interval [0, sp_search_num_playlists() - 1]
2622
+ *
2623
+ * @return The playlist image_uri at the given index in the given search object
2624
+ */
2625
+ SP_LIBEXPORT(const char *) sp_search_playlist_image_uri(sp_search *search, int index);
2626
+
2627
+ /**
2628
+ * Get the number of artists for the specified search
2629
+ *
2630
+ * @param[in] search Search object
2631
+ *
2632
+ * @return The number of artists for the specified search
2633
+ */
2634
+ SP_LIBEXPORT(int) sp_search_num_artists(sp_search *search);
2635
+
2636
+ /**
2637
+ * Return the artist at the given index in the given search object
2638
+ *
2639
+ * @param[in] search Search object
2640
+ * @param[in] index Index of the wanted artist. Should be in the interval [0, sp_search_num_artists() - 1]
2641
+ *
2642
+ * @return The artist at the given index in the given search object
2643
+ */
2644
+ SP_LIBEXPORT(sp_artist *) sp_search_artist(sp_search *search, int index);
2645
+
2646
+ /**
2647
+ * Return the search query for the given search object
2648
+ *
2649
+ * @param[in] search Search object
2650
+ *
2651
+ * @return The search query for the given search object
2652
+ */
2653
+ SP_LIBEXPORT(const char *) sp_search_query(sp_search *search);
2654
+
2655
+ /**
2656
+ * Return the "Did you mean" query for the given search object
2657
+ *
2658
+ * @param[in] search Search object
2659
+ *
2660
+ * @return The "Did you mean" query for the given search object, or the empty string if no such info is available
2661
+ */
2662
+ SP_LIBEXPORT(const char *) sp_search_did_you_mean(sp_search *search);
2663
+
2664
+ /**
2665
+ * Return the total number of tracks for the search query - regardless of the interval requested at creation.
2666
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
2667
+ * To fetch these, create a new search object with a new interval.
2668
+ *
2669
+ * @param[in] search Search object
2670
+ *
2671
+ * @return The total number of tracks matching the original query
2672
+ */
2673
+ SP_LIBEXPORT(int) sp_search_total_tracks(sp_search *search);
2674
+
2675
+ /**
2676
+ * Return the total number of albums for the search query - regardless of the interval requested at creation.
2677
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
2678
+ * To fetch these, create a new search object with a new interval.
2679
+ *
2680
+ * @param[in] search Search object
2681
+ *
2682
+ * @return The total number of albums matching the original query
2683
+ */
2684
+ SP_LIBEXPORT(int) sp_search_total_albums(sp_search *search);
2685
+
2686
+ /**
2687
+ * Return the total number of artists for the search query - regardless of the interval requested at creation.
2688
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
2689
+ * To fetch these, create a new search object with a new interval.
2690
+ *
2691
+ * @param[in] search Search object
2692
+ *
2693
+ * @return The total number of artists matching the original query
2694
+ */
2695
+ SP_LIBEXPORT(int) sp_search_total_artists(sp_search *search);
2696
+
2697
+ /**
2698
+ * Return the total number of playlists for the search query - regardless of the interval requested at creation.
2699
+ * If this value is larger than the interval specified at creation of the search object, more search results are available.
2700
+ * To fetch these, create a new search object with a new interval.
2701
+ *
2702
+ * @param[in] search Search object
2703
+ *
2704
+ * @return The total number of playlists matching the original query
2705
+ */
2706
+ SP_LIBEXPORT(int) sp_search_total_playlists(sp_search *search);
2707
+
2708
+ /**
2709
+ * Increase the reference count of a search result
2710
+ *
2711
+ * @param[in] search The search result object
2712
+ * @return One of the following errors, from ::sp_error
2713
+ * SP_ERROR_OK
2714
+ */
2715
+ SP_LIBEXPORT(sp_error) sp_search_add_ref(sp_search *search);
2716
+
2717
+ /**
2718
+ * Decrease the reference count of a search result
2719
+ *
2720
+ * @param[in] search The search result object
2721
+ * @return One of the following errors, from ::sp_error
2722
+ * SP_ERROR_OK
2723
+ */
2724
+ SP_LIBEXPORT(sp_error) sp_search_release(sp_search *search);
2725
+
2726
+ /** @} */
2727
+
2728
+
2729
+
2730
+
2731
+ /**
2732
+ * @defgroup playlist Playlist subsystem
2733
+ *
2734
+ * The playlist subsystem handles playlists and playlist containers (list of playlists).
2735
+ *
2736
+ * The playlist container functions are always valid, but your playlists are not
2737
+ * guaranteed to be loaded until the sp_session_callbacks#logged_in callback has
2738
+ * been issued.
2739
+ *
2740
+ * @{
2741
+ */
2742
+
2743
+ /**
2744
+ * Playlist callbacks
2745
+ *
2746
+ * Used to get notifications when playlists are updated.
2747
+ * If some callbacks should not be of interest, set them to NULL.
2748
+ */
2749
+ typedef struct sp_playlist_callbacks {
2750
+
2751
+ /**
2752
+ * Called when one or more tracks have been added to a playlist
2753
+ *
2754
+ * @param[in] pl Playlist object
2755
+ * @param[in] tracks Array of pointers to track objects
2756
+ * @param[in] num_tracks Number of entries in \p tracks
2757
+ * @param[in] position Position in the playlist for the first track.
2758
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2759
+ */
2760
+ void (SP_CALLCONV *tracks_added)(sp_playlist *pl, sp_track * const *tracks, int num_tracks, int position, void *userdata);
2761
+
2762
+ /**
2763
+ * Called when one or more tracks have been removed from a playlist
2764
+ *
2765
+ * @param[in] pl Playlist object
2766
+ * @param[in] tracks Array of positions representing the tracks that were removed
2767
+ * @param[in] num_tracks Number of entries in \p tracks
2768
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2769
+ */
2770
+ void (SP_CALLCONV *tracks_removed)(sp_playlist *pl, const int *tracks, int num_tracks, void *userdata);
2771
+
2772
+ /**
2773
+ * Called when one or more tracks have been moved within a playlist
2774
+ *
2775
+ * @param[in] pl Playlist object
2776
+ * @param[in] tracks Array of positions representing the tracks that were moved
2777
+ * @param[in] num_tracks Number of entries in \p tracks
2778
+ * @param[in] position New position in the playlist for the first track.
2779
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2780
+ */
2781
+ void (SP_CALLCONV *tracks_moved)(sp_playlist *pl, const int *tracks, int num_tracks, int new_position, void *userdata);
2782
+
2783
+ /**
2784
+ * Called when a playlist has been renamed. sp_playlist_name() can be used to find out the new name
2785
+ *
2786
+ * @param[in] pl Playlist object
2787
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2788
+ */
2789
+ void (SP_CALLCONV *playlist_renamed)(sp_playlist *pl, void *userdata);
2790
+
2791
+ /**
2792
+ * Called when state changed for a playlist.
2793
+ *
2794
+ * There are three states that trigger this callback:
2795
+ * - Collaboration for this playlist has been turned on or off
2796
+ * - The playlist started having pending changes, or all pending changes have now been committed
2797
+ * - The playlist started loading, or finished loading
2798
+ *
2799
+ * @param[in] pl Playlist object
2800
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2801
+ * @sa sp_playlist_is_collaborative
2802
+ * @sa sp_playlist_has_pending_changes
2803
+ * @sa sp_playlist_is_loaded
2804
+ */
2805
+ void (SP_CALLCONV *playlist_state_changed)(sp_playlist *pl, void *userdata);
2806
+
2807
+ /**
2808
+ * Called when a playlist is updating or is done updating
2809
+ *
2810
+ * This is called before and after a series of changes are applied to the
2811
+ * playlist. It allows e.g. the user interface to defer updating until the
2812
+ * entire operation is complete.
2813
+ *
2814
+ * @param[in] pl Playlist object
2815
+ * @param[in] done True iff the update is completed
2816
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2817
+ */
2818
+ void (SP_CALLCONV *playlist_update_in_progress)(sp_playlist *pl, bool done, void *userdata);
2819
+
2820
+ /**
2821
+ * Called when metadata for one or more tracks in a playlist has been updated.
2822
+ *
2823
+ * @param[in] pl Playlist object
2824
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2825
+ */
2826
+ void (SP_CALLCONV *playlist_metadata_updated)(sp_playlist *pl, void *userdata);
2827
+
2828
+ /**
2829
+ * Called when create time and/or creator for a playlist entry changes
2830
+ *
2831
+ * @param[in] pl Playlist object
2832
+ * @param[in] position Position in playlist
2833
+ * @param[in] user User object
2834
+ * @param[in] time When entry was created, seconds since the unix epoch.
2835
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2836
+ */
2837
+ void (SP_CALLCONV *track_created_changed)(sp_playlist *pl, int position, sp_user *user, int when, void *userdata);
2838
+
2839
+ /**
2840
+ * Called when seen attribute for a playlist entry changes.
2841
+ *
2842
+ * @param[in] pl Playlist object
2843
+ * @param[in] position Position in playlist
2844
+ * @param[in] seen Set if entry it marked as seen
2845
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2846
+ */
2847
+ void (SP_CALLCONV *track_seen_changed)(sp_playlist *pl, int position, bool seen, void *userdata);
2848
+
2849
+ /**
2850
+ * Called when playlist description has changed
2851
+ *
2852
+ * @param[in] pl Playlist object
2853
+ * @param[in] desc New description
2854
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2855
+ */
2856
+ void (SP_CALLCONV *description_changed)(sp_playlist *pl, const char *desc, void *userdata);
2857
+
2858
+
2859
+ /**
2860
+ * Called when playlist image has changed
2861
+ *
2862
+ * @param[in] pl Playlist object
2863
+ * @param[in] image New image
2864
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2865
+ */
2866
+ void (SP_CALLCONV *image_changed)(sp_playlist *pl, const byte *image, void *userdata);
2867
+
2868
+
2869
+ /**
2870
+ * Called when message attribute for a playlist entry changes.
2871
+ *
2872
+ * @param[in] pl Playlist object
2873
+ * @param[in] position Position in playlist
2874
+ * @param[in] message UTF-8 encoded message
2875
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2876
+ */
2877
+ void (SP_CALLCONV *track_message_changed)(sp_playlist *pl, int position, const char *message, void *userdata);
2878
+
2879
+
2880
+ /**
2881
+ * Called when playlist subscribers changes (count or list of names)
2882
+ *
2883
+ * @param[in] pl Playlist object
2884
+ * @param[in] userdata Userdata passed to sp_playlist_add_callbacks()
2885
+ */
2886
+ void (SP_CALLCONV *subscribers_changed)(sp_playlist *pl, void *userdata);
2887
+
2888
+ } sp_playlist_callbacks;
2889
+
2890
+
2891
+ /**
2892
+ * Get load status for the specified playlist. If it's false, you have to wait until
2893
+ * playlist_state_changed happens, and check again if is_loaded has changed
2894
+ *
2895
+ * @param[in] playlist Playlist object
2896
+ *
2897
+ * @return True if playlist is loaded, otherwise false
2898
+ */
2899
+ SP_LIBEXPORT(bool) sp_playlist_is_loaded(sp_playlist *playlist);
2900
+
2901
+ /**
2902
+ * Register interest in the given playlist
2903
+ *
2904
+ * Here is a snippet from \c jukebox.c:
2905
+ * @dontinclude jukebox.c
2906
+ * @skipline sp_playlist_add_callbacks
2907
+ *
2908
+ * @param[in] playlist Playlist object
2909
+ * @param[in] callbacks Callbacks, see #sp_playlist_callbacks
2910
+ * @param[in] userdata Userdata to be passed to callbacks
2911
+ * @sa sp_playlist_remove_callbacks
2912
+ *
2913
+ */
2914
+ SP_LIBEXPORT(sp_error) sp_playlist_add_callbacks(sp_playlist *playlist, sp_playlist_callbacks *callbacks, void *userdata);
2915
+
2916
+ /**
2917
+ * Unregister interest in the given playlist
2918
+ *
2919
+ * The combination of (\p callbacks, \p userdata) is used to find the entry to be removed
2920
+ *
2921
+ * Here is a snippet from \c jukebox.c:
2922
+ * @dontinclude jukebox.c
2923
+ * @skipline sp_playlist_remove_callbacks
2924
+ *
2925
+ * @param[in] playlist Playlist object
2926
+ * @param[in] callbacks Callbacks, see #sp_playlist_callbacks
2927
+ * @param[in] userdata Userdata to be passed to callbacks
2928
+ * @sa sp_playlist_add_callbacks
2929
+ * @return One of the following errors, from ::sp_error
2930
+ * SP_ERROR_OK
2931
+ *
2932
+ */
2933
+ SP_LIBEXPORT(sp_error) sp_playlist_remove_callbacks(sp_playlist *playlist, sp_playlist_callbacks *callbacks, void *userdata);
2934
+
2935
+ /**
2936
+ * Return number of tracks in the given playlist
2937
+ *
2938
+ * @param[in] playlist Playlist object
2939
+ *
2940
+ * @return The number of tracks in the playlist
2941
+ */
2942
+ SP_LIBEXPORT(int) sp_playlist_num_tracks(sp_playlist *playlist);
2943
+
2944
+ /**
2945
+ * Return the track at the given index in a playlist
2946
+ *
2947
+ * @param[in] playlist Playlist object
2948
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2949
+ *
2950
+ * @return The track at the given index
2951
+ */
2952
+ SP_LIBEXPORT(sp_track *) sp_playlist_track(sp_playlist *playlist, int index);
2953
+
2954
+ /**
2955
+ * Return when the given index was added to the playlist
2956
+ *
2957
+ * @param[in] playlist Playlist object
2958
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2959
+ *
2960
+ * @return Time, Seconds since unix epoch.
2961
+ */
2962
+ SP_LIBEXPORT(int) sp_playlist_track_create_time(sp_playlist *playlist, int index);
2963
+
2964
+ /**
2965
+ * Return user that added the given index in the playlist
2966
+ *
2967
+ * @param[in] playlist Playlist object
2968
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2969
+ *
2970
+ * @return User object
2971
+ */
2972
+ SP_LIBEXPORT(sp_user *) sp_playlist_track_creator(sp_playlist *playlist, int index);
2973
+
2974
+ /**
2975
+ * Return if a playlist entry is marked as seen or not
2976
+ *
2977
+ * @param[in] playlist Playlist object
2978
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2979
+ *
2980
+ * @return Seen state
2981
+ */
2982
+ SP_LIBEXPORT(bool) sp_playlist_track_seen(sp_playlist *playlist, int index);
2983
+
2984
+ /**
2985
+ * Set seen status of a playlist entry
2986
+ *
2987
+ * @param[in] playlist Playlist object
2988
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
2989
+ * @param[in] seen Seen status to be set
2990
+ *
2991
+ * @return error One of the following errors, from ::sp_error
2992
+ * SP_ERROR_OK
2993
+ * SP_ERROR_INDEX_OUT_OF_RANGE
2994
+ */
2995
+ SP_LIBEXPORT(sp_error) sp_playlist_track_set_seen(sp_playlist *playlist, int index, bool seen);
2996
+
2997
+ /**
2998
+ * Return a message attached to a playlist item. Typically used on inbox.
2999
+ *
3000
+ * @param[in] playlist Playlist object
3001
+ * @param[in] index Index into playlist container. Should be in the interval [0, sp_playlist_num_tracks() - 1]
3002
+ *
3003
+ * @return UTF-8 encoded message, or NULL if no message is present
3004
+ */
3005
+ SP_LIBEXPORT(const char *) sp_playlist_track_message(sp_playlist *playlist, int index);
3006
+
3007
+ /**
3008
+ * Return name of given playlist
3009
+ *
3010
+ * @param[in] playlist Playlist object
3011
+ *
3012
+ * @return The name of the given playlist
3013
+ */
3014
+ SP_LIBEXPORT(const char *) sp_playlist_name(sp_playlist *playlist);
3015
+
3016
+ /**
3017
+ * Rename the given playlist
3018
+ * The name must not consist of only spaces and it must be shorter than 256 characters.
3019
+ *
3020
+ * @param[in] playlist Playlist object
3021
+ * @param[in] new_name New name for playlist
3022
+ *
3023
+ * @return One of the following errors, from ::sp_error
3024
+ * SP_ERROR_OK
3025
+ * SP_ERROR_INVALID_INDATA
3026
+ * SP_ERROR_PERMISSION_DENIED
3027
+ */
3028
+ SP_LIBEXPORT(sp_error) sp_playlist_rename(sp_playlist *playlist, const char *new_name);
3029
+
3030
+ /**
3031
+ * Return a pointer to the user for the given playlist
3032
+ *
3033
+ * @param[in] playlist Playlist object
3034
+ *
3035
+ * @return User object
3036
+ */
3037
+ SP_LIBEXPORT(sp_user *) sp_playlist_owner(sp_playlist *playlist);
3038
+
3039
+ /**
3040
+ * Return collaborative status for a playlist.
3041
+ *
3042
+ * A playlist in collaborative state can be modifed by all users, not only the user owning the list
3043
+ *
3044
+ * @param[in] playlist Playlist object
3045
+ *
3046
+ * @return true if playlist is collaborative, otherwise false
3047
+ */
3048
+ SP_LIBEXPORT(bool) sp_playlist_is_collaborative(sp_playlist *playlist);
3049
+
3050
+ /**
3051
+ * Set collaborative status for a playlist.
3052
+ *
3053
+ * A playlist in collaborative state can be modified by all users, not only the user owning the list
3054
+ *
3055
+ * @param[in] playlist Playlist object
3056
+ * @param[in] collaborative True or false
3057
+ * @return One of the following errors, from ::sp_error
3058
+ * SP_ERROR_OK
3059
+ */
3060
+ SP_LIBEXPORT(sp_error) sp_playlist_set_collaborative(sp_playlist *playlist, bool collaborative);
3061
+
3062
+ /**
3063
+ * Set autolinking state for a playlist.
3064
+ *
3065
+ * If a playlist is autolinked, unplayable tracks will be made playable
3066
+ * by linking them to other Spotify tracks, where possible.
3067
+ *
3068
+ * @param[in] playlist Playlist object
3069
+ * @param[in] link True or false
3070
+ * @return One of the following errors, from ::sp_error
3071
+ * SP_ERROR_OK
3072
+ */
3073
+ SP_LIBEXPORT(sp_error) sp_playlist_set_autolink_tracks(sp_playlist *playlist, bool link);
3074
+
3075
+
3076
+ /**
3077
+ * Get description for a playlist
3078
+ *
3079
+ * @param[in] playlist Playlist object
3080
+ *
3081
+ * @return Playlist description or NULL if unset
3082
+ *
3083
+ */
3084
+ SP_LIBEXPORT(const char *) sp_playlist_get_description(sp_playlist *playlist);
3085
+
3086
+
3087
+ /**
3088
+ * Get description for a playlist
3089
+ *
3090
+ * @param[in] playlist Playlist object
3091
+ * @param[out] image 20 byte image id
3092
+
3093
+ * @return TRUE if playlist has an image, FALSE if not
3094
+ *
3095
+ */
3096
+ SP_LIBEXPORT(bool) sp_playlist_get_image(sp_playlist *playlist, byte image[20]);
3097
+
3098
+
3099
+ /**
3100
+ * Check if a playlist has pending changes
3101
+ *
3102
+ * Pending changes are local changes that have not yet been acknowledged by the server.
3103
+ *
3104
+ * @param[in] playlist Playlist object
3105
+ *
3106
+ * @return A flag representing if there are pending changes or not
3107
+ */
3108
+ SP_LIBEXPORT(bool) sp_playlist_has_pending_changes(sp_playlist *playlist);
3109
+
3110
+ /**
3111
+ * Add tracks to a playlist
3112
+ *
3113
+ * @param[in] playlist Playlist object
3114
+ * @param[in] tracks Array of pointer to tracks.
3115
+ * @param[in] num_tracks Length of \p tracks array
3116
+ * @param[in] position Start position in playlist where to insert the tracks
3117
+ * @param[in] session Your session object
3118
+ *
3119
+ * @return One of the following errors, from ::sp_error
3120
+ * SP_ERROR_OK
3121
+ * SP_ERROR_INVALID_INDATA - position is > current playlist length
3122
+ * SP_ERROR_PERMISSION_DENIED
3123
+ */
3124
+ SP_LIBEXPORT(sp_error) sp_playlist_add_tracks(sp_playlist *playlist, sp_track *const*tracks, int num_tracks, int position, sp_session *session);
3125
+
3126
+ /**
3127
+ * Remove tracks from a playlist
3128
+ *
3129
+ * @param[in] playlist Playlist object
3130
+ * @param[in] tracks Array of pointer to track indices.
3131
+ * A certain track index should be present at most once, e.g. [0, 1, 2] is valid indata,
3132
+ * whereas [0, 1, 1] is invalid.
3133
+ * @param[in] num_tracks Length of \p tracks array
3134
+ *
3135
+ * @return One of the following errors, from ::sp_error
3136
+ * SP_ERROR_OK
3137
+ * SP_ERROR_PERMISSION_DENIED
3138
+ */
3139
+ SP_LIBEXPORT(sp_error) sp_playlist_remove_tracks(sp_playlist *playlist, const int *tracks, int num_tracks);
3140
+
3141
+ /**
3142
+ * Move tracks in playlist
3143
+ *
3144
+ * @param[in] playlist Playlist object
3145
+ * @param[in] tracks Array of pointer to track indices to be moved.
3146
+ * A certain track index should be present at most once, e.g. [0, 1, 2] is valid indata,
3147
+ * whereas [0, 1, 1] is invalid.
3148
+ * @param[in] num_tracks Length of \p tracks array
3149
+ * @param[in] new_position New position for tracks
3150
+ *
3151
+ * @return One of the following errors, from ::sp_error
3152
+ * SP_ERROR_OK
3153
+ * SP_ERROR_INVALID_INDATA - position is > current playlist length
3154
+ * SP_ERROR_PERMISSION_DENIED
3155
+ */
3156
+ SP_LIBEXPORT(sp_error) sp_playlist_reorder_tracks(sp_playlist *playlist, const int *tracks, int num_tracks, int new_position);
3157
+
3158
+
3159
+ /**
3160
+ * Return number of subscribers for a given playlist
3161
+ *
3162
+ * @param[in] playlist Playlist object
3163
+ *
3164
+ * @return Number of subscribers
3165
+ *
3166
+ */
3167
+ SP_LIBEXPORT(unsigned int) sp_playlist_num_subscribers(sp_playlist *playlist);
3168
+
3169
+ /**
3170
+ * Return subscribers for a playlist
3171
+ *
3172
+ * @param[in] playlist Playlist object
3173
+ *
3174
+ * @return sp_subscribers struct with array of canonical usernames.
3175
+ * This object should be free'd using sp_playlist_subscribers_free()
3176
+ *
3177
+ * @note The count returned for this function may be less than those
3178
+ * returned by sp_playlist_num_subscribers(). Spotify does not
3179
+ * track each user subscribed to a playlist for playlist with
3180
+ * many (>500) subscribers.
3181
+ */
3182
+ SP_LIBEXPORT(sp_subscribers *) sp_playlist_subscribers(sp_playlist *playlist);
3183
+
3184
+ /**
3185
+ * Free object returned from sp_playlist_subscribers()
3186
+ *
3187
+ * @param[in] subscribers Subscribers object
3188
+ * @return One of the following errors, from ::sp_error
3189
+ * SP_ERROR_OK
3190
+ */
3191
+ SP_LIBEXPORT(sp_error) sp_playlist_subscribers_free(sp_subscribers *subscribers);
3192
+
3193
+ /**
3194
+ * Ask library to update the subscription count for a playlist
3195
+ *
3196
+ * When the subscription info has been fetched from the Spotify backend
3197
+ * the playlist subscribers_changed() callback will be invoked.
3198
+ * In that callback use sp_playlist_num_subscribers() and/or
3199
+ * sp_playlist_subscribers() to get information about the subscribers.
3200
+ * You can call those two functions anytime you want but the information
3201
+ * might not be up to date in such cases
3202
+ *
3203
+ * @param[in] session Session object
3204
+ * @param[in] playlist Playlist object
3205
+ * @return One of the following errors, from ::sp_error
3206
+ * SP_ERROR_OK
3207
+ */
3208
+ SP_LIBEXPORT(sp_error) sp_playlist_update_subscribers(sp_session *session, sp_playlist *playlist);
3209
+
3210
+ /**
3211
+ * Return whether a playlist is loaded in RAM (as opposed to only
3212
+ * stored on disk)
3213
+ *
3214
+ * @param[in] session Session object
3215
+ * @param[in] playlist Playlist object
3216
+ *
3217
+ * @return True iff playlist is in RAM, False otherwise
3218
+ *
3219
+ * @note When a playlist is no longer in RAM it will appear empty.
3220
+ * However, libspotify will retain information about the
3221
+ * list metadata (owner, title, picture, etc) in RAM.
3222
+ * There is one caveat tough: If libspotify has never seen the
3223
+ * playlist before this metadata will also be unset.
3224
+ * In order for libspotify to get the metadata the playlist
3225
+ * needs to be loaded at least once.
3226
+ * In order words, if libspotify starts with an empty playlist
3227
+ * cache and the application has set 'initially_unload_playlists'
3228
+ * config parameter to True all playlists will be empty.
3229
+ * It will not be possible to generate URI's to the playlists
3230
+ * nor extract playlist title until the application calls
3231
+ * sp_playlist_set_in_ram(..., true). So an application
3232
+ * that needs to stay within a low memory profile would need to
3233
+ * cycle thru all new playlists in order to extract metadata.
3234
+ *
3235
+ * The easiest way to detect this case is when
3236
+ * sp_playlist_is_in_ram() returns false and
3237
+ * sp_link_create_from_playlist() returns NULL
3238
+ */
3239
+ SP_LIBEXPORT(bool) sp_playlist_is_in_ram(sp_session *session, sp_playlist *playlist);
3240
+
3241
+ /**
3242
+ * Return whether a playlist is loaded in RAM (as opposed to only
3243
+ * stored on disk)
3244
+ *
3245
+ * @param[in] session Session object
3246
+ * @param[in] playlist Playlist object
3247
+ * @param[in] in_ram Controls whether or not to keep the list in RAM
3248
+ * @return One of the following errors, from ::sp_error
3249
+ * SP_ERROR_OK
3250
+ */
3251
+ SP_LIBEXPORT(sp_error) sp_playlist_set_in_ram(sp_session *session, sp_playlist *playlist, bool in_ram);
3252
+
3253
+ /**
3254
+ * Load an already existing playlist without adding it to a playlistcontainer.
3255
+ *
3256
+ * @param[in] session Session object
3257
+ * @param[in] link Link object referring to a playlist
3258
+ *
3259
+ * @return A playlist. The reference is owned by the caller and should be released with sp_playlist_release()
3260
+ *
3261
+ */
3262
+ SP_LIBEXPORT(sp_playlist *) sp_playlist_create(sp_session *session, sp_link *link);
3263
+
3264
+ /**
3265
+ * Mark a playlist to be synchronized for offline playback.
3266
+ * The playlist must be in the users playlistcontainer
3267
+ *
3268
+ * @param[in] session Session object
3269
+ * @param[in] playlist Playlist object
3270
+ * @param[in] offline True iff playlist should be offline, false otherwise
3271
+ * @return One of the following errors, from ::sp_error
3272
+ * SP_ERROR_OK
3273
+ */
3274
+ SP_LIBEXPORT(sp_error) sp_playlist_set_offline_mode(sp_session *session, sp_playlist *playlist, bool offline);
3275
+
3276
+ /**
3277
+ * Get offline status for a playlist
3278
+ *
3279
+ * @param[in] session Session object
3280
+ * @param[in] playlist Playlist object
3281
+ *
3282
+ * @return sp_playlist_offline_status
3283
+ *
3284
+ * @see When in SP_PLAYLIST_OFFLINE_STATUS_DOWNLOADING mode the
3285
+ * sp_playlist_get_offline_download_completed() method can be used to query
3286
+ * progress of the download
3287
+ */
3288
+ SP_LIBEXPORT(sp_playlist_offline_status) sp_playlist_get_offline_status(sp_session *session, sp_playlist *playlist);
3289
+
3290
+ /**
3291
+ * Get download progress for an offline playlist
3292
+ *
3293
+ * @param[in] session Session object
3294
+ * @param[in] playlist Playlist object
3295
+ *
3296
+ * @return Value from 0 - 100 that indicates amount of playlist that is downloaded
3297
+ * or 0 if the playlist is not in the SP_PLAYLIST_OFFLINE_STATUS_DOWNLOADING mode.
3298
+ *
3299
+ * @see sp_playlist_offline_status()
3300
+ */
3301
+ SP_LIBEXPORT(int) sp_playlist_get_offline_download_completed(sp_session *session, sp_playlist *playlist);
3302
+
3303
+ /**
3304
+ * Increase the reference count of a playlist
3305
+ *
3306
+ * @param[in] playlist The playlist object
3307
+ * @return One of the following errors, from ::sp_error
3308
+ * SP_ERROR_OK
3309
+ */
3310
+ SP_LIBEXPORT(sp_error) sp_playlist_add_ref(sp_playlist *playlist);
3311
+
3312
+ /**
3313
+ * Decrease the reference count of a playlist
3314
+ *
3315
+ * @param[in] playlist The playlist object
3316
+ * @return One of the following errors, from ::sp_error
3317
+ * SP_ERROR_OK
3318
+ */
3319
+ SP_LIBEXPORT(sp_error) sp_playlist_release(sp_playlist *playlist);
3320
+
3321
+
3322
+ /**
3323
+ * Playlist container callbacks.
3324
+ * If some callbacks should not be of interest, set them to NULL.
3325
+ *
3326
+ * @see sp_playlistcontainer_add_callbacks
3327
+ * @see sp_playlistcontainer_remove_callbacks
3328
+ */
3329
+ typedef struct sp_playlistcontainer_callbacks {
3330
+ /**
3331
+ * Called when a new playlist has been added to the playlist container.
3332
+ *
3333
+ * @param[in] pc Playlist container
3334
+ * @param[in] playlist Playlist object.
3335
+ * @param[in] position Position in list
3336
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
3337
+ */
3338
+ void (SP_CALLCONV *playlist_added)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, void *userdata);
3339
+
3340
+
3341
+ /**
3342
+ * Called when a new playlist has been removed from playlist container
3343
+ *
3344
+ * @param[in] pc Playlist container
3345
+ * @param[in] playlist Playlist object.
3346
+ * @param[in] position Position in list
3347
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
3348
+ */
3349
+ void (SP_CALLCONV *playlist_removed)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, void *userdata);
3350
+
3351
+
3352
+ /**
3353
+ * Called when a playlist has been moved in the playlist container
3354
+ *
3355
+ * @param[in] pc Playlist container
3356
+ * @param[in] playlist Playlist object.
3357
+ * @param[in] position Previous position in playlist container list
3358
+ * @param[in] new_position New position in playlist container list
3359
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
3360
+ */
3361
+ void (SP_CALLCONV *playlist_moved)(sp_playlistcontainer *pc, sp_playlist *playlist, int position, int new_position, void *userdata);
3362
+
3363
+ /**
3364
+ * Called when the playlist container is loaded
3365
+ *
3366
+ * @param[in] pc Playlist container
3367
+ * @param[in] userdata Userdata as set in sp_playlistcontainer_add_callbacks()
3368
+ */
3369
+ void (SP_CALLCONV *container_loaded)(sp_playlistcontainer *pc, void *userdata);
3370
+ } sp_playlistcontainer_callbacks;
3371
+
3372
+
3373
+ /**
3374
+ * Register interest in changes to a playlist container
3375
+ *
3376
+ * @param[in] pc Playlist container
3377
+ * @param[in] callbacks Callbacks, see sp_playlistcontainer_callbacks
3378
+ * @param[in] userdata Opaque value passed to callbacks.
3379
+ *
3380
+ * @note Every sp_playlistcontainer_add_callbacks() needs to be paired with a corresponding
3381
+ * sp_playlistcontainer_remove_callbacks() that is invoked before releasing the
3382
+ * last reference you own for the container. In other words, you must make sure
3383
+ * to have removed all the callbacks before the container gets destroyed.
3384
+ *
3385
+ * @sa sp_session_playlistcontainer()
3386
+ * @sa sp_playlistcontainer_remove_callbacks
3387
+ * @return One of the following errors, from ::sp_error
3388
+ * SP_ERROR_OK
3389
+ */
3390
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_add_callbacks(sp_playlistcontainer *pc, sp_playlistcontainer_callbacks *callbacks, void *userdata);
3391
+
3392
+
3393
+ /**
3394
+ * Unregister interest in changes to a playlist container
3395
+ *
3396
+ * @param[in] pc Playlist container
3397
+ * @param[in] callbacks Callbacks, see sp_playlistcontainer_callbacks
3398
+ * @param[in] userdata Opaque value passed to callbacks.
3399
+ *
3400
+ * @sa sp_session_playlistcontainer()
3401
+ * @sa sp_playlistcontainer_add_callbacks
3402
+ * @return One of the following errors, from ::sp_error
3403
+ * SP_ERROR_OK
3404
+ */
3405
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_remove_callbacks(sp_playlistcontainer *pc, sp_playlistcontainer_callbacks *callbacks, void *userdata);
3406
+
3407
+ /**
3408
+ * Return the number of playlists in the given playlist container
3409
+ *
3410
+ * @param[in] pc Playlist container
3411
+ *
3412
+ * @return Number of playlists, -1 if undefined
3413
+ *
3414
+ * @sa sp_session_playlistcontainer()
3415
+ */
3416
+ SP_LIBEXPORT(int) sp_playlistcontainer_num_playlists(sp_playlistcontainer *pc);
3417
+
3418
+ /**
3419
+ * Return true if the playlistcontainer is fully loaded
3420
+ *
3421
+ * @param[in] pc Playlist container
3422
+ *
3423
+ * @return True if container is loaded
3424
+ *
3425
+ * @note The container_loaded callback will be invoked when this flips to true
3426
+ */
3427
+ SP_LIBEXPORT(bool) sp_playlistcontainer_is_loaded(sp_playlistcontainer *pc);
3428
+
3429
+ /**
3430
+ * Return a pointer to the playlist at a specific index
3431
+ *
3432
+ * @param[in] pc Playlist container
3433
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
3434
+ *
3435
+ * @return The playlist object
3436
+ *
3437
+ * @sa sp_session_playlistcontainer()
3438
+ */
3439
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_playlist(sp_playlistcontainer *pc, int index);
3440
+
3441
+ /**
3442
+ * Return the type of the playlist at a @a index
3443
+ *
3444
+ * @param[in] pc Playlist container
3445
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
3446
+ *
3447
+ * @return Type of the playlist, @see sp_playlist_type
3448
+ *
3449
+ * @sa sp_session_playlistcontainer()
3450
+ */
3451
+ SP_LIBEXPORT(sp_playlist_type) sp_playlistcontainer_playlist_type(sp_playlistcontainer *pc, int index);
3452
+
3453
+ /**
3454
+ * Return the folder name at @a index
3455
+ *
3456
+ * @param[in] pc Playlist container
3457
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1].
3458
+ * Index should point at a start-folder entry, otherwise the empty string is written to buffer.
3459
+ * @param[in] buffer Pointer to char[] where to store folder name
3460
+ * @param[in] buffer_size Size of array
3461
+ *
3462
+ * @return One of the following errors, from ::sp_error
3463
+ * SP_ERROR_OK
3464
+ * SP_ERROR_INDEX_OUT_OF_RANGE
3465
+ *
3466
+ * @sa sp_session_playlistcontainer()
3467
+ */
3468
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_playlist_folder_name(sp_playlistcontainer *pc, int index, char *buffer, int buffer_size);
3469
+
3470
+ /**
3471
+ * Return the folder id at @a index
3472
+ *
3473
+ * @param[in] pc Playlist container
3474
+ * @param[in] index Index in playlist container. Should be in the interval [0, sp_playlistcontainer_num_playlists() - 1]
3475
+ *
3476
+ * @return The group ID of the folder. Returns 0 on index out of range, pc being NULL or indexed item not being a folder
3477
+ *
3478
+ * @sa sp_session_playlistcontainer()
3479
+ */
3480
+ SP_LIBEXPORT(sp_uint64) sp_playlistcontainer_playlist_folder_id(sp_playlistcontainer *pc, int index);
3481
+
3482
+ /**
3483
+ * Add an empty playlist at the end of the playlist container.
3484
+ * The name must not consist of only spaces and it must be shorter than 256 characters.
3485
+ *
3486
+ * @param[in] pc Playlist container
3487
+ * @param[in] name Name of new playlist
3488
+ *
3489
+ * @return Pointer to the new playlist. Can be NULL if the operation fails.
3490
+ */
3491
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_add_new_playlist(sp_playlistcontainer *pc, const char *name);
3492
+
3493
+ /**
3494
+ * Add an existing playlist at the end of the given playlist container
3495
+ *
3496
+ * @param[in] pc Playlist container
3497
+ * @param[in] link Link object pointing to a playlist
3498
+ *
3499
+ * @return Pointer to the new playlist. Will be NULL if the playlist already exists.
3500
+ */
3501
+ SP_LIBEXPORT(sp_playlist *) sp_playlistcontainer_add_playlist(sp_playlistcontainer *pc, sp_link *link);
3502
+
3503
+ /**
3504
+ * Remove playlist at index from the given playlist container
3505
+ *
3506
+ * @param[in] pc Playlist container
3507
+ * @param[in] index Index of playlist to be removed
3508
+ *
3509
+ * @return error One of the following errors, from ::sp_error
3510
+ * SP_ERROR_OK
3511
+ * SP_ERROR_INDEX_OUT_OF_RANGE
3512
+ */
3513
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_remove_playlist(sp_playlistcontainer *pc, int index);
3514
+
3515
+ /**
3516
+ * Move a playlist in the playlist container
3517
+ *
3518
+ * @param[in] pc Playlist container
3519
+ * @param[in] index Index of playlist to be moved
3520
+ * @param[in] new_position New position for the playlist
3521
+ * @param[in] dry_run Do not execute the move, only check if it possible
3522
+
3523
+ * @return error One of the following errors, from ::sp_error
3524
+ * SP_ERROR_OK
3525
+ * SP_ERROR_INDEX_OUT_OF_RANGE
3526
+ * SP_ERROR_INVALID_INDATA - If trying to move a folder into itself
3527
+ */
3528
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_move_playlist(sp_playlistcontainer *pc, int index, int new_position, bool dry_run);
3529
+
3530
+
3531
+ /**
3532
+ * Add a playlist folder
3533
+ *
3534
+ * @param[in] pc Playlist container
3535
+ * @param[in] index Position of SP_PLAYLIST_TYPE_START_FOLDER entry
3536
+ * @param[in] name Name of group
3537
+
3538
+ * @return error One of the following errors, from ::sp_error
3539
+ * SP_ERROR_OK
3540
+ * SP_ERROR_INDEX_OUT_OF_RANGE
3541
+ *
3542
+ * @note This operation will actually create two playlists. One of
3543
+ * type SP_PLAYLIST_TYPE_START_FOLDER and immediately following a
3544
+ * SP_PLAYLIST_TYPE_END_FOLDER one.
3545
+ *
3546
+ * To remove a playlist folder both of these must be deleted or the list
3547
+ * will be left in an inconsistant state.
3548
+ *
3549
+ * There is no way to rename a playlist folder. Instead you need to remove
3550
+ * the folder and recreate it again.
3551
+ */
3552
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_add_folder(sp_playlistcontainer *pc, int index, const char *name);
3553
+
3554
+
3555
+ /**
3556
+ * Return a pointer to the user object of the owner.
3557
+ *
3558
+ * @param[in] pc Playlist container.
3559
+ * @return The user object or NULL if unknown or none.
3560
+ */
3561
+ SP_LIBEXPORT(sp_user *) sp_playlistcontainer_owner(sp_playlistcontainer *pc);
3562
+
3563
+
3564
+ /**
3565
+ * Increase reference count on playlistconatiner object
3566
+ *
3567
+ * @param[in] pc Playlist container.
3568
+ * @return One of the following errors, from ::sp_error
3569
+ * SP_ERROR_OK
3570
+ */
3571
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_add_ref(sp_playlistcontainer *pc);
3572
+
3573
+ /**
3574
+ * Release reference count on playlistconatiner object
3575
+ *
3576
+ * @param[in] pc Playlist container.
3577
+ * @return One of the following errors, from ::sp_error
3578
+ * SP_ERROR_OK
3579
+ */
3580
+ SP_LIBEXPORT(sp_error) sp_playlistcontainer_release(sp_playlistcontainer *pc);
3581
+
3582
+ /**
3583
+ * Get the number of new tracks in a playlist since the corresponding
3584
+ * function sp_playlistcontainer_clear_unseen_tracks() was called. The
3585
+ * function always returns the number of new tracks, and fills the
3586
+ * \p tracks array with the new tracks, but not more than specified in
3587
+ * \p num_tracks. The function will return a negative value on failure.
3588
+ *
3589
+ * @param[in] pc Playlist container.
3590
+ * @param[in] playlist Playlist object.
3591
+ * @param[out] tracks Array of pointer to new tracks (maybe NULL)
3592
+ * @param[in] num_tracks Size of tracks array
3593
+ * @return Returns the number of unseen tracks
3594
+ */
3595
+ SP_LIBEXPORT(int) sp_playlistcontainer_get_unseen_tracks(sp_playlistcontainer *pc, sp_playlist *playlist, sp_track **tracks, int num_tracks);
3596
+
3597
+ /**
3598
+ * Clears a playlist from unseen tracks, so that next call to sp_playlistcontainer_get_unseen_tracks() will return 0 until a new track is added to the \p playslist.
3599
+ *
3600
+ * @param[in] pc Playlist container.
3601
+ * @param[in] playlist Playlist object.
3602
+ * @return Returns 0 on success and -1 on failure.
3603
+ */
3604
+ SP_LIBEXPORT(int) sp_playlistcontainer_clear_unseen_tracks(sp_playlistcontainer *pc, sp_playlist *playlist);
3605
+
3606
+ /** @} */
3607
+
3608
+
3609
+ /**
3610
+ * @defgroup user User handling
3611
+ * @{
3612
+ */
3613
+
3614
+
3615
+ /**
3616
+ * User relation type
3617
+ */
3618
+ typedef enum sp_relation_type {
3619
+ SP_RELATION_TYPE_UNKNOWN = 0, ///< Not yet known
3620
+ SP_RELATION_TYPE_NONE = 1, ///< No relation
3621
+ SP_RELATION_TYPE_UNIDIRECTIONAL = 2, ///< The currently logged in user is following this uer
3622
+ SP_RELATION_TYPE_BIDIRECTIONAL = 3, ///< Bidirectional friendship established
3623
+ } sp_relation_type;
3624
+
3625
+
3626
+
3627
+ /**
3628
+ * Get a pointer to a string representing the user's canonical username.
3629
+ *
3630
+ * @param[in] user The Spotify user whose canonical username you would like a string representation of
3631
+ *
3632
+ * @return A string representing the canonical username.
3633
+ */
3634
+ SP_LIBEXPORT(const char *) sp_user_canonical_name(sp_user *user);
3635
+
3636
+ /**
3637
+ * Get a pointer to a string representing the user's displayable username.
3638
+ * If there is no difference between the canonical username and the display name,
3639
+ * or if the library does not know about the display name yet, the canonical username will
3640
+ * be returned.
3641
+ *
3642
+ * @param[in] user The Spotify user whose displayable username you would like a string representation of
3643
+ *
3644
+ * @return A string
3645
+ */
3646
+ SP_LIBEXPORT(const char *) sp_user_display_name(sp_user *user);
3647
+
3648
+ /**
3649
+ * Get load status for a user object. Before it is loaded, only the user's canonical username
3650
+ * is known.
3651
+ *
3652
+ * @param[in] user Spotify user object
3653
+ *
3654
+ * @return True if user object is loaded, otherwise false
3655
+ */
3656
+ SP_LIBEXPORT(bool) sp_user_is_loaded(sp_user *user);
3657
+
3658
+
3659
+ /**
3660
+ * Increase the reference count of an user
3661
+ *
3662
+ * @param[in] user The user object
3663
+ * @return One of the following errors, from ::sp_error
3664
+ * SP_ERROR_OK
3665
+ */
3666
+ SP_LIBEXPORT(sp_error) sp_user_add_ref(sp_user *user);
3667
+
3668
+ /**
3669
+ * Decrease the reference count of an user
3670
+ *
3671
+ * @param[in] user The user object
3672
+ * @return One of the following errors, from ::sp_error
3673
+ * SP_ERROR_OK
3674
+ */
3675
+ SP_LIBEXPORT(sp_error) sp_user_release(sp_user *user);
3676
+
3677
+ /** @} */
3678
+
3679
+
3680
+ /**
3681
+ * @defgroup toplist Toplist handling
3682
+ * @{
3683
+ */
3684
+
3685
+ /**
3686
+ * Toplist types
3687
+ */
3688
+ typedef enum {
3689
+ SP_TOPLIST_TYPE_ARTISTS = 0, ///< Top artists
3690
+ SP_TOPLIST_TYPE_ALBUMS = 1, ///< Top albums
3691
+ SP_TOPLIST_TYPE_TRACKS = 2, ///< Top tracks
3692
+ } sp_toplisttype;
3693
+
3694
+
3695
+ /**
3696
+ * Convenience macro to create a toplist region. Toplist regions are ISO 3166-1
3697
+ * country codes (in uppercase) encoded in an integer. There are also some reserved
3698
+ * codes used to denote non-country regions. See sp_toplistregion
3699
+ *
3700
+ * Example: SP_TOPLIST_REGION('S', 'E') for Sweden
3701
+ */
3702
+ #define SP_TOPLIST_REGION(a, b) ((a) << 8 | (b))
3703
+
3704
+ /**
3705
+ * Special toplist regions
3706
+ */
3707
+ typedef enum {
3708
+ SP_TOPLIST_REGION_EVERYWHERE = 0, ///< Global toplist
3709
+ SP_TOPLIST_REGION_USER = 1, ///< Toplist for a given user
3710
+ } sp_toplistregion;
3711
+
3712
+
3713
+ /**
3714
+ * The type of a callback used in sp_toplistbrowse_create()
3715
+ *
3716
+ * When the callback is called, the metadata of all tracks belonging to it will have
3717
+ * been loaded, so sp_track_is_loaded() will return non-zero. The same goes for the
3718
+ * similar toplist data.
3719
+ *
3720
+ * @param[in] result The same pointer returned by sp_toplistbrowse_create()
3721
+ * @param[in] userdata The opaque pointer given to sp_toplistbrowse_create()
3722
+ */
3723
+ typedef void SP_CALLCONV toplistbrowse_complete_cb(sp_toplistbrowse *result, void *userdata);
3724
+
3725
+ /**
3726
+ * Initiate a request for browsing an toplist
3727
+ *
3728
+ * The user is responsible for freeing the returned toplist browse using sp_toplistbrowse_release(). This can be done in the callback.
3729
+ *
3730
+ * @param[in] session Session object
3731
+ * @param[in] type Type of toplist to be browsed. see the sp_toplisttype enum for possible values
3732
+ * @param[in] region Region. see sp_toplistregion enum. Country specific regions are coded as two chars in an integer.
3733
+ * Sweden would correspond to 'S' << 8 | 'E'
3734
+ * @param[in] username If region is SP_TOPLIST_REGION_USER this specifies which user to get toplists for. NULL means the logged in user.
3735
+ * @param[in] callback Callback to be invoked when browsing has been completed. Pass NULL if you are not interested in this event.
3736
+ * @param[in] userdata Userdata passed to callback.
3737
+ *
3738
+ * @return Toplist browse object
3739
+ *
3740
+ * @see ::toplistbrowse_complete_cb
3741
+ */
3742
+ SP_LIBEXPORT(sp_toplistbrowse *) sp_toplistbrowse_create(sp_session *session, sp_toplisttype type, sp_toplistregion region, const char *username, toplistbrowse_complete_cb *callback, void *userdata);
3743
+
3744
+
3745
+ /**
3746
+ * Check if an toplist browse request is completed
3747
+ *
3748
+ * @param[in] tlb Toplist browse object
3749
+ *
3750
+ * @return True if browsing is completed, false if not
3751
+ */
3752
+ SP_LIBEXPORT(bool) sp_toplistbrowse_is_loaded(sp_toplistbrowse *tlb);
3753
+
3754
+ /**
3755
+ * Check if browsing returned an error code.
3756
+ *
3757
+ * @param[in] tlb Toplist browse object
3758
+ *
3759
+ * @return One of the following errors, from ::sp_error
3760
+ * SP_ERROR_OK
3761
+ * SP_ERROR_IS_LOADING
3762
+ * SP_ERROR_OTHER_PERMANENT
3763
+ * SP_ERROR_OTHER_TRANSIENT
3764
+ */
3765
+ SP_LIBEXPORT(sp_error) sp_toplistbrowse_error(sp_toplistbrowse *tlb);
3766
+
3767
+
3768
+
3769
+ /**
3770
+ * Increase the reference count of an toplist browse result
3771
+ *
3772
+ * @param[in] tlb The toplist browse result object
3773
+ * @return One of the following errors, from ::sp_error
3774
+ * SP_ERROR_OK
3775
+ */
3776
+ SP_LIBEXPORT(sp_error) sp_toplistbrowse_add_ref(sp_toplistbrowse *tlb);
3777
+
3778
+ /**
3779
+ * Decrease the reference count of an toplist browse result
3780
+ *
3781
+ * @param[in] tlb The toplist browse result object
3782
+ * @return One of the following errors, from ::sp_error
3783
+ * SP_ERROR_OK
3784
+ */
3785
+ SP_LIBEXPORT(sp_error) sp_toplistbrowse_release(sp_toplistbrowse *tlb);
3786
+
3787
+ /**
3788
+ * Given an toplist browse object, return number of artists
3789
+ *
3790
+ * @param[in] tlb Toplist browse object
3791
+ *
3792
+ * @return Number of artists on toplist
3793
+ */
3794
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_artists(sp_toplistbrowse *tlb);
3795
+
3796
+ /**
3797
+ * Return the artist at the given index in the given toplist browse object
3798
+ *
3799
+ * @param[in] tlb Toplist object
3800
+ * @param[in] index Index of the wanted artist. Should be in the interval [0, sp_toplistbrowse_num_artists() - 1]
3801
+ *
3802
+ * @return The artist at the given index in the given toplist browse object
3803
+ */
3804
+ SP_LIBEXPORT(sp_artist *) sp_toplistbrowse_artist(sp_toplistbrowse *tlb, int index);
3805
+
3806
+
3807
+ /**
3808
+ * Given an toplist browse object, return number of albums
3809
+ *
3810
+ * @param[in] tlb Toplist browse object
3811
+ *
3812
+ * @return Number of albums on toplist
3813
+ */
3814
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_albums(sp_toplistbrowse *tlb);
3815
+
3816
+
3817
+ /**
3818
+ * Return the album at the given index in the given toplist browse object
3819
+ *
3820
+ * @param[in] tlb Toplist object
3821
+ * @param[in] index Index of the wanted album. Should be in the interval [0, sp_toplistbrowse_num_albums() - 1]
3822
+ *
3823
+ * @return The album at the given index in the given toplist browse object
3824
+ */
3825
+ SP_LIBEXPORT(sp_album *) sp_toplistbrowse_album(sp_toplistbrowse *tlb, int index);
3826
+
3827
+
3828
+ /**
3829
+ * Given an toplist browse object, return number of tracks
3830
+ *
3831
+ * @param[in] tlb Toplist browse object
3832
+ *
3833
+ * @return Number of tracks on toplist
3834
+ */
3835
+ SP_LIBEXPORT(int) sp_toplistbrowse_num_tracks(sp_toplistbrowse *tlb);
3836
+
3837
+
3838
+ /**
3839
+ * Return the track at the given index in the given toplist browse object
3840
+ *
3841
+ * @param[in] tlb Toplist object
3842
+ * @param[in] index Index of the wanted track. Should be in the interval [0, sp_toplistbrowse_num_tracks() - 1]
3843
+ *
3844
+ * @return The track at the given index in the given toplist browse object
3845
+ */
3846
+ SP_LIBEXPORT(sp_track *) sp_toplistbrowse_track(sp_toplistbrowse *tlb, int index);
3847
+
3848
+ /**
3849
+ * Return the time (in ms) that was spent waiting for the Spotify backend to serve the request
3850
+ *
3851
+ * @param[in] tlb Toplist object
3852
+ *
3853
+ * @return -1 if the request was served from the local cache
3854
+ * If the result is not yet loaded the return value is undefined
3855
+ */
3856
+ SP_LIBEXPORT(int) sp_toplistbrowse_backend_request_duration(sp_toplistbrowse *tlb);
3857
+
3858
+
3859
+ /** @} */
3860
+
3861
+ /**
3862
+ * @defgroup inbox Inbox subsystem
3863
+ * @{
3864
+ */
3865
+
3866
+ /**
3867
+ * The type of a callback used in sp_inbox_post()
3868
+ *
3869
+ * When this callback is called, the sp_track_is_loaded(), sp_album_is_loaded(),
3870
+ * and sp_artist_is_loaded() functions will return non-zero for the objects
3871
+ * contained in the search result.
3872
+ *
3873
+ * @param[in] result The same pointer returned by sp_search_create()
3874
+ * @param[in] userdata The opaque pointer given to sp_search_create()
3875
+ */
3876
+ typedef void SP_CALLCONV inboxpost_complete_cb(sp_inbox *result, void *userdata);
3877
+
3878
+ /**
3879
+ * Add to inbox
3880
+ *
3881
+ * @param[in] session Session object
3882
+ * @param[in] user Canonical username of recipient
3883
+ * @param[in] tracks Array of tracks to post
3884
+ * @param[in] num_tracks Number of tracks in \p tracks
3885
+ * @param[in] message Message to attach to tracks. UTF-8
3886
+ * @param[in] callback Callback to be invoked when the request has completed
3887
+ * @param[in] userdata Userdata passed to callback
3888
+ *
3889
+ * @return sp_inbox object if the request has been sent, NULL if request failed to initialize
3890
+ */
3891
+ SP_LIBEXPORT(sp_inbox *) sp_inbox_post_tracks(sp_session *session, const char *user, sp_track * const *tracks, int num_tracks, const char *message, inboxpost_complete_cb *callback, void *userdata);
3892
+
3893
+
3894
+ /**
3895
+ * Check if inbox operation returned an error code.
3896
+ *
3897
+ * @param[in] inbox Inbox object
3898
+ *
3899
+ * @return One of the following errors, from ::sp_error
3900
+ * SP_ERROR_OK
3901
+ * SP_ERROR_OTHER_TRANSIENT
3902
+ * SP_ERROR_PERMISSION_DENIED
3903
+ * SP_ERROR_INVALID_INDATA
3904
+ * SP_ERROR_INBOX_IS_FULL
3905
+ * SP_ERROR_NO_SUCH_USER
3906
+ * SP_ERROR_OTHER_PERMANENT
3907
+ */
3908
+ SP_LIBEXPORT(sp_error) sp_inbox_error(sp_inbox *inbox);
3909
+
3910
+ /**
3911
+ * Increase the reference count of a inbox result
3912
+ *
3913
+ * @param[in] inbox The inbox result object
3914
+ * @return One of the following errors, from ::sp_error
3915
+ * SP_ERROR_OK
3916
+ */
3917
+ SP_LIBEXPORT(sp_error) sp_inbox_add_ref(sp_inbox *inbox);
3918
+
3919
+ /**
3920
+ * Decrease the reference count of a inbox result
3921
+ *
3922
+ * @param[in] inbox The inbox result object
3923
+ * @return One of the following errors, from ::sp_error
3924
+ * SP_ERROR_OK
3925
+ */
3926
+ SP_LIBEXPORT(sp_error) sp_inbox_release(sp_inbox *inbox);
3927
+
3928
+ /** @} */
3929
+
3930
+ /**
3931
+ * Return the libspotify build ID
3932
+ *
3933
+ * This might be useful to have available for display somewhere in your
3934
+ * user interface.
3935
+ */
3936
+ SP_LIBEXPORT(const char *) sp_build_id(void);
3937
+
3938
+ #ifdef __cplusplus
3939
+ }
3940
+ #endif
3941
+
3942
+ #endif /* PUBLIC_API_H */
3943
+ /**
3944
+ * @example browse.c
3945
+ *
3946
+ * The browse.c example shows how you can use the album, artist, and browse functions.
3947
+ * The example also include some rudimentary playlist browsing.
3948
+ * It is part of the spshell program
3949
+ */
3950
+ /**
3951
+ * @example search.c
3952
+ *
3953
+ * The search.c example shows how you can use search functions.
3954
+ * It is part of the spshell program
3955
+ */
3956
+ /**
3957
+ * @example toplist.c
3958
+ *
3959
+ * The toplist.c example shows how you can use toplist functions.
3960
+ * It is part of the spshell program
3961
+ */
3962
+ /**
3963
+ * @example jukebox.c
3964
+ *
3965
+ * The jukebox.c example shows how you can use playback and playlist functions.
3966
+ */