Skip to content

Commit 2543ed2

Browse files
author
Jonas Dellinger
committed
Added new player endpoints
1 parent 7e6dab6 commit 2543ed2

10 files changed

Lines changed: 421 additions & 11 deletions

File tree

‎SpotifyAPI.Example/WebControl.cs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ private async void InitialSetup()
3737
return;
3838
}
3939

40-
var test = _spotify.GetUsersRecentlyPlayedTracks();
41-
4240
authButton.Enabled = false;
4341
_profile = _spotify.GetPrivateProfile();
4442

@@ -111,7 +109,7 @@ private async void RunAuthentication()
111109
"26d287105e31491889f3cd293d85bfea",
112110
Scope.UserReadPrivate | Scope.UserReadEmail | Scope.PlaylistReadPrivate | Scope.UserLibraryRead |
113111
Scope.UserReadPrivate | Scope.UserFollowRead | Scope.UserReadBirthdate | Scope.UserTopRead | Scope.PlaylistReadCollaborative |
114-
Scope.UserReadRecentlyPlayed);
112+
Scope.UserReadRecentlyPlayed | Scope.UserReadPlaybackState | Scope.UserModifyPlaybackState);
115113

116114
try
117115
{

‎SpotifyAPI/SpotifyAPI.csproj‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<Private>True</Private>
4343
</Reference>
4444
<Reference Include="System" />
45+
<Reference Include="System.ComponentModel.DataAnnotations" />
4546
<Reference Include="System.Core" />
4647
<Reference Include="System.Drawing" />
4748
<Reference Include="System.Web" />
@@ -59,6 +60,7 @@
5960
<Compile Include="Local\Models\SpotifyUri.cs" />
6061
<Compile Include="Local\VolumeMixerControl.cs" />
6162
<Compile Include="Web\Auth\WebAPIFactory.cs" />
63+
<Compile Include="Web\Enums\RepeatState.cs" />
6264
<Compile Include="Web\Enums\TimeRangeType.cs" />
6365
<Compile Include="Web\IClient.cs" />
6466
<Compile Include="Local\Models\CFID.cs" />
@@ -79,17 +81,20 @@
7981
<Compile Include="Web\Auth\ImplicitGrantAuth.cs" />
8082
<Compile Include="Web\Models\ArrayResponse.cs" />
8183
<Compile Include="Web\Models\AudioFeatures.cs" />
84+
<Compile Include="Web\Models\AvailabeDevices.cs" />
8285
<Compile Include="Web\Models\BasicModel.cs" />
8386
<Compile Include="Web\Models\Category.cs" />
8487
<Compile Include="Web\Models\CategoryList.cs" />
8588
<Compile Include="Web\Models\CategoryPlaylist.cs" />
8689
<Compile Include="Web\Models\CursorPaging.cs" />
90+
<Compile Include="Web\Models\Device.cs" />
8791
<Compile Include="Web\Models\FeaturedPlaylists.cs" />
8892
<Compile Include="Web\Models\FollowedArtists.cs" />
8993
<Compile Include="Web\Models\FullAlbum.cs" />
9094
<Compile Include="Web\Models\FullArtist.cs" />
9195
<Compile Include="Web\Models\FullTrack.cs" />
9296
<Compile Include="Web\Models\NewAlbumReleases.cs" />
97+
<Compile Include="Web\Models\PlaybackContext.cs" />
9398
<Compile Include="Web\Models\PlayHistory.cs" />
9499
<Compile Include="Web\Models\Recommendations.cs" />
95100
<Compile Include="Web\Models\RecommendationSeed .cs" />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
3+
namespace SpotifyAPI.Web.Enums
4+
{
5+
[Flags]
6+
public enum RepeatState
7+
{
8+
[String("track")]
9+
Track = 1,
10+
11+
[String("context")]
12+
Context = 2,
13+
14+
[String("off")]
15+
Off = 4
16+
}
17+
}

‎SpotifyAPI/Web/Enums/Scope.cs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ public enum Scope
4848
PlaylistReadCollaborative = 8192,
4949

5050
[String("user-read-recently-played")]
51-
UserReadRecentlyPlayed = 16384
51+
UserReadRecentlyPlayed = 16384,
52+
53+
[String("user-read-playback-state")]
54+
UserReadPlaybackState = 32768,
55+
56+
[String("user-modify-playback-state")]
57+
UserModifyPlaybackState = 65536
5258
}
5359
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace SpotifyAPI.Web.Models
5+
{
6+
public class AvailabeDevices : BasicModel
7+
{
8+
[JsonProperty("devices")]
9+
public List<Device> Devices { get; set; }
10+
}
11+
}

