Click here to Skip to main content
6,630,901 members and growing! (17,570 online)
Email Password   helpLost your password?
Languages » C# » General     Beginner License: The Code Project Open License (CPOL)

MP3-CMS Project

By thund3rstruck

Update to the MP3-CMS Project
SQL, C# 2.0, Windows, .NET 2.0VS2005, DBA, Dev, QA
Version:2 (See All)
Posted:30 Mar 2007
Updated:2 Jul 2009
Views:42,956
Bookmarked:67 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
13 votes for this article.
Popularity: 3.53 Rating: 3.17 out of 5
3 votes, 23.1%
1
1 vote, 7.7%
2
2 votes, 15.4%
3
3 votes, 23.1%
4
4 votes, 30.8%
5

MP3-CMS Introduction

Resources

Even in 2007 managing digital music libraries remains an enduring problem in a distributed environment. Most of us have pcs or pc appliances in just about every room in the house. Making sure all of these devices all have access to the family's digital music library seems as simple as creating a file server. However as the features included in these standalone players increase, so do application footprints. Each application needs to spend countless hours scanning the file server for music, updating it's database, and then there's the problem of synchronization or having to make sure that all these applications have the newest music in their databases. Ultimately it becomes quite a administrative task.

What is needed is a single interface, with common features that runs entirely from a web server. It needs to be intelligent. Specifically it should allow consumers to create playlists, rate tracks, comment on albums, generate smart playlists based on criteria such as star ratings, genres, newest tracks, and most importantly it should remember which tracks have been played and how often. Based on such analysis the system should recommend music and this system should be self-contained with as little administration as possible. If the users add or delete music from the server, the system should update itself appropriately.

Obviously the CMS is huge and has a degree of complexity that cannot be covered in one article so this article will focus on the core elements I used to satisfy my goals.

Using the Code

For Users

