I did a little bit of my music player again.

Source: Internet
Author: User
Tags id3

Some days ago saw the news that Windows10 's own Windows Media Player will support FLAC lossless playback, and the current player is using the Bass Audio Library to support lossless playback, the use of Bass Audio library not to say, not many documents, Encounter problems on-line search for half a day can not find the answer is really worried death, so intend to my music player to do some, this time back to the WMP kernel.


I believe that the development of the WPF Media application of the students know that the new one mediaplayer can achieve the operation of the media, and this mediaplayer is actually used in the current operating system of Windows Media Player, support play pause stop, Playback rate adjustment, volume settings (bass volume setting is very painful, will even the system volume is adjusted), provide media open, media end, play error 3 events, so if you want to do a music player, and then the media status of the judgment, as well as the addition of media status/playback progress changes in the event is almost. Because it is redo, so only to achieve a basic function (playback control, collection, playback mode) and a few personality features (music statistics, timing stop, the display of the progress of the show), while the bug is still a lot, still in development, if interested can be developed together Yo, the project has been uploaded to TFS, The address is http://llyn23.visualstudio.com.

Debug Catalog File Download: Http://yun.baidu.com/s/1xYWua

Solution Project Source code download: Http://yun.baidu.com/s/1mguWDCG

1. Build CoreHelper.cs

This player core class contains media playback, add cancel favorites, toggle playback mode, song file reading, Media Library/playlist/player configuration etc.

2. Saving and reading data

When the program starts (Onstartup), the loaded XML file is deserialized into an object, saved with a media library, a playlist, a playlist, a favorite song, and so on, when exiting (OnExit), the object is serialized into an XML file depending on whether the object has changed

            String repository = System.IO.Path.Combine (new string[] {AppDomain.CurrentDomain.BaseDirectory, "repository"            }); if (!            System.IO.Directory.Exists (repository)) {return; }//load player Settings playerconfig = serializehelper.toentity<playerconfigmodel> (repository + "\\PlayerC            Onfig.xml "); Load Media Library mediacollection = serializehelper.toentity<list<mediamodel>> (repository + "\\MediaCollectio            N.xml ");             Load Playlist playlists = serializehelper.toentity<list<playlistmodel>> (repository + "\\Playlists.xml"); Load Play Queue playqueues = serializehelper.toentity<list<playqueuemodel>> (repository + "\\Pl            Ayqueues.xml "); Load playback Record playrecords = serializehelper.toentity<list<playrecordmodel>> (repository + "\\PlayRecords.            XML "); Load Favorites list Favorites = Serializehelper.toentity<list<favoRitemodel>> (repository + "\\Favorites.xml"); Initialize counter autostopcounter = Playerconfig.autostoptimeset;

            String repository = System.IO.Path.Combine (new string[] {AppDomain.CurrentDomain.BaseDirectory, "repository"});            if (! System.IO.Directory.Exists (repository))            {                try                {                    System.IO.Directory.CreateDirectory (repository );                }                catch (Exception ex)                {                    loghelper.error (ex. Message);                    return;                }            }            Save Player Settings            if (isplayerconfigchanged)            {                serializehelper.toxml<playerconfigmodel> ( Playerconfig, repository + "\\PlayerConfig.xml");            }            Save Media Library            if (ismediacollectionchanged)            {                serializehelper.toxml<list<mediamodel>> ( Mediacollection, repository + "\\MediaCollection.xml");            }

2. Style and Resource usage

The background image and color of the interface element, font color and font size are all stored in the application resource dictionary and can be dynamically updated by code

        <ResourceDictionary>            <ResourceDictionary.MergedDictionaries>                <resourcedictionary source= "/resources/color.xaml" ></ResourceDictionary>                <resourcedictionary source= "/resources/ Imagebrush.xaml "></ResourceDictionary>                <resourcedictionary source="/resources/ Lineargradientbrush.xaml "></ResourceDictionary>                <resourcedictionary source="/resources/ Solidbrush.xaml "></ResourceDictionary>                <resourcedictionary source="/styles/border.xaml ">< /resourcedictionary>                <resourcedictionary source= "/styles/textblock.xaml" ></resourcedictionary >            </ResourceDictionary.MergedDictionaries>        </ResourceDictionary>

3. Playback Control Core Section

