/// <summary> /// Encode this item into a valid SoundByte protocol item /// </summary> public static string EncodeTrackProtocolItem(TrackProtocolItem protocolItem, bool includeFullUri) { // We will add all paramters to this list var parameters = new Dictionary <string, string>(); // Track if (protocolItem.Track?.Track != null) { parameters.Add("t", $"{(int)protocolItem.Track.Track.ServiceType}:{protocolItem.Track.Track.TrackId}"); } // Track duration if (protocolItem.TrackPosition != null) { parameters.Add("tp", protocolItem.TrackPosition.Value.Seconds.ToString()); } // Source and Source details if (protocolItem.Source != null) { parameters.Add("s", protocolItem.Source.GetType().Name); parameters.Add("sd", string.Join(',', protocolItem.Source.GetParameters().Select(x => $"{x.Key}:{x.Value}"))); } // Playlist token if (!string.IsNullOrEmpty(protocolItem.PlaylistToken)) { parameters.Add("pt", protocolItem.PlaylistToken); } // Playlist if (protocolItem.Playlist != null && protocolItem.Playlist.Any()) { // If we don't have a token, we do not need to send the tracks // unless this is a dummy source. This is because our source can // load the first set of items. if (!string.IsNullOrEmpty(protocolItem.PlaylistToken) && protocolItem.Source?.GetType() != typeof(DummyTrackSource)) { parameters.Add("p", string.Join(',', protocolItem.Playlist.Select(x => $"{(int)x.Track.ServiceType}:{x.Track.TrackId}"))); } } // Is shuffled if (protocolItem.IsShuffled) { parameters.Add("is", "t"); } // Join all the data var contentUri = parameters .Where(param => !string.IsNullOrEmpty(param.Key) && !string.IsNullOrEmpty(param.Value)) .Aggregate(string.Empty, (current, param) => current + "&" + param.Key + "=" + param.Value); return(includeFullUri ? $"sb://track?d={Uri.EscapeDataString(StringHelpers.CompressString(contentUri.TrimStart('&')))}" : $"{Uri.EscapeDataString(StringHelpers.CompressString(contentUri.TrimStart('&')))}"); }
public static async Task HandleTrackProtocolAsync(TrackProtocolItem protocolData) { // If no source was supplied, use the dummy source if (protocolData.Source == null) { protocolData.Source = new DummyTrackSource(); } // Try init the playlist var initPlaylist = await SimpleIoc.Default.GetInstance <IPlaybackService>().InitializePlaylistAsync(protocolData.Source, protocolData.Playlist, protocolData.PlaylistToken); if (initPlaylist.Success == false) { throw new SoundByteException("Could not start playlist", initPlaylist.Message); } await SimpleIoc.Default.GetInstance <IPlaybackService>().StartTrackAsync(protocolData.Track?.Track, protocolData.TrackPosition); }
public static async Task <TrackProtocolItem> DecodeTrackProtocolItemAsync(string compressedData) { // Get the raw data string var data = StringHelpers.DecompressString(Uri.UnescapeDataString(compressedData)); var returnItem = new TrackProtocolItem(); // Get from url var paramCollection = data.Split('&'); // Get the raw data var rawTrack = GetParameterString(paramCollection, "t"); var rawTrackPos = GetParameterString(paramCollection, "tp"); var rawSource = GetParameterString(paramCollection, "s"); var rawSourceData = GetParameterString(paramCollection, "sd"); var rawPlaylistToken = GetParameterString(paramCollection, "pt"); var rawPlaylist = GetParameterString(paramCollection, "p"); var rawShuffled = GetParameterString(paramCollection, "is"); // Add Track if (!string.IsNullOrEmpty(rawTrack)) { var trackService = int.Parse(rawTrack.Split(':')[0]); var trackId = rawTrack.Split(':')[1]; var track = await BaseTrack.GetTrackAsync(trackService, trackId); returnItem.Track = track; } // Add track position if (!string.IsNullOrEmpty(rawTrackPos)) { returnItem.TrackPosition = TimeSpan.FromSeconds(int.Parse(rawTrackPos)); } // Add source if (!string.IsNullOrEmpty(rawSource)) { if (string.IsNullOrEmpty(rawSourceData)) { returnItem.Source = App.SourceManager.GetTrackSource(rawSource); } else { var sourceData = rawSourceData.Split(',').ToDictionary(x => x.Split(':')[0], x => (object)x.Split(':')[1]); returnItem.Source = App.SourceManager.GetTrackSource(rawSource, sourceData); } } // Add Playlist token if (!string.IsNullOrEmpty(rawPlaylistToken)) { returnItem.PlaylistToken = rawPlaylistToken; } // Add playlist items if (!string.IsNullOrEmpty(rawPlaylist)) { var unsortedPlaylistItems = new List <Tuple <int, string> >(); // Get the data and parse it foreach (var trackPair in rawPlaylist.Split(',')) { var trackService = int.Parse(trackPair.Split(':')[0]); var trackId = trackPair.Split(':')[1]; unsortedPlaylistItems.Add(new Tuple <int, string>(trackService, trackId)); } // Sort into wanted groups var soundCloudIds = string.Join(',', unsortedPlaylistItems.Where(x => x.Item1 == ServiceTypes.SoundCloud || x.Item1 == ServiceTypes.SoundCloudV2).Select(x => x.Item2)); var youTubeIds = string.Join(',', unsortedPlaylistItems.Where(x => x.Item1 == ServiceTypes.YouTube).Select(x => x.Item2)); // Temp list of tracks to shove all information into var tempTracks = new List <BaseSoundByteItem>(); // SoundCloud if (!string.IsNullOrEmpty(soundCloudIds)) { tempTracks.AddRange(await BaseTrack.GetTracksAsync(ServiceTypes.SoundCloud, soundCloudIds)); } // YouTube if (!string.IsNullOrEmpty(youTubeIds)) { tempTracks.AddRange(await BaseTrack.GetTracksAsync(ServiceTypes.YouTube, youTubeIds)); } // Add this list of tracks into the return object var rawSortedIds = unsortedPlaylistItems.Select(x => x.Item2).ToList(); returnItem.Playlist = tempTracks.OrderBy(x => rawSortedIds.IndexOf(x.Track.TrackId)); } // Shuffle if (!string.IsNullOrEmpty(rawShuffled)) { returnItem.IsShuffled = rawShuffled == "t"; } return(returnItem); }