Playing PLS Winamp files in Windows Media

From CDYNE Wiki
Jump to navigation Jump to search

Description

Allows you to play PLS (Winamp Streaming Files) from sources like Shoutcast, SomaFM, Sky.fm, or any other WinAmp PLS compatible site. There will be more information on how to get those working later.

Requirements

  • Any Windows Media 9, 10, or 11+ platform (Tested and working on Vista Windows Media 11).
  • Tested and works great on 32 and 64 bit Operating Systems.

Features

V1.0

  • Play from any browser window.
  • Winamp is not required. (Winamp Alternative)
  • Loads all the streams into the playlist.
  • Plays MP3 HTTP streams.

V1.0 with AAC Support * Not recommended *

  • All the features in V1.0 with playing AAC/AAC+ streams.
  • A little slower to load the playlist since it has to open the stream and find the AAC+ media type.
  • You must download the Orban AAC/aacPlus Plugin for Windows Media. for AAC/AAC+ streams to work.

Downloadable Installer

Source Code and Credits

Special Thanks to Jon Galloway for the inspiration to make and improve this.

  1 using System;
  2 using System.IO;
  3 using System.Collections;
  4 using System.Net;
  5 using System.Net.Sockets;
  6 
  7 namespace CDYNE.PLSinWindowsMedia
  8 {
  9     class PLSinWindowsMedia
 10     {
 11         static int FileCount;
 12         static int aacCount;
 13         static bool FoundAAC;
 14         static ArrayList Entries = new ArrayList();
 15 
 16         static bool CheckForNewEntry(string[] txt)
 17         {
 18             bool ret = false;
 19             if (txt.Length > 0)
 20             {
 21                 int tempFC = int.Parse(CleanAllExceptNumbers(txt[0]));
 22                 if (FileCount != tempFC)
 23                 {
 24 
 25                     Entries.Add(new plsEntry());
 26                     ret = true;
 27                     FileCount = tempFC;
 28                 }
 29 
 30             }
 31 
 32             return ret;
 33         }
 34 
 35         [STAThread]
 36         static void Main(string[] args)
 37         {
 38             if (args.GetUpperBound(0) > -1)
 39             {
 40                 // build asx file
 41                 string asxpath = System.Reflection.Assembly.GetExecutingAssembly().Location;
 42                 string asxFile = (new FileInfo(asxpath).DirectoryName) + "PLSinWindowsMedia.asx";
 43                 Console.WriteLine("Writing ASX FILE: " + asxFile);
 44                 FileCount = 0;
 45                 using (StreamWriter sw = new StreamWriter(asxFile))
 46                 {
 47                     sw.WriteLine("<ASX VERSION=\"3.0\">");
 48                     sw.WriteLine("<TITLE>wiki.cdyne.com PLS Winamp to Windows Media</TITLE>");
 49 
 50                     string filename = args[0];
 51 
 52 
 53                     using (StreamReader sr = new StreamReader(filename))
 54                     {
 55                         string line;
 56                         aacCount = 0;
 57 
 58                         while ((line = sr.ReadLine()) != null)
 59                         {
 60                             string[] sl = line.Split('=');
 61                             if (line.ToLower().StartsWith("file"))
 62                             {
 63                                 // lower the first 4 characters.
 64                                 sl[1] = sl[1].Substring(0, 4).ToLower() + sl[1].Substring(4);
 65                                 CheckForNewEntry(sl);
 66                                 // check url for aac
 67                                 if (ISAACstream(sl[1]))
 68                                 {
 69                                     ((plsEntry)Entries[(FileCount - 1)]).Ref = "<REF HREF=\"" + sl[1].Replace("http://", "icyx://") + "\" />";
 70 
 71                                 }
 72                                 else
 73                                 {
 74                                     ((plsEntry)Entries[(FileCount - 1)]).Ref = "<REF HREF=\"" + sl[1] + "\" />";
 75                                 }
 76 
 77                             }
 78                             if (line.ToLower().StartsWith("title"))
 79                             {
 80                                 CheckForNewEntry(sl);
 81                                 ((plsEntry)Entries[(FileCount - 1)]).Title = "<TITLE>" + sl[1] + "</TITLE>";
 82                             }
 83                         }
 84                         sr.Close();
 85                     }
 86                     foreach (plsEntry ent in Entries)
 87                     {
 88                         sw.WriteLine("<ENTRY>");
 89                         sw.WriteLine(ent.Ref);
 90                         sw.WriteLine(ent.Title);
 91                         sw.WriteLine("</ENTRY>");
 92                     }
 93 
 94 
 95                     sw.WriteLine("</ASX>");
 96                     sw.Close();
 97                 }
 98                 System.Diagnostics.Process.Start("wmplayer.exe", "\"" + asxFile + "\"");
 99 
100             }
101             else
102             {
103                 Console.WriteLine("Usage: PLSinWindowsMedia \"playlist.pls\"");
104                 Console.WriteLine("Associate PLS file extension with this application to allow Windows Media Player to play them.");
105             }
106         }
107 
108         private static bool ISAACstream(string url)
109         {
110             
111             if (aacCount > 0 || FoundAAC)
112                 return FoundAAC;
113             // we have to use a tcp socket since WebRequest doesn't like the return :|
114             Uri u = new Uri(url);
115             bool aac = false;
116             Console.WriteLine("Checking stream: " + url + " for AAC");
117             try
118             {
119                 // Create a TcpClient.
120                 // Note, for this client to work you need to have a TcpServer 
121                 // connected to the same address as specified by the server, port
122                 // combination.
123                 TcpClient client = new TcpClient();
124 
125                 client.SendTimeout = 5000;
126                 client.ReceiveTimeout = 5000;
127                 client.Connect(u.Host, u.Port);
128                 // Translate the passed message into ASCII and store it as a Byte array.
129                 string msg = "GET " + u.AbsolutePath + " HTTP/1.1\r\n";
130                 msg += "Accept: */*\r\n";
131                 msg += "Host: " + u.Host + "\r\n";
132                 msg += "UserAgent:  NSPlayer/11.0.5744.6324 WMFSDK/11.0\r\n";
133                 msg += "Accept-Encoding:  gzip, deflate\r\n";
134                 msg += "Connection: Keep-Alive\r\n\r\n";
135 
136                 Byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
137 
138                 // Get a client stream for reading and writing.
139                 //  Stream stream = client.GetStream();
140 
141                 NetworkStream stream = client.GetStream();
142                 //Console.WriteLine(stream.ReadByte().ToString());
143                 // Send the message to the connected TcpServer. 
144                 stream.Write(data, 0, data.Length);
145 
146 
147                 //Console.WriteLine("Sent: {0}", msg);
148 
149                 // Receive the TcpServer.response.
150 
151                 // Buffer to store the response bytes.
152                 data = new Byte[8192];
153 
154                 for (int i = 0; i < 2; i++)
155                 {
156                     String responseData = String.Empty;
157 
158                     // Read the first batch of the TcpServer response bytes.
159                     Int32 bytes = stream.Read(data, 0, data.Length);
160                     responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
161                     if (responseData.ToLower().Contains("audio/aacp"))
162                     {
163                         Console.WriteLine("Found aac Content type");
164                         aac = true;
165                         FoundAAC = true;
166                     }
167 
168                     //Console.WriteLine("Received: {0}", responseData);
169                 }
170                 // String to store the response ASCII representation.
171 
172                 aacCount += 1;
173                 // Close everything.
174                 stream.Close();
175                 client.Close();
176             }
177             catch (Exception e)
178             {
179                 //Console.WriteLine(e.ToString());
180             }
181 
182 
183 
184 
185             return aac;
186         }
187 
188         private class plsEntry
189         {
190             string p_ref;
191             string p_title;
192 
193             public string Ref
194             {
195                 get { return p_ref; }
196                 set { p_ref = value; }
197             }
198             public string Title
199             {
200                 get { return p_title; }
201                 set { p_title = value; }
202             }
203 
204             public plsEntry()
205             {
206             }
207         }
208 
209         private static bool IsNumeric(string s)
210         {
211             try
212             {
213                 Int32.Parse(s);
214             }
215             catch
216             {
217                 return false;
218             }
219             return true;
220         }
221 
222         private static string CleanAllExceptNumbers(string Txt)
223         {
224             string temp = "";
225             for (int i = 0; i < Txt.Length; i++)
226             {
227                 if (IsNumeric(Txt.Substring(i, 1)))
228                 {
229                     temp += Txt.Substring(i, 1);
230                 }
231             }
232 
233             return temp;
234         }
235 
236     }
237 
238 }