In fact, the handling of MediaPlayer 4 events, mediaopened,mediafailed,mediaended, as well as their own added events mediapositionchanging

        private static void _mainplayer_mediaopened (object sender, EventArgs e)        {            //Set Current media            Currentmedia = Mediacollection.where (w = W.fullname = = Httputility.urldecode (MainPlayer.Source.AbsolutePath). Replace ("/", "\ \")). FirstOrDefault ();        }

        private static void _mainplayer_mediafailed (object sender, Exceptioneventargs e)        {            Playerstatus = Playerstatusenum. has ceased;            Loghelper.error (e.errorexception.message);        }

        private static void _mainplayer_mediaended (object sender, EventArgs e) {//Add play History IsP            Layrecordschanged = true; Playrecords.add (new Playrecordmodel {createdat = DateTime.Now, Media = Currentme Dia.            FullName});            Set player Status Playerstatus = Playerstatusenum. stopped;                    Depending on the playback mode, decide which song to play with switch (Playerconfig.playmode) {case (int) playmodeenum. Single loop:                        {playbyrepeat ();                    Break                        } case (int) playmodeenum. List loop: {playbyrecycle ();                    Break                        } case (int) playmodeenum. Sequential playback: {Playbyorder ();                    Break       } case (int) playmodeenum. Random Play: {                 Playbyrandom ();                    Break }            }        }

 

        CoreHelper.cs Trigger Media playback Progress Change event private static void _maintimer1_tick () {if (isautostopopene D && autostopcounter <= 0) {//Stop play (cross-threading) MainPlayer.Dispatcher.Invok                    E (New Action () = {Stop ();                }));                Autostopcounter = Playerconfig.autostoptimeset;                isautostopopened = false;            Return                } if (Playerstatus = = Playerstatusenum. Play) {autostopcounter-= 1;            Mediapositionchanging ();        }}//Handle media playback Progress events in the UI thread corehelper.mediapositionchanging + = corehelper_mediapositionchanging; private void Corehelper_mediapositionchanging () {this.                Dispatcher.invoke (new Action () = {displayautostop ();                TimeSpan Duration = timespan.fromseconds (0); if (coreheLper. MainPlayer.NaturalDuration.HasTimeSpan) {duration = CoreHelper.MainPlayer.NaturalDurati On.                TimeSpan;                } double percent = 0; if (duration. TotalSeconds > 0) {percent = Corehelper.mainplayer.position.totalseconds/duration.                TotalSeconds; }//Display the media playback progress background GS2.                Offset = percent; Gs3.                Offset = percent; Displays the media playback progress and total duration text _mediapositiontextblock.text = String.Format ("{0}/{1}", Stringhelper.gettimespanstring (C            oreHelper.MainPlayer.Position), stringhelper.gettimespanstring (duration));        })); }

5. Update the Media Library

This mainly involves reading the song information from the file, so one step is to read the files in the folder recursively, the second step is to read the song information (through the third-party class library Id3.dll,taglib.dll), the third step is to read the status in real time on the UI

        public static void Findmatchedfile (string folder, list<string> extensions, double minfilelength, double MAXF Ilelength, Updatemediacollectioneventhandler callback) {string[] files = System.IO.Directory.GetFiles (f            Older, "* *", searchoption.topdirectoryonly);            FileInfo info = null;                foreach (string file in files) {info = new FileInfo (file); if (!extensions. Contains (System.IO.Path.GetExtension (file).                ToLower ())) {continue; } if (info.                Length < Minfilelength) {continue; } if (info.                Length > Maxfilelength) {continue;            }//through a delegate to notify the front-end UI callback (file, Addtomediacollection (info)); } string[] directories = System.IO.Directory.GetDirectories (folder, "", Searchoption.topdirecTORYONLY); foreach (string directory in directories) {findmatchedfile (directory, extensions, minfilelength            , Maxfilelength, callback); }        }

 

        public static int addtomediacollection (FileInfo file) {Id3info ID3 = null; try {id3 = new Id3info (file.            FullName, True); } catch (Exception ex) {Loghelper.error (ex.                Message);            return-1;            } Mediamodel Media = new Mediamodel (); The time media that was created.            Createdtime = DateTime.Now; File length media. Filelength = file.            Length; File full path media. FullName = file.            FullName; Song of the album Media. Album = ID3. Id3v2info.gettextframe ("Talb")??            "Unknown album"; The artist media of the song. Artists = ID3. Id3v2info.gettextframe ("TPE1")??            "Unknown singer"; The title of the song media. Title = ID3. Id3v2info.gettextframe ("TIT2")?? System.IO.Path.GetFileNameWithoutExtension (file.            FullName);            Taglib.file f = null; try {f = TagLib.File.Create (File. FullName);               Duration of the song media.                Duration = F.properties.duration.totalseconds; Save song cover if (F.tag.pictures.length > 0) {string folder = System.IO.Pa Th.                    Combine (new string[] {AppDomain.CurrentDomain.BaseDirectory, "Repository", "Cover"}); if (! System.IO.Directory.Exists (folder)) {System.IO.Directory.CreateDirectory (folder)                    ); } byte[] bytes = F.tag.pictures[0].                    Data.data; String cover = System.IO.Path.Combine (new string[] {folder, stringhelper.removespecialcharacters (media.                    Album) + ". jpg"}); using (FileStream fs = new FileStream (cover, FileMode.Create)) {fs. Write (bytes, 0, bytes.                    Length); }}} catch (Exception ex) {Loghelper.debug (ex).    Message);        } Mediamodel model = mediacollection.where (w = w.fullname = = file. FullName).            FirstOrDefault (); if (model = = NULL | | String.IsNullOrEmpty (model.                FullName)) {mediacollection.add (media); Loghelper.debug ("added a media:" + file.)                FullName);            return 1; }//Update media information model. Album = media.            Album; Model. Artists = media.            Artists; Model. Duration = media.            Duration; Model. filelength = media.            Filelength; Model. Title = media.            Title; Loghelper.debug ("Updated a media:" + file.)            FullName);        return 0; }

 

        Private list<int> _operations = null;            private void Updatemediacollectiontextblock_mouseleftbuttondown (object sender, MouseButtonEventArgs e) {            updatemediacollectiontextblock.isenabled = false;            processingmediatextblock.visibility = visibility.visible;            _operations = new list<int> ();            Turn on thread Update Media Library BackgroundWorker worker = new BackgroundWorker (); Worker.            DoWork + = Worker_dowork; Worker.            runworkercompleted + = worker_runworkercompleted; Worker.        RunWorkerAsync (); private void Worker_runworkercompleted (object sender, Runworkercompletedeventargs e) {Updateme            Diacollectiontextblock.isenabled = true;            processingmediatextblock.visibility = visibility.collapsed; int succeed = _operations.            Count (c = = c = 1); int updated = _operations.            Count (c = = c = 0); int failed = _operations. Count (c + = c < 0);            if (Succeed > 0 | | Updated > 0) {corehelper.ismediacollectionchanged = true;            } uihelper.showprompt (String.Format ("NEW: {0}, update: {1}, failed: {2}", succeed, updated, failed));        _operations = null; }

I did a little bit of my music player again.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.