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.
Special Thanks to Jon Galloway
for the inspiration to make and improve this.
using System;
using System.IO;
using System.Collections;
using System.Net;
using System.Net.Sockets;
namespace CDYNE.PLSinWindowsMedia
{
class PLSinWindowsMedia
{
static int FileCount;
static int aacCount;
static bool FoundAAC;
static ArrayList Entries = new ArrayList();
static bool CheckForNewEntry(string[] txt)
{
bool ret = false;
if (txt.Length > 0)
{
int tempFC = int.Parse(CleanAllExceptNumbers(txt[0]));
if (FileCount != tempFC)
{
Entries.Add(new plsEntry());
ret = true;
FileCount = tempFC;
}
}
return ret;
}
[STAThread]
static void Main(string[] args)
{
if (args.GetUpperBound(0) > -1)
{
// build asx file
string asxpath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string asxFile = (new FileInfo(asxpath).DirectoryName) + "PLSinWindowsMedia.asx";
Console.WriteLine("Writing ASX FILE: " + asxFile);
FileCount = 0;
using (StreamWriter sw = new StreamWriter(asxFile))
{
sw.WriteLine("<ASX VERSION=\"3.0\">");
sw.WriteLine("<TITLE>wiki.cdyne.com PLS Winamp to Windows Media</TITLE>");
string filename = args[0];
using (StreamReader sr = new StreamReader(filename))
{
string line;
aacCount = 0;
while ((line = sr.ReadLine()) != null)
{
string[] sl = line.Split('=');
if (line.ToLower().StartsWith("file"))
{
// lower the first 4 characters.
sl[1] = sl[1].Substring(0, 4).ToLower() + sl[1].Substring(4);
CheckForNewEntry(sl);
// check url for aac
if (ISAACstream(sl[1]))
{
((plsEntry)Entries[(FileCount - 1)]).Ref = "<REF HREF=\"" + sl[1].Replace("http://", "icyx://") + "\" />";
}
else
{
((plsEntry)Entries[(FileCount - 1)]).Ref = "<REF HREF=\"" + sl[1] + "\" />";
}
}
if (line.ToLower().StartsWith("title"))
{
CheckForNewEntry(sl);
((plsEntry)Entries[(FileCount - 1)]).Title = "<TITLE>" + sl[1] + "</TITLE>";
}
}
sr.Close();
}
foreach (plsEntry ent in Entries)
{
sw.WriteLine("<ENTRY>");
sw.WriteLine(ent.Ref);
sw.WriteLine(ent.Title);
sw.WriteLine("</ENTRY>");
}
sw.WriteLine("</ASX>");
sw.Close();
}
System.Diagnostics.Process.Start("wmplayer.exe", "\"" + asxFile + "\"");
}
else
{
Console.WriteLine("Usage: PLSinWindowsMedia \"playlist.pls\"");
Console.WriteLine("Associate PLS file extension with this application to allow Windows Media Player to play them.");
}
}
private static bool ISAACstream(string url)
{
if (aacCount > 0 || FoundAAC)
return FoundAAC;
// we have to use a tcp socket since WebRequest doesn't like the return :|
Uri u = new Uri(url);
bool aac = false;
Console.WriteLine("Checking stream: " + url + " for AAC");
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
TcpClient client = new TcpClient();
client.SendTimeout = 5000;
client.ReceiveTimeout = 5000;
client.Connect(u.Host, u.Port);
// Translate the passed message into ASCII and store it as a Byte array.
string msg = "GET " + u.AbsolutePath + " HTTP/1.1\r\n";
msg += "Accept: */*\r\n";
msg += "Host: " + u.Host + "\r\n";
msg += "UserAgent: NSPlayer/11.0.5744.6324 WMFSDK/11.0\r\n";
msg += "Accept-Encoding: gzip, deflate\r\n";
msg += "Connection: Keep-Alive\r\n\r\n";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
//Console.WriteLine(stream.ReadByte().ToString());
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
//Console.WriteLine("Sent: {0}", msg);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[8192];
for (int i = 0; i < 2; i++)
{
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
if (responseData.ToLower().Contains("audio/aacp"))
{
Console.WriteLine("Found aac Content type");
aac = true;
FoundAAC = true;
}
//Console.WriteLine("Received: {0}", responseData);
}
// String to store the response ASCII representation.
aacCount += 1;
// Close everything.
stream.Close();
client.Close();
}
catch (Exception e)
{
//Console.WriteLine(e.ToString());
}
return aac;
}
private class plsEntry
{
string p_ref;
string p_title;
public string Ref
{
get { return p_ref; }
set { p_ref = value; }
}
public string Title
{
get { return p_title; }
set { p_title = value; }
}
public plsEntry()
{
}
}
private static bool IsNumeric(string s)
{
try
{
Int32.Parse(s);
}
catch
{
return false;
}
return true;
}
private static string CleanAllExceptNumbers(string Txt)
{
string temp = "";
for (int i = 0; i < Txt.Length; i++)
{
if (IsNumeric(Txt.Substring(i, 1)))
{
temp += Txt.Substring(i, 1);
}
}
return temp;
}
}
}