Skip to content

Commit 6e7058c

Browse files
committed
Adding samples.
1 parent 6861e32 commit 6e7058c

File tree

7 files changed

+328
-12
lines changed

7 files changed

+328
-12
lines changed

Spotify.NET.sln

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Express 2013 for Windows Desktop
4-
VisualStudioVersion = 12.0.31101.0
4+
VisualStudioVersion = 12.0.30501.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spotify", "Spotify\Spotify.csproj", "{C942243A-65F2-4433-9A08-61A1BC68DAD2}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jukebox", "jukebox\jukebox.csproj", "{29444363-D2A1-448F-8047-3DCD73F9E18A}"
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B127B7C6-FFA0-468B-87DD-9431BB53D148}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jukebox", "examples\jukebox\jukebox.csproj", "{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2}"
911
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,12 +19,15 @@ Global
1719
{C942243A-65F2-4433-9A08-61A1BC68DAD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
1820
{C942243A-65F2-4433-9A08-61A1BC68DAD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
1921
{C942243A-65F2-4433-9A08-61A1BC68DAD2}.Release|Any CPU.Build.0 = Release|Any CPU
20-
{29444363-D2A1-448F-8047-3DCD73F9E18A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21-
{29444363-D2A1-448F-8047-3DCD73F9E18A}.Debug|Any CPU.Build.0 = Debug|Any CPU
22-
{29444363-D2A1-448F-8047-3DCD73F9E18A}.Release|Any CPU.ActiveCfg = Release|Any CPU
23-
{29444363-D2A1-448F-8047-3DCD73F9E18A}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2}.Release|Any CPU.Build.0 = Release|Any CPU
2426
EndGlobalSection
2527
GlobalSection(SolutionProperties) = preSolution
2628
HideSolutionNode = FALSE
2729
EndGlobalSection
30+
GlobalSection(NestedProjects) = preSolution
31+
{D4E685A3-C8E7-4DBA-9B71-6DFC5097F8C2} = {B127B7C6-FFA0-468B-87DD-9431BB53D148}
32+
EndGlobalSection
2833
EndGlobal

Spotify/LoggedInEventArgs.cs

+8
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,13 @@ public LoggedInEventArgs(Error code)
88
: base(code)
99
{
1010
}
11+
12+
public string Message
13+
{
14+
get
15+
{
16+
return LibSpotify.ReadUtf8(LibSpotify.sp_error_message_r(ErrorCode));
17+
}
18+
}
1119
}
1220
}

Spotify/Session.cs

+11-6
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,8 @@ public void Dispose()
186186
}
187187

188188
public void Start()
189-
{
190-
_running = true;
191-
_thread = new Thread(this.Main);
189+
{
190+
_thread = new Thread(ProcessEvents);
192191
_thread.Name = "Spotify.NET Event";
193192
_thread.Start();
194193
}
@@ -256,6 +255,11 @@ public Playlist CreateStarredForUser(string canonicalUser)
256255
canonicalUser));
257256
}
258257

258+
public PlaylistContainer CreatePlaylistContainer()
259+
{
260+
return new PlaylistContainer(LibSpotify.sp_session_playlistcontainer_r(Handle), false);
261+
}
262+
259263
public PlaylistContainer CreatePublishedContainerForUser(string canonicalUser)
260264
{
261265
return new PlaylistContainer(LibSpotify.sp_session_publishedcontainer_for_user_create_r(
@@ -422,6 +426,7 @@ public static Session Create(SessionConfig sessionConfig)
422426

423427
// This call results in a callback to RaiseNotifyMainThread, but the
424428
// actual _handle has not been set yet.
429+
session._running = true;
425430
ThrowHelper.ThrowIfError(LibSpotify.sp_session_create_r(ref config, ref ptr));
426431
session.Handle = ptr;
427432
}
@@ -442,7 +447,7 @@ internal Internal.Image CreateImage(IntPtr imageId)
442447
return new Internal.Image(LibSpotify.sp_image_create_r(Handle, imageId));
443448
}
444449

445-
private void Main()
450+
public void ProcessEvents()
446451
{
447452
TimeSpan nextTimeout = TimeSpan.FromHours(24);
448453

@@ -454,7 +459,7 @@ private void Main()
454459

455460
do
456461
{
457-
nextTimeout = ProcessEvents();
462+
nextTimeout = ProcessEventsInternal();
458463
}
459464
while (nextTimeout == TimeSpan.MinValue);
460465
}
@@ -473,7 +478,7 @@ private void HandleOnNotifyMainThread(object sender, EventArgs e)
473478
_notifyEvent.Set();
474479
}
475480

