Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / C#

LyricsFetcher - The Easiest Way to Find Lyrics for your Songs

Rate me:
Please Sign up or sign in to vote.
4.93/5 (82 votes)
29 Oct 2009GPL325 min read 201.2K   2.4K   184  
An article describing the development of a non-trivial C#/.NET application to fetch lyrics for songs.
/*
 * This file holds the class implementations necessary to interact with Window Media Library.
 *
 * Author: Phillip Piper
 * Date: 2009-02-06 4:28 PM
 *
 * CHANGE LOG:
 * 2009-03-14 JPP  Changed to use MetaDataEditor to update lyrics
 * 2009-02-06 JPP  Initial Version
 */

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

using WMPLib;

namespace LyricsFetcher
{
    /// <summary>
    /// This song library knows how to manipulate a WindowMediaPlayer
    /// database. 
    /// </summary>
    public class WmpLibrary : SongLibrary
    {
        protected override SongLoader ChooseSongLoader() {
            return new WmpSongLoader();
        }

        /// <summary>
        /// Close this library
        /// </summary>
        public override void Close() {
            // WMP is embedded in our program, so if we close the library, we 
            // have to stop playing any current songs, otherwise the user has no
            // way to stop the music.
            this.StopPlaying();
            base.Close();
        }

        /// <summary>
        /// Is the given song currently playing
        /// </summary>
        /// <param name="song">The song to check</param>
        /// <returns>Is the given song playing</returns>
        public override bool IsPlaying(Song song)
        {
            WmpSong wmpSong = song as WmpSong;
            if (wmpSong == null)
                return false;

            if (Wmp.Instance.Player.playState != WMPPlayState.wmppsPlaying)
                return false;

            return Wmp.Instance.Player.currentMedia.get_isIdentical(wmpSong.Media);
        }

        /// <summary>
        /// Start the given song playing
        /// </summary>
        /// <param name="song">The song to play</param>
        public override void Play(Song song)
        {
            WmpSong wmpSong = song as WmpSong;
            if (wmpSong != null) {
                Wmp.Instance.Player.currentPlaylist.appendItem(wmpSong.Media);
                Wmp.Instance.Player.controls.playItem(wmpSong.Media);
            }
        }

        /// <summary>
        /// Stop playing any song
        /// </summary>
        public override void StopPlaying()
        {
            Wmp.Instance.Player.controls.stop();
        }

        #region Event handlers

        /// <summary>
        /// Initialize all events required for this library
        /// </summary>
        public override void InitializeEvents()
        {
            Wmp.Instance.Player.PlayStateChange += new _WMPOCXEvents_PlayStateChangeEventHandler(PlayerPlayStateChange);
        }

        /// <summary>
        /// Stop listening for events on this library
        /// </summary>
        public override void DeinitializeEvents()
        {
            Wmp.Instance.Player.PlayStateChange -= new _WMPOCXEvents_PlayStateChangeEventHandler(PlayerPlayStateChange);
        }

        void PlayerPlayStateChange(int NewState) {
            this.OnPlayEvent(new EventArgs());
        }

        #endregion
    }

    public class WmpSongLoader : SongLoader
    {
        protected override object DoWork(DoWorkEventArgs e) {
            try {
                IWMPPlaylist tracks = Wmp.Instance.AllTracks;

                // How many tracks are there and how many songs should we fetch?
                int trackCount = tracks.count;
                int maxSongs = trackCount;
                if (this.MaxSongsToFetch > 0)
                    maxSongs = Math.Min(trackCount, this.MaxSongsToFetch);

                this.ReportProgress(0, "Gettings songs...");
                for (int i = 0; i < trackCount && this.Songs.Count < maxSongs && this.CanContinueRunning; i++) {

                    IWMPMedia track = tracks.get_Item(i);
                    this.AddSong(new WmpSong(track));

                    this.ReportProgress((i * 100) / maxSongs);
                }
            }
            catch (COMException ex) {
                // If the server died or stalled during the load, just ignore it
                if (!(((uint)ex.ErrorCode) == 0x80010007 || ((uint)ex.ErrorCode) == 0x8001010A))
                    throw ex;
            }
            return true;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Team Leader
Australia Australia
Phillip has been playing with computers since the Apple II was the hottest home computer available. He learned the fine art of C programming and Guru meditation on the Amiga.

C# and Python are his languages of choice. Smalltalk is his mentor for simplicity and beauty. C++ is to programming what drills are to visits to the dentist.

He worked for longer than he cares to remember as Lead Programmer and System Architect of the Objective document management system. (www.objective.com)

He has lived for 10 years in northern Mozambique, teaching in villages.

He has developed high volume trading software, low volume FX trading software, and is currently working for Atlassian on HipChat.

Comments and Discussions