Installing the CMS for users is really simple: See the instructions here for installation.

    For Developers

    We're using subversion for source control and you can get the code (the current trunk or the entire source tree) from our source-forge repository. A complete set of instructions can be found here.

    My Problem

    So back in 2006 or so I was struggling with trying to keep all the music player software on all my computers synchronized and uniform. My Linux seats had Amarok and my Windows seats had a mix of WinAmp, iTunes, and Windows Media Player (argh..). After years of complaining about this hassle I started building an ASPNET based mp3 content management system. My needs were greater than my skill at the time so I strived to leverage re-usable components and recruit collaborators to help me out with this dream project.

    I located an open source flash-based mp3 component from Jeroen Wijering and decided to use it in the application. The component uses an XSPF XML playlist format so all I needed to do was execute a database query and build a properly formed XSPF document to feed to it. To encapsulate the player's JavaScript and properties, a custom UserControl was created to wrap the player:

    Mp3Player User Control

    public partial class controls_Mp3Player : System.Web.UI.UserControl
    {
    	private string _playlist = null;
    	private bool _shuffle = true;
    	private string _movie = "../player/mp3player.swf";
    	private string _scriptPath = "../player/swfobject.js";
    	private string _width = "500";
    	private string _height = "400";
    	private string _bgcolor = "#FFFFFF";
    	private string _lightcolor = "0x0C0C0C";
    	private string _forecolor = "0x000000";
    	private string _backcolor = "0xFFFFFF";
    	private string _displayheight = "200";
    	private bool _repeat = true;
    	private bool _displaythumbs = true;
    	private bool _overstretch = false;
    	private bool _autoscroll = false;
    	private string _callbackPath = "../player/SetPlayCount.aspx";
    
    	protected void Page_Load(object sender, EventArgs e)
    	{ }
    
    	// **** Omitted Properties for Brevity ****
        
    	/// <summary>
    	/// Renders the control.
    	/// </summary>
    
    	/// <param name="writer"></param>
    	protected override void Render(HtmlTextWriter writer)
    	{
    		base.Render(writer);
    		writer.Write(GetHtml());
    	}
    
    	/// <summary>
    	/// Gets the HTML output for the player.
    	/// </summary>
    	/// <returns></returns>
    
    	public string GetHtml()
    	{
    		StringBuilder builder = new StringBuilder();
    
    		builder.AppendFormat("<script type=\"text/javascript\" 
                          src=\"{0}\"></script>\n", _scriptPath);
    		builder.Append("<p id=\"player\"><a 
                          href=\"http://www.macromedia.com/go/getflashplayer\">
                          Get the Flash Player</a> to see this player.</p>\n");
    		builder.Append("<script type=\"text/javascript\">");
    		builder.AppendFormat("var so = new SWFObject('{0}','mpl',
                          '{1}','{2}','7');\n", _movie, _width, _height);
    		builder.AppendFormat("so.addVariable(\"height\",\"{0}\");\n", _height);
    		builder.AppendFormat("so.addVariable(\"width\",\"{0}\");\n", _width);
    		builder.AppendFormat("so.addVariable(\"file\",\"{0}\");\n",
                          HttpUtility.UrlEncode(_playlist));
    		builder.AppendFormat("so.addVariable(\"repeat\",\"{0}\");\n",
                          _repeat.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"overstretch\",\"{0}\");\n",
                          _overstretch.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"displayheight\",\"{0}\");\n",
                          _displayheight);
    		builder.AppendFormat("so.addVariable(\"shuffle\",\"{0}\");\n",
                          _shuffle.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"thumbsinplaylist\",\"{0}\");\n",
                          _displaythumbs.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"overstretch\",\"{0}\");\n",
                          _overstretch.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"lightcolor\",\"{0}\");\n",
                          _lightcolor);
    		builder.AppendFormat("so.addVariable(\"backcolor\",\"{0}\");\n",
                          _backcolor);
    		builder.AppendFormat("so.addVariable(\"frontcolor\",\"{0}\");\n",
                          _forecolor);
    		builder.AppendFormat("so.addVariable(\"autoscroll\",\"{0}\");\n",
                          _autoscroll.ToString().ToLower());
    		builder.AppendFormat("so.addVariable(\"callback\",\"{0}\");\n",
                          _callbackPath);
    		builder.Append("so.write('player');\n");
    		builder.Append("</script>");
    
    		return builder.ToString();
    	}
    }

    Once the Mp3Player control was established we place the player anywhere we want in our pages and define properties cleanly within ASP.NET:

    Using the Control

    <custom:Mp3Player ID="Player" runat="server" Playlist="../scripts/GetPlaylist.aspx"
        EnableViewState="true" 
    Width="350" Height="200" BgColor="#000000" DisplayHeight="0" Repeat="true" Shuffle="false" 
    BackColor="0xFFFFFF" ForeColor="0x000000" DisplayThumbs="false" OverStretch="false" />

    In earlier versions of the CMS, I used to use cycles in the scanner to cache XSPF playlists but now they're generated dynamically with a script written to do it. Basically when the user clicks on a playlist or loads a page where a player is being used the [UNIQUE] trackId values are saved in a client cookie, which the playlist generation script reads from.

    Generating XSPF Playlists AD-Hoc

    <script runat="server">	
    	protected void Page_Load(object sender, EventArgs e)
    	{		
    		string playlistTrackIds = Convert.ToString(
                          Request.Cookies["playlist_tracks"].Value);
    		string[] trackIds = playlistTrackIds.Split(new char[] { ',' },
                          StringSplitOptions.RemoveEmptyEntries);
    
    		List<int> trackIdList = new List<int>();
    
    		foreach (string trackId in trackIds)
    			trackIdList.Add(Convert.ToInt32(trackId));
    		
    		IList<Track> tracks = TrackRepository.GetTracksById(trackIdList);
    		List<Track> sortedTracks = new List<Track>();
    		
    		foreach (int trackId in trackIdList)
    		{
    			foreach (Track track in tracks)
    			{
    				if (track.Id == trackId)
    				{
    					sortedTracks.Add(track);
    					break;
    				}
    			}
    		}
    
    		StreamWriter writer = new StreamWriter(Response.OutputStream);
    		string playlistXml = Playlist.GenerateXml(sortedTracks);
    		writer.Write(playlistXml);
    		writer.Flush();
    	}	
    
    </script>

    With the Mp3Player control and dynamic playlist generation we have the core processing engine for the solution. For reading & writing ID3Tags I'm using this ID3 library from HundredMilesSoftware.

    Conclusion

    We've recently released v2.0.0.0 to the public and it's getting a positive response so far. Please feel free to download, modify, improve, and participate in the project! A lot of people spent a lot of time on this project and I hope that everyone out there really enjoys it.

    History

    • Dumped the revised article; updated for v2.0.0.0
    • Dumped the original article; updated for v1.5.0.3
    • Updated article 03/07: entire code base re-written. Article depreciated
    • Originally submitted 03-30-2007
    • Online Demo is now up 04-01-2007
    • Fixed broken links
    • Updated article 06-14-2007

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

thund3rstruck


Member
I'm a typical 30 year old generation X guy that likes video games, NFL football, and comic style art. I have an insatiable passion for programming and doing what ever it takes to become a better programmer.
Occupation: Software Developer
Location: United States United States

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 32 (Total in Forum: 32) (Refresh)FirstPrevNext
Generalsource tree Pinmembermjmeans18:26 18 Nov '08  
GeneralRe: source tree Pinmembermjmeans18:59 18 Nov '08  
GeneralRe: source tree Pinmembermjmeans19:09 18 Nov '08  
GeneralRe: source tree Pinmembermjmeans19:19 18 Nov '08  
GeneralRe: source tree Pinmembermjmeans19:24 18 Nov '08  
GeneralRe: source tree - almost running Pinmembermjmeans20:13 18 Nov '08  
GeneralRe: source tree - GOT IT! Pinmembermjmeans21:11 18 Nov '08  
GeneralRe: source tree - GOT IT! Pinmemberthund3rstruck4:23 19 Nov '08  
GeneralRe: source tree - GOT IT! Pinmembermjmeans21:06 19 Nov '08  
GeneralRe: source tree - GOT IT! Pinmemberthund3rstruck4:48 20 Nov '08  
GeneralRe: source tree - APPOLOGY Pinmembermjmeans12:38 21 Nov '08  
RantRe: source tree - GOT IT! PinmemberCodeMasterMP8:22 20 Nov '08  
Generalmanage.aspx missing Pinmembermjmeans22:03 17 Nov '08  
GeneralRe: manage.aspx missing Pinmemberthund3rstruck5:04 18 Nov '08  
GeneralRe: manage.aspx missing Pinmembermjmeans14:34 18 Nov '08  
GeneralRe: manage.aspx missing Pinmemberthund3rstruck16:51 18 Nov '08  
GeneralFileSystemWatcher PinmemberbinaryDigit@@21:50 26 Sep '08  
GeneralRe: FileSystemWatcher Pinmemberthund3rstruck19:03 27 Sep '08  
QuestionSystem.Data.SQLite.SQLiteException: Unable to open the database file Pinmembermshehadeh23:26 27 Mar '08  
GeneralRe: System.Data.SQLite.SQLiteException: Unable to open the database file Pinmemberthund3rstruck4:32 28 Mar '08  
GeneralMP3-CMS v1.5.0 Pinmemberthund3rstruck15:57 7 Mar '08  
GeneralSong is not playing Pinmemberqumer1013:59 5 Apr '07  
GeneralRe: Song is not playing Pinmemberthund3rstruck4:23 5 Apr '07  
GeneralRe: Song is not playing Pinmemberqumer1015:42 5 Apr '07  
GeneralRe: Song is not playing Pinmemberthund3rstruck6:16 5 Apr '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 2 Jul 2009
Editor: Sean Ewington
Copyright 2007 by thund3rstruck
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project