‎SpotifyAPI/Web/Models/Device.cs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Newtonsoft.Json;
2+
3+
namespace SpotifyAPI.Web.Models
4+
{
5+
public class Device
6+
{
7+
[JsonProperty("id")]
8+
public string Id { get; set; }
9+
10+
[JsonProperty("is_active")]
11+
public bool IsActive { get; set; }
12+
13+
[JsonProperty("is_restricted")]
14+
public bool IsRestricted { get; set; }
15+
16+
[JsonProperty("name")]
17+
public string Name { get; set; }
18+
19+
[JsonProperty("type")]
20+
public string Type { get; set; }
21+
22+
[JsonProperty("volume_percent")]
23+
public int VolumePercent { get; set; }
24+
}
25+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
using SpotifyAPI.Web.Enums;
5+
6+
namespace SpotifyAPI.Web.Models
7+
{
8+
public class PlaybackContext : BasicModel
9+
{
10+
[JsonProperty("device")]
11+
public Device Device { get; set; }
12+
13+
[JsonProperty("repeat_state")]
14+
[JsonConverter(typeof(StringEnumConverter))]
15+
public RepeatState RepeatState { get; set; }
16+
17+
[JsonProperty("shuffle_state")]
18+
public bool ShuffleState { get; set; }
19+
20+
[JsonProperty("context")]
21+
public Context Context { get; set; }
22+
23+
[JsonProperty("timestamp")]
24+
public long Timestamp { get; set; }
25+
26+
[JsonProperty("progress_ms")]
27+
public int ProgressMs { get; set; }
28+
29+
[JsonProperty("is_playing")]
30+
public bool IsPlaying { get; set; }
31+
32+
[JsonProperty("item")]
33+
public FullTrack Item { get; set; }
34+
}
35+
}

‎SpotifyAPI/Web/SpotifyWebAPI.cs‎

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using SpotifyAPI.Web.Models;
55
using System;
66
using System.Collections.Generic;
7+
using System.Dynamic;
78
using System.Linq;
89
using System.Runtime.InteropServices;
910
using System.Threading;
@@ -1825,6 +1826,170 @@ public Task<SeveralAudioFeatures> GetSeveralAudioFeaturesAsync(List<string> ids)
18251826

18261827
#endregion Tracks
18271828

1829+
#region Player
1830+
1831+
/// <summary>
1832+
/// Get information about a user’s available devices.
1833+
/// </summary>
1834+
/// <returns></returns>
1835+
public AvailabeDevices GetDevices()
1836+
{
1837+
return DownloadData<AvailabeDevices>(_builder.GetDevices());
1838+
}
1839+
1840+
/// <summary>
1841+
/// Get information about the user’s current playback state, including track, track progress, and active device.
1842+
/// </summary>
1843+
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
1844+
/// <returns></returns>
1845+
public PlaybackContext GetPlayback(string market = "")
1846+
{
1847+
return DownloadData<PlaybackContext>(_builder.GetPlayback(market));
1848+
}
1849+
1850+
/// <summary>
1851+
/// Get the object currently being played on the user’s Spotify account.
1852+
/// </summary>
1853+
/// <param name="market">An ISO 3166-1 alpha-2 country code. Provide this parameter if you want to apply Track Relinking.</param>
1854+
/// <returns></returns>
1855+
public PlaybackContext GetPlayingTrack(string market = "")
1856+
{
1857+
return DownloadData<PlaybackContext>(_builder.GetPlayingTrack(market));
1858+
}
1859+
1860+
/// <summary>
1861+
/// Transfer playback to a new device and determine if it should start playing.
1862+
/// </summary>
1863+
/// <param name="deviceId">ID of the device on which playback should be started/transferred to</param>
1864+
/// <param name="play">
1865+
/// true: ensure playback happens on new device.
1866+
/// false or not provided: keep the current playback state.
1867+
/// </param>
1868+
/// <returns></returns>
1869+
public ErrorResponse TransferPlayback(string deviceId, bool play = false) => TransferPlayback(
1870+
new List<string> { deviceId }, play);
1871+
1872+
/// <summary>
1873+
/// Transfer playback to a new device and determine if it should start playing.
1874+
/// NOTE: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request
1875+
/// </summary>
1876+
/// <param name="deviceIds">A array containing the ID of the device on which playback should be started/transferred.</param>
1877+
/// <param name="play">
1878+
/// true: ensure playback happens on new device.
1879+
/// false or not provided: keep the current playback state.
1880+
/// </param>
1881+
/// <returns></returns>
1882+
public ErrorResponse TransferPlayback(List<string> deviceIds, bool play = false)
1883+
{
1884+
JObject ob = new JObject()
1885+
{
1886+
{ "play", play },
1887+
{ "device_ids", new JArray(deviceIds) }
1888+
};
1889+
return UploadData<ErrorResponse>(_builder.TransferPlayback(), ob.ToString(Formatting.None), "PUT");
1890+
}
1891+
1892+
/// <summary>
1893+
/// Start a new context or resume current playback on the user’s active device.
1894+
/// </summary>
1895+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1896+
/// <param name="contextUri">Spotify URI of the context to play.</param>
1897+
/// <param name="uris">A JSON array of the Spotify track URIs to play.</param>
1898+
/// <param name="offset">Indicates from where in the context playback should start.
1899+
/// Only available when context_uri corresponds to an album or playlist object, or when the uris parameter is used.</param>
1900+
/// <returns></returns>
1901+
public ErrorResponse ResumePlayback(string deviceId = "", string contextUri = "", List<string> uris = null,
1902+
int? offset = null)
1903+
{
1904+
JObject ob = new JObject();
1905+
if(!string.IsNullOrEmpty(contextUri))
1906+
ob.Add("context_uri", contextUri);
1907+
if(uris != null)
1908+
ob.Add("uris", new JArray(uris));
1909+
if(offset != null)
1910+
ob.Add("offset", offset);
1911+
return UploadData<ErrorResponse>(_builder.ResumePlayback(deviceId), ob.ToString(Formatting.None), "PUT");
1912+
}
1913+
1914+
/// <summary>
1915+
/// Pause playback on the user’s account.
1916+
/// </summary>
1917+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1918+
/// <returns></returns>
1919+
public ErrorResponse PausePlayback(string deviceId = "")
1920+
{
1921+
return UploadData<ErrorResponse>(_builder.PausePlayback(deviceId), string.Empty, "PUT");
1922+
}
1923+
1924+
/// <summary>
1925+
/// Skips to next track in the user’s queue.
1926+
/// </summary>
1927+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1928+
/// <returns></returns>
1929+
public ErrorResponse SkipPlaybackToNext(string deviceId = "")
1930+
{
1931+
return UploadData<ErrorResponse>(_builder.SkipPlaybackToNext(deviceId), string.Empty);
1932+
}
1933+
1934+
/// <summary>
1935+
/// Skips to previous track in the user’s queue.
1936+
/// Note that this will ALWAYS skip to the previous track, regardless of the current track’s progress.
1937+
/// Returning to the start of the current track should be performed using the https://api.spotify.com/v1/me/player/seek endpoint.
1938+
/// </summary>
1939+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1940+
/// <returns></returns>
1941+
public ErrorResponse SkipPlaybackToPrevious(string deviceId = "")
1942+
{
1943+
return UploadData<ErrorResponse>(_builder.SkipPlaybackToPrevious(deviceId), string.Empty);
1944+
}
1945+
1946+
/// <summary>
1947+
/// Seeks to the given position in the user’s currently playing track.
1948+
/// </summary>
1949+
/// <param name="positionMs">The position in milliseconds to seek to. Must be a positive number.
1950+
/// Passing in a position that is greater than the length of the track will cause the player to start playing the next song.</param>
1951+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1952+
/// <returns></returns>
1953+
public ErrorResponse SeekPlayback(int positionMs, string deviceId = "")
1954+
{
1955+
return UploadData<ErrorResponse>(_builder.SeekPlayback(positionMs, deviceId), string.Empty);
1956+
}
1957+
1958+
/// <summary>
1959+
/// Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off.
1960+
/// </summary>
1961+
/// <param name="state">track, context or off. </param>
1962+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1963+
/// <returns></returns>
1964+
public ErrorResponse SetRepeatMode(RepeatState state, string deviceId = "")
1965+
{
1966+
return UploadData<ErrorResponse>(_builder.SetRepeatMode(state, deviceId), string.Empty);
1967+
}
1968+
1969+
/// <summary>
1970+
/// Set the volume for the user’s current playback device.
1971+
/// </summary>
1972+
/// <param name="volumePercent">Integer. The volume to set. Must be a value from 0 to 100 inclusive.</param>
1973+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1974+
/// <returns></returns>
1975+
public ErrorResponse SetVolume(int volumePercent, string deviceId = "")
1976+
{
1977+
return UploadData<ErrorResponse>(_builder.SetVolume(volumePercent, deviceId), string.Empty);
1978+
}
1979+
1980+
/// <summary>
1981+
/// Toggle shuffle on or off for user’s playback.
1982+
/// </summary>
1983+
/// <param name="shuffle">True or False</param>
1984+
/// <param name="deviceId">The id of the device this command is targeting. If not supplied, the user's currently active device is the target.</param>
1985+
/// <returns></returns>
1986+
public ErrorResponse SetShuffle(bool shuffle, string deviceId = "")
1987+
{
1988+
return UploadData<ErrorResponse>(_builder.SetShuffle(shuffle, deviceId), string.Empty);
1989+
}
1990+
1991+
#endregion
1992+
18281993
#region Util
18291994

18301995
public TOut GetNextPage<TOut, TIn>(Paging<TIn> paging) where TOut : BasicModel

0 commit comments

Comments
 (0)