476-
private TimeSpan ProcessEvents()
481+
private TimeSpan ProcessEventsInternal()
477482
{
478483
int nextTimeout = 0;
479484
lock (_lock)

examples/jukebox/App.config

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
5+
</startup>
6+
</configuration>

examples/jukebox/Program.cs

+189
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace jukebox
8+
{
9+
class Program
10+
{
11+
private static NAudio.Wave.BufferedWaveProvider _audioProvider;
12+
private static NAudio.Wave.WaveOut _audioSink;
13+
private static Spotify.Playlist _jukeboxList;
14+
private static Spotify.Session _session;
15+
private static string _listname;
16+
private static int _trackIndex;
17+
18+
public static void Main(string[] args)
19+
{
20+
21+
string username = args[0];
22+
string password = args[1];
23+
_listname = args[2];
24+
25+
InitAudio();
26+
27+
Console.OutputEncoding = System.Text.Encoding.UTF8;
28+
Spotify.Environment.UnhandledException += Environment_UnhandledException;
29+
30+
Spotify.SessionConfig sessionConfig = new Spotify.SessionConfig();
31+
sessionConfig.ApplicationKeyFile = @"c:\Temp\spotify_appkey.key";
32+
sessionConfig.UserAgent = "jukebox-example";
33+
34+
_session = Spotify.Session.Create(sessionConfig);
35+
_session.OnLoggedIn += session_OnLoggedIn;
36+
_session.OnMusicDelivered += session_OnMusicDelivered;
37+
_session.OnMetadataUpdated += session_OnMetadataUpdated;
38+
_session.OnPlayTokenLost += session_OnPlayTokenLost;
39+
_session.OnLogMessage += session_OnLogMessage;
40+
_session.OnEndOfTrack += session_OnEndOfTrack;
41+
_session.LoginAsync(new Spotify.LoginParameters() { UserName = username, Password = password }, null);
42+
_session.ProcessEvents();
43+
}
44+
45+
private static void TryJukeboxStart()
46+
{
47+
if (_jukeboxList == null)
48+
return;
49+
50+
IList<Spotify.Track> trackList = _jukeboxList.Tracks;
51+
if (_trackIndex >= trackList.Count)
52+
{
53+
Console.WriteLine("jukebox: Not more tracks in playlist. Waiting");
54+
return;
55+
}
56+
57+
Spotify.Track track = trackList[_trackIndex];
58+
59+
// TODO: Should we override Equals() to compare handles?
60+
61+
if (track.Error != Spotify.Error.Ok)
62+
return;
63+
64+
Console.WriteLine("jukebox: Now playing \"{0}\"...", track.Name);
65+
66+
_session.PlayerLoad(track);
67+
_session.PlayerPlay(true);
68+
_audioSink.Play();
69+
}
70+
71+
private static void Environment_UnhandledException(object sender, UnhandledExceptionEventArgs e)
72+
{
73+
74+
Console.WriteLine("Unhandled Exception");
75+
Console.WriteLine(e);
76+
}
77+
private static void session_OnEndOfTrack(object sender, EventArgs e)
78+
{
79+
_audioSink.Stop();
80+
_session.PlayerUnload();
81+
82+
// TODO:
83+
_trackIndex++;
84+
85+
TryJukeboxStart();
86+
}
87+
88+
private static void session_OnLogMessage(object sender, Spotify.LogMessageEventArgs e)
89+
{
90+
Console.WriteLine("LibSpotify: {0}", e.Message);
91+
}
92+
93+
private static void session_OnPlayTokenLost(object sender, EventArgs e)
94+
{
95+
96+
}
97+
98+
private static void session_OnMetadataUpdated(object sender, EventArgs e)
99+
{
100+
// TryJukeboxStart();
101+
}
102+
103+
private static void session_OnMusicDelivered(object sender, Spotify.MusicDeliveryEventArgs e)
104+
{
105+
_audioProvider.AddSamples(e.PcmData, 0, e.PcmData.Length);
106+
}
107+
108+
private static void session_OnLoggedIn(object sender, Spotify.LoggedInEventArgs e)
109+
{
110+
Spotify.Session session = (Spotify.Session)sender;
111+
if (e.ErrorCode != Spotify.Error.Ok)
112+
{
113+
Console.WriteLine("jukebox: Login failed: {0}", e.Message);
114+
}
115+
116+
Spotify.PlaylistContainer playlistContainer = session.CreatePlaylistContainer();
117+
playlistContainer.OnPlaylistAdded += playlistContainer_OnPlaylistAdded;
118+
playlistContainer.OnPlaylistMoved += playlistContainer_OnPlaylistMoved;
119+
playlistContainer.OnLoaded += playlistContainer_OnLoaded;
120+
121+
foreach (Spotify.Playlist playlist in playlistContainer.Playlists)
122+
{
123+
playlist.OnTracksAdded += playlist_OnTracksAdded;
124+
playlist.OnTracksRemoved += playlist_OnTracksRemoved;
125+
playlist.OnTracksMoved += playlist_OnTracksMoved;
126+
playlist.OnRenamed += playlist_OnRenamed;
127+
128+
if (playlist.Name.Equals(_listname))
129+
{
130+
_jukeboxList = playlist;
131+
132+
TryJukeboxStart();
133+
}
134+
else
135+
{
136+
playlist.Dispose();
137+
}
138+
}
139+
140+
if (_jukeboxList == null)
141+
Console.WriteLine("jukebox: No such playlist. Waiting for one to pop up...");
142+
}
143+
144+
private static void playlist_OnRenamed(object sender, EventArgs e)
145+
{
146+
147+
}
148+
149+
private static void playlist_OnTracksMoved(object sender, Spotify.PlaylistTracksMovedEventArgs e)
150+
{
151+
152+
}
153+
154+
private static void playlist_OnTracksRemoved(object sender, Spotify.PlaylistTracksRemovedEventArgs e)
155+
{
156+
157+
}
158+
159+
private static void playlist_OnTracksAdded(object sender, Spotify.PlaylistTracksAddedEventArgs e)
160+
{
161+
162+
}
163+
164+
private static void playlistContainer_OnLoaded(object sender, EventArgs e)
165+
{
166+
167+
}
168+
169+
private static void playlistContainer_OnPlaylistMoved(object sender, EventArgs e)
170+
{
171+
172+
}
173+
174+
private static void playlistContainer_OnPlaylistAdded(object sender, Spotify.PlaylistAddedEventArgs e)
175+
{
176+
177+
}
178+
179+
private static void InitAudio()
180+
{
181+
_audioProvider = new NAudio.Wave.BufferedWaveProvider(new NAudio.Wave.WaveFormat(44100, 2));
182+
_audioProvider.BufferDuration = TimeSpan.FromSeconds(300);
183+
_audioSink = new NAudio.Wave.WaveOut();
184+
_audioSink.Init(_audioProvider);
185+
}
186+
}
187+
}
188+
189+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("jukebox")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("jukebox")]
13+
[assembly: AssemblyCopyright("Copyright © 2015")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("36ae6a3b-2171-4cf2-8e87-3bdecef9dbdf")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)