/Player/Core/Playlists/Parsers/M3U.cs

http://yet-another-music-application.googlecode.com/ · C# · 181 lines · 123 code · 16 blank · 42 comment · 39 complexity · 9f436b1be2cb4dfeee17cfa08363ed8b MD5 · raw file

  1. /***
  2. * M3U.cs
  3. *
  4. * Reads and writes playlist files in M3U format.
  5. *
  6. * * * * * * * * *
  7. *
  8. * Copyright 2013 Simplare
  9. *
  10. * This code is part of the Stoffi Music Player Project.
  11. * Visit our website at: stoffiplayer.com
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version
  16. * 3 of the License, or (at your option) any later version.
  17. *
  18. * See stoffiplayer.com/license for more information.
  19. ***/
  20. using System;
  21. using System.Collections.Generic;
  22. using System.IO;
  23. using Stoffi.Core.Media;
  24. using Stoffi.Core.Sources;
  25. namespace Stoffi.Core.Playlists.Parsers
  26. {
  27. /// <summary>
  28. /// Parser of playlists in M3U format.
  29. /// </summary>
  30. public class M3U : Parser
  31. {
  32. #region Methods
  33. /// <summary>
  34. /// Read a playlist from a stream.
  35. /// </summary>
  36. /// <param name="reader">Stream reader.</param>
  37. /// <param name="path">The relative path of the tracks in the playlist</param>
  38. /// <param name="resolveMetaData">If true and the playlist contains stream URLs, then a connection will be made to load meta data.</param>
  39. /// <returns>The playlist.</returns>
  40. public override List<Playlist> ReadStream (StreamReader reader, string path = "", bool resolveMetaData = true)
  41. {
  42. var playlist = new Playlist ();
  43. string line;
  44. bool ext = false;
  45. string inf = "";
  46. int nr = 0;
  47. while ((line = reader.ReadLine()) != null)
  48. {
  49. nr++;
  50. if (line.ToLower() == "#extm3u")
  51. ext = true;
  52. else if (ext && line.ToLower().StartsWith("#extinf:"))
  53. inf = line.Substring(8);
  54. else if (line.StartsWith("#") || line == "")
  55. continue;
  56. else
  57. {
  58. string p = line;
  59. TrackType type = Track.GetType(p);
  60. Track track;
  61. string length = "";
  62. string artist = "";
  63. string title = "";
  64. if (inf != "")
  65. {
  66. if (!inf.Contains(","))
  67. {
  68. U.L(LogLevel.Warning, "M3U Parser", "Bad format on line "
  69. + nr + ": expecting ','");
  70. continue;
  71. }
  72. string[] split = inf.Split(',');
  73. length = split[0];
  74. if (split[1].Contains("-"))
  75. {
  76. artist = split[1].Split('-')[0];
  77. title = split[1].Split('-')[1];
  78. }
  79. else
  80. title = split[1];
  81. }
  82. switch (type)
  83. {
  84. case TrackType.File:
  85. if (!File.Exists(p) && File.Exists(Path.Combine(path, p)))
  86. p = Path.Combine(path, p);
  87. if (File.Exists(path))
  88. {
  89. if (!Files.PathIsAdded(path))
  90. Files.AddSource(p);
  91. foreach (Track t in Settings.Manager.FileTracks)
  92. if (t.Path == path)
  93. {
  94. if (!playlist.Tracks.Contains(t))
  95. playlist.Tracks.Add(t);
  96. break;
  97. }
  98. inf = "";
  99. }
  100. break;
  101. case TrackType.WebRadio:
  102. if (resolveMetaData)
  103. track = Media.Manager.ParseURL (p);
  104. else
  105. track = new Track() { Path = p };
  106. if (String.IsNullOrWhiteSpace(track.URL))
  107. track.URL = p;
  108. if (String.IsNullOrWhiteSpace(track.Title))
  109. track.Title = title;
  110. if (track != null && !playlist.Tracks.Contains(track))
  111. playlist.Tracks.Add(track);
  112. break;
  113. case TrackType.YouTube:
  114. track = Sources.Manager.YouTube.CreateTrack(p);
  115. if (track != null && !playlist.Tracks.Contains(track))
  116. playlist.Tracks.Add(track);
  117. break;
  118. case TrackType.SoundCloud:
  119. track = Sources.Manager.SoundCloud.CreateTrack(p);
  120. if (track != null && !playlist.Tracks.Contains(track))
  121. playlist.Tracks.Add(track);
  122. break;
  123. case TrackType.Jamendo:
  124. track = Sources.Manager.Jamendo.CreateTrack(p);
  125. if (track != null && !playlist.Tracks.Contains(track))
  126. playlist.Tracks.Add(track);
  127. break;
  128. }
  129. }
  130. }
  131. return new List<Playlist>() {playlist};
  132. }
  133. /// <summary>
  134. /// Write a playlist to a stream.
  135. /// </summary>
  136. /// <param name="reader">Stream reader.</param>
  137. /// <param name="playlist">Playlist.</param>
  138. /// <param name="writer">Writer.</param>
  139. /// <param name="extension">The extension of the playlist path.</param>
  140. public override void WriteStream (Playlist playlist, StreamWriter writer, string extension = null)
  141. {
  142. writer.WriteLine("#EXTM3U");
  143. writer.WriteLine("");
  144. foreach (var track in playlist.Tracks)
  145. {
  146. writer.WriteLine(String.Format("#EXTINF:{0},{1} - {2}", (int)track.Length, track.Artist, track.Title));
  147. writer.WriteLine(track.Path);
  148. writer.WriteLine("");
  149. }
  150. }
  151. /// <summary>
  152. /// Determines if a playlist path is supported by the parser.
  153. /// </summary>
  154. /// <returns>true</returns>
  155. /// <c>false</c>
  156. /// <param name="path">Path.</param>
  157. public override bool Supports (string path)
  158. {
  159. var ext = Path.GetExtension (path);
  160. var supported = new List<string>() { ".m3u", ".m3u8" };
  161. return !String.IsNullOrWhiteSpace (ext) && supported.Contains (ext.ToLower ());
  162. }
  163. #endregion
  164. }
  165. }