/// <summary> /// Gets the album art for a given track /// </summary> /// <param name="track">The track to find the album art for</param> /// <returns>The album art if it could be found, otherwise a default image</returns> public static ImageSource GetImageTag(TrackData track) { BitmapImage def = new BitmapImage(new Uri(DefaultAlbumArt, UriKind.RelativeOrAbsolute)); switch (MediaManager.GetType(track)) { case TrackType.YouTube: return(new BitmapImage(new Uri(YouTubeManager.GetThumbnail(track)))); case TrackType.SoundCloud: if (track.ArtURL != null) { return(new BitmapImage(new Uri(track.ArtURL))); } break; case TrackType.File: try { TagLib.File file = TagLib.File.Create(track.Path, TagLib.ReadStyle.None); if (file.Tag.Pictures.Count() > 0) { try { TagLib.IPicture pic = file.Tag.Pictures[0]; if (pic.Data.Data.Count <byte>() > 0) { MemoryStream stream = new MemoryStream(pic.Data.Data); BitmapFrame bmp = BitmapFrame.Create(stream); return(bmp); } } catch { } } } catch { } break; } return(def); // return default image }
/// <summary> /// Searches YouTube for tracks matching a certain query /// </summary> /// <param name="query">The query to search for</param> /// <returns>An observable collection of TrackData with all YouTube tracks that match query</returns> public static ObservableCollection <TrackData> Search(string query) { ObservableCollection <TrackData> tracks = new ObservableCollection <TrackData>(); try { string filter = SettingsManager.YouTubeFilter; YouTubeQuery q = new YouTubeQuery(YouTubeQuery.DefaultVideoUri); q.OrderBy = "relevance"; q.Query = query; q.Formats.Add(YouTubeQuery.VideoFormat.Embeddable); q.NumberToRetrieve = 50; q.SafeSearch = YouTubeQuery.SafeSearchValues.None; if (!String.IsNullOrWhiteSpace(filter) && filter != "None") { AtomCategory category = new AtomCategory(filter, YouTubeNameTable.CategorySchema); q.Categories.Add(new QueryCategory(category)); } YouTubeRequest request = new YouTubeRequest(settings); Feed <Video> videoFeed = request.Get <Video>(q); foreach (Video entry in videoFeed.Entries) { tracks.Add(YouTubeManager.CreateTrack(entry)); } } catch (Exception exc) { U.L(LogLevel.Error, "YOUTUBE", "Error while performing search: " + exc.Message); VerifyConnectivity(); } TrackSource = tracks; return(tracks); }
/// <summary> /// Parses an M3U playlist and returns the tracks of it. /// </summary> /// <param name="reader">The data stream of the playlist</param> /// <param name="path">The relative path of the tracks in the playlist</param> /// <returns>A collection of tracks represented by the playlist</returns> private static ObservableCollection <TrackData> ParseM3U(StreamReader reader, string path = "") { ObservableCollection <TrackData> ret = new ObservableCollection <TrackData>(); string line; bool ext = false; string inf = ""; int nr = 0; while ((line = reader.ReadLine()) != null) { nr++; if (line == "#EXTM3U") { ext = true; } else if (ext && line.StartsWith("#EXTINF:")) { inf = line.Substring(8); } else if (line.StartsWith("#") || line == "") { continue; } else { string p = line; TrackType type = MediaManager.GetType(p); TrackData track; switch (type) { case TrackType.File: if (!File.Exists(p) && File.Exists(Path.Combine(path, p))) { p = Path.Combine(path, p); } if (File.Exists(path)) { string length = ""; string artist = ""; string title = ""; if (inf != "") { if (!inf.Contains(',')) { U.L(LogLevel.Warning, "PLAYLIST", "Bad format on line " + nr + ": expecting ','"); continue; } string[] split = inf.Split(','); length = split[0]; if (split[1].Contains('-')) { artist = split[1].Split('-')[0]; title = split[1].Split('-')[1]; } else { title = split[1]; } } if (!FilesystemManager.PathIsAdded(path)) { FilesystemManager.AddSource(p); } foreach (TrackData t in SettingsManager.FileTracks) { if (t.Path == path) { if (!ret.Contains(t)) { ret.Add(t); } break; } } inf = ""; } break; case TrackType.WebRadio: track = MediaManager.ParseURL(p); if (track != null && !ret.Contains(track)) { ret.Add(track); } break; case TrackType.YouTube: track = YouTubeManager.CreateTrack(p); if (track != null && !ret.Contains(track)) { ret.Add(track); } break; case TrackType.SoundCloud: track = SoundCloudManager.CreateTrack(p); if (track != null && !ret.Contains(track)) { ret.Add(track); } break; } } } return(ret); }
/// <summary> /// Parses a PLS playlist and returns the tracks of it. /// </summary> /// <param name="reader">The data stream of the playlist</param> /// <param name="path">The relative path of the tracks in the playlist</param> /// <returns>A collection of tracks represented by the playlist</returns> private static ObservableCollection <TrackData> ParsePLS(StreamReader reader, string path = "") { ObservableCollection <TrackData> ret = new ObservableCollection <TrackData>(); bool hdr = false; string version = ""; int noe = 0; int nr = 0; string line; List <string> lines = new List <string>(); while ((line = reader.ReadLine()) != null) { lines.Add(line); nr++; if (line == "[playlist]") { hdr = true; } else if (!hdr) { U.L(LogLevel.Warning, "PLAYLIST", "Bad format on line " + nr + ": expecting '[playlist]'"); } else if (line.StartsWith("NumberOfEntries=")) { noe = Convert.ToInt32(line.Split('=')[1]); } else if (line.StartsWith("Version=")) { version = line.Split('=')[1]; } } if (!hdr) { U.L(LogLevel.Warning, "PLAYLIST", "No header found"); } // It seems there's many Internet radios that doesn't specify a version, // so we can't be too picky about this one. //else if (version != "2") // U.L(LogLevel.Warning, "PLAYLIST", "Unsupported version '" + // version + "'"); else { string[,] tracks = new string[noe, 3]; nr = 0; foreach (string l in lines) { if (l.StartsWith("File") || l.StartsWith("Title") || l.StartsWith("Length")) { int tmp = 4; int index = 0; if (l.StartsWith("Title")) { tmp = 5; index = 1; } else if (l.StartsWith("Length")) { tmp = 6; index = 2; } string[] split = l.Split('='); int number = Convert.ToInt32(split[0].Substring(tmp)); if (number > noe) { U.L(LogLevel.Warning, "PLAYLIST", "Bad format on line " + nr + ": entry number is '" + number + "' but NumberOfEntries is '" + noe + "'"); } else { tracks[number - 1, index] = split[1]; } } else if (!l.StartsWith("NumberOfEntries") && l != "[playlist]" && !l.StartsWith("Version=")) { U.L(LogLevel.Warning, "PLAYLIST", "Bad format on line " + nr + ": unexpected '" + l + "'"); } } for (int i = 0; i < noe; i++) { string p = tracks[i, 0]; TrackType type = MediaManager.GetType(p); TrackData track; switch (type) { case TrackType.File: if (!File.Exists(p) && File.Exists(Path.Combine(path, p))) { p = Path.Combine(path, p); } if (File.Exists(p)) { if (!FilesystemManager.PathIsAdded(p)) { FilesystemManager.AddSource(p); } foreach (TrackData t in SettingsManager.FileTracks) { if (t.Path == p) { if (!ret.Contains(t)) { ret.Add(t); } break; } } } break; case TrackType.WebRadio: track = MediaManager.ParseURL(p); if (track != null && !ret.Contains(track)) { if (String.IsNullOrWhiteSpace(track.Title)) { track.Title = tracks[i, 1]; } if (String.IsNullOrWhiteSpace(track.URL)) { track.URL = p; } ret.Add(track); } break; case TrackType.YouTube: track = YouTubeManager.CreateTrack(p); if (track != null && !ret.Contains(track)) { ret.Add(track); } break; case TrackType.SoundCloud: track = SoundCloudManager.CreateTrack(p); if (track != null && !ret.Contains(track)) { ret.Add(track); } break; } } } return(ret); }