Пример #1
0
        public static void RenameArtFileCanExec(object sender, CanExecuteRoutedEventArgs e)
        {
            string filePath = e.Parameter as string;

            //TODO: Check for file existence and permissions here too?
            e.CanExecute = !String.IsNullOrEmpty(filePath) && !EmbeddedArtHelpers.IsEmbeddedArtPath(filePath);
        }
Пример #2
0
        /// <summary>
        /// Sets all properties related to an album having a file present:
        /// <see cref="ArtFile"/> set to <paramref name="filePath"/>
        /// <see cref="ArtFileStatus"/> set to <see cref="ArtFileStatus.Present"/>
        /// <see cref="ArtFileSize"/> set to the file size (or 0 if it could not be determined)
        /// <see cref="ArtFileWidth"/> and <see cref="ArtFileHeight"/> to the file image dimensions (or 0 if they could not be determined)
        /// </summary>
        /// <param name="filePath"></param>
        public void SetArtFile(string filePath)
        {
            ArtFile       = filePath;
            ArtFileStatus = ArtFileStatus.Present;

            if (EmbeddedArtHelpers.IsEmbeddedArtPath(filePath))
            {
                //Get the size of the embedded image, not the size of the file itself
                try
                {
                    var embeddedArt = EmbeddedArtHelpers.GetEmbeddedArt(filePath);
                    if (embeddedArt != null)
                    {
                        ArtFileSize = embeddedArt.Data.Count;

                        using (var dataStream = new MemoryStream(embeddedArt.Data.Data, false))
                        {
                            var bitmapDecoder = BitmapDecoder.Create(dataStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
                            ArtFileWidth  = bitmapDecoder.Frames[0].PixelWidth;
                            ArtFileHeight = bitmapDecoder.Frames[0].PixelHeight;
                        }
                    }
                }
                catch (Exception)
                {
                    //Ignore exceptions when reading the embedded artwork; it's not important at this stage
                    ArtFileSize  = 0;
                    ArtFileWidth = ArtFileHeight = 0;
                }
            }
            else
            {
                //Not an embedded image, but an image file itself
                try
                {
                    ArtFileSize = new FileInfo(filePath).Length;
                }
                catch (Exception)
                {
                    //Ignore exceptions when reading the filesize it's not important
                    ArtFileSize = 0;
                }

                //Attempt to get the image dimesions
                try
                {
                    using (var fileStream = File.OpenRead(filePath))
                    {
                        var bitmapDecoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
                        ArtFileWidth  = bitmapDecoder.Frames[0].PixelWidth;
                        ArtFileHeight = bitmapDecoder.Frames[0].PixelHeight;
                    }
                }
                catch (Exception)
                {
                    //Ignore exceptions when reading the dimensions, they aren't important
                    ArtFileWidth = ArtFileHeight = 0;
                }
            }
        }
Пример #3
0
        private static void AddEmbeddedPictureToResults(AlbumArtDownloader.Scripts.IScriptResults results, TagLib.IPicture[] embeddedPictures, int embeddedIndex, string filename)
        {
            //Create an in-memory copy so that the bitmap file isn't in use, and can be replaced
            Bitmap bitmap = new Bitmap(new MemoryStream(embeddedPictures[embeddedIndex].Data.Data));             //NOTE: Do not dispose of MemoryStream, or it will cause later saving of the bitmap to throw a generic GDI+ error (annoyingly)

            results.Add(bitmap, EmbeddedArtHelpers.GetEmbeddedFilePath(Path.GetFileName(filename), embeddedIndex), filename, bitmap.Width, bitmap.Height, null);
        }
Пример #4
0
        public static void ShowInExplorerExec(object sender, ExecutedRoutedEventArgs e)
        {
            string filePath = e.Parameter as string;

            if (!String.IsNullOrEmpty(filePath))
            {
                //TODO: Validation that this is a valid file path?
                if (EmbeddedArtHelpers.IsEmbeddedArtPath(filePath))
                {
                    int ignored;
                    EmbeddedArtHelpers.SplitToFilenameAndIndex(filePath, out filePath, out ignored);
                }
                System.Diagnostics.Process.Start("explorer.exe", "/select,\"" + filePath + "\"");
            }
        }
Пример #5
0
        private void ReadFoobarWorker()
        {
            try
            {
                Foobar2000.Tracks07 tracks = SelectedPlaylist.GetTracks(null);
                //Now searching for something, so set the state to indicate that.
                //Also set the count of albums, for the progress bar
                Dispatcher.Invoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                {
                    State        = BrowserState.FindingFiles;
                    Progress     = 0;
                    ProgressMax  = tracks.Count;
                    ProgressText = "Reading Media Library...";
                }));
                foreach (Foobar2000.Track07 track in tracks)
                {
                    string artistName = track.FormatTitle("%album artist%");
                    string albumName  = track.FormatTitle("%album%");
                    string filename   = track.FormatTitle("%path%");
                    string path;
                    try
                    {
                        path = System.IO.Path.GetDirectoryName(filename);
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Trace.WriteLine("Could not get file path for \"" + artistName + "\" / \"" + albumName + "\": " + filename);
                        System.Diagnostics.Trace.Indent();
                        System.Diagnostics.Trace.WriteLine(e.Message);
                        System.Diagnostics.Trace.Unindent();
                        continue;                         //skip this one, can't find the path.
                    }

                    var  album      = new Album(path, artistName, albumName);
                    bool addedAlbum = false;

                    Dispatcher.Invoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                    {
                        Progress++;
                        if (!(String.IsNullOrEmpty(artistName) && String.IsNullOrEmpty(albumName)))                         //No point adding it if no artist or album could be found.
                        {
                            addedAlbum = mAlbums.Add(album);
                        }
                    }));

                    if (addedAlbum)
                    {
                        // Check for embedded art
                        int?        embeddedArtIndex = null;
                        TagLib.File fileTags         = null;
                        try
                        {
                            fileTags         = TagLib.File.Create(filename, TagLib.ReadStyle.None);
                            embeddedArtIndex = EmbeddedArtHelpers.GetEmbeddedFrontCoverIndex(fileTags);
                        }
                        catch (Exception e)
                        {
                            System.Diagnostics.Trace.WriteLine("TagLib# could not get embedded artwork for file: " + filename);
                            System.Diagnostics.Trace.Indent();
                            System.Diagnostics.Trace.WriteLine(e.Message);
                            System.Diagnostics.Trace.Unindent();
                            //If embedded images couldn't be read, ignore that
                        }
                        finally
                        {
                            if (fileTags != null)
                            {
                                fileTags.Mode = TagLib.File.AccessMode.Closed;
                            }
                        }

                        if (embeddedArtIndex.HasValue)
                        {
                            //Read the picture from the data
                            album.SetArtFile(EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedArtIndex.Value));
                        }
                    }
                }

                //Finished with the FindingFiles state, so now set the state to whatever the results state is (either FindingArt, or Done).
                Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                {
                    ProgressText = mResults.ProgressText;
                    State        = mResults.State;
                }));
            }
            catch (ThreadAbortException)
            {
                Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                {
                    State = BrowserState.Stopped;
                }));
            }
            catch (Exception e)
            {
                uint hResult = (uint)System.Runtime.InteropServices.Marshal.GetHRForException(e);

                if (e is COMException ||
                    (hResult == 0x800706BE ||                    //RPC failed
                     hResult == 0x80004002))                     //No interface
                {
                    SetErrorState("Lost connection to Foobar automation server while reading media library");
                }
                else
                {
                    SetErrorState(String.Format("Error occurred while reading media library: {0}", e.Message));
                }
            }
        }
Пример #6
0
        protected override void SearchInternal(string artist, string album, AlbumArtDownloader.Scripts.IScriptResults results)
        {
            //Add the pattern used to the history list.
            CustomSettingsUI.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind, new System.Threading.ThreadStart(delegate
            {
                ((LocalFilesSourceSettings)CustomSettingsUI).mSearchPathPatternBox.AddPatternToHistory();
            }));

            int lastMinImageSizeSet = 0;

            //Avoid duplicates
            StringDictionary addedFiles = new StringDictionary();

            string pathPattern = GetSearchPath(artist, album);

            foreach (string alternate in pathPattern.Split('|'))
            {
                int?   embeddedIndex         = null;
                string unembeddedPathPattern = alternate;

                if (EmbeddedArtHelpers.IsEmbeddedArtPath(alternate))
                {
                    //TODO: Allow a pattern to specify multiple embedded images as "<?>" or similar.
                    int i;
                    EmbeddedArtHelpers.SplitToFilenameAndIndex(alternate, out unembeddedPathPattern, out i);
                    embeddedIndex = i;
                }

                //Match path with wildcards
                foreach (string filename in Common.ResolvePathPattern(unembeddedPathPattern))
                {
                    if (!addedFiles.ContainsKey(filename))                     //Don't re-add a file that's already been added
                    {
                        addedFiles.Add(filename, null);

                        if (embeddedIndex.HasValue)
                        {
                            //Read embedded image from file, rather than the file itself as an image
                            TagLib.File fileTags = null;
                            try
                            {
                                fileTags = TagLib.File.Create(filename, TagLib.ReadStyle.None);

                                var embeddedPictures = fileTags.Tag.Pictures;
                                if (embeddedIndex.Value == -1)                                 //Special value indicating "all embedded images"
                                {
                                    for (int i = 0; i < embeddedPictures.Length; i++)
                                    {
                                        AddEmbeddedPictureToResults(results, embeddedPictures, i, filename);
                                    }
                                }
                                else if (embeddedPictures.Length > embeddedIndex.Value)
                                {
                                    //Found the embedded image
                                    AddEmbeddedPictureToResults(results, embeddedPictures, embeddedIndex.Value, filename);
                                }
                                else
                                {
                                    System.Diagnostics.Trace.WriteLine("Skipping file missing specified embedded image in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value));
                                }
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Trace.WriteLine("Skipping unreadable embedded image from file in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value));
                                System.Diagnostics.Trace.Indent();
                                System.Diagnostics.Trace.WriteLine(e.Message);
                                System.Diagnostics.Trace.Unindent();
                            }
                            finally
                            {
                                if (fileTags != null)
                                {
                                    fileTags.Mode = TagLib.File.AccessMode.Closed;
                                }
                            }
                        }
                        else
                        {
                            //Each filename is potentially an image, so try to load it
                            try
                            {
                                using (var filestream = File.OpenRead(filename))
                                {
                                    var decoder = BitmapDecoder.Create(filestream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None); //Don't cache, only want the width and height, and delay creation as no need to actually read the data.
                                    var frame   = decoder.Frames[0];
                                    int width   = frame.PixelWidth;
                                    int height  = frame.PixelHeight;

                                    results.Add(File.OpenRead(filename), Path.GetFileName(filename), filename, width, height, null);

                                    if (SetMinimumSizeFilter)
                                    {
                                        var minImageSize = Math.Min(width, height);
                                        if (lastMinImageSizeSet == 0)
                                        {
                                            Properties.Settings.Default.UseMinimumImageSize = true;
                                            Properties.Settings.Default.MinimumImageSize    = lastMinImageSizeSet = minImageSize;
                                        }
                                        else if (Properties.Settings.Default.UseMinimumImageSize && Properties.Settings.Default.MinimumImageSize == lastMinImageSizeSet)            // Don't override during a search if the user has made manual changes
                                        {
                                            Properties.Settings.Default.MinimumImageSize = Math.Max(lastMinImageSizeSet, minImageSize);                                             // If this image is bigger, use it as the minimum size
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Trace.WriteLine("Skipping unreadable file in local file search: " + filename);
                                System.Diagnostics.Trace.Indent();
                                System.Diagnostics.Trace.WriteLine(e.Message);
                                System.Diagnostics.Trace.Unindent();
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
 private static void AddEmbeddedPictureToResults(AlbumArtDownloader.Scripts.IScriptResults results, TagLib.IPicture[] embeddedPictures, int embeddedIndex, string filename)
 {
     results.Add(new MemoryStream(embeddedPictures[embeddedIndex].Data.Data), EmbeddedArtHelpers.GetEmbeddedFilePath(Path.GetFileName(filename), embeddedIndex), filename, -1, -1, null);
 }
Пример #8
0
        protected override void SearchInternal(string artist, string album, AlbumArtDownloader.Scripts.IScriptResults results)
        {
            //Add the pattern used to the history list.
            CustomSettingsUI.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind, new System.Threading.ThreadStart(delegate
            {
                ((LocalFilesSourceSettings)CustomSettingsUI).mSearchPathPatternBox.AddPatternToHistory();
            }));

            //Avoid duplicates
            StringDictionary addedFiles = new StringDictionary();

            string pathPattern = GetSearchPath(artist, album);

            foreach (string alternate in pathPattern.Split('|'))
            {
                int?   embeddedIndex         = null;
                string unembeddedPathPattern = alternate;

                if (EmbeddedArtHelpers.IsEmbeddedArtPath(alternate))
                {
                    //TODO: Allow a pattern to specify multiple embedded images as "<?>" or similar.
                    int i;
                    EmbeddedArtHelpers.SplitToFilenameAndIndex(alternate, out unembeddedPathPattern, out i);
                    embeddedIndex = i;
                }

                //Match path with wildcards
                foreach (string filename in Common.ResolvePathPattern(unembeddedPathPattern))
                {
                    if (!addedFiles.ContainsKey(filename))                     //Don't re-add a file that's already been added
                    {
                        addedFiles.Add(filename, null);

                        if (embeddedIndex.HasValue)
                        {
                            //Read embedded image from file, rather than the file itself as an image
                            TagLib.File fileTags = null;
                            try
                            {
                                fileTags = TagLib.File.Create(filename, TagLib.ReadStyle.None);

                                var embeddedPictures = fileTags.Tag.Pictures;
                                if (embeddedIndex.Value == -1)                                 //Special value indicating "all embedded images"
                                {
                                    for (int i = 0; i < embeddedPictures.Length; i++)
                                    {
                                        AddEmbeddedPictureToResults(results, embeddedPictures, i, filename);
                                    }
                                }
                                else if (embeddedPictures.Length > embeddedIndex.Value)
                                {
                                    //Found the embedded image
                                    AddEmbeddedPictureToResults(results, embeddedPictures, embeddedIndex.Value, filename);
                                }
                                else
                                {
                                    System.Diagnostics.Trace.WriteLine("Skipping file missing specified embedded image in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value));
                                }
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Trace.WriteLine("Skipping unreadable embedded image from file in local file search: " + EmbeddedArtHelpers.GetEmbeddedFilePath(filename, embeddedIndex.Value));
                                System.Diagnostics.Trace.Indent();
                                System.Diagnostics.Trace.WriteLine(e.Message);
                                System.Diagnostics.Trace.Unindent();
                            }
                            finally
                            {
                                if (fileTags != null)
                                {
                                    fileTags.Mode = TagLib.File.AccessMode.Closed;
                                }
                            }
                        }
                        else
                        {
                            //Each filename is potentially an image, so try to load it
                            try
                            {
                                IntPtr hBitmap;
                                int    status = GdipCreateBitmapFromFile(filename, out hBitmap);
                                GdipDisposeImage(new HandleRef(this, hBitmap));
                                if (status == 0)
                                {
                                    //Successfully opened as image

                                    //Create an in-memory copy so that the bitmap file isn't in use, and can be replaced
                                    byte[] fileBytes = File.ReadAllBytes(filename);                                     //Read the file, closing it after use
                                    Bitmap bitmap    = new Bitmap(new MemoryStream(fileBytes));                         //NOTE: Do not dispose of MemoryStream, or it will cause later saving of the bitmap to throw a generic GDI+ error (annoyingly)
                                    results.Add(bitmap, Path.GetFileName(filename), filename, bitmap.Width, bitmap.Height, null);
                                }
                                else
                                {
                                    System.Diagnostics.Trace.WriteLine("Skipping non-bitmap file in local file search: " + filename);
                                }
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Trace.WriteLine("Skipping unreadable file in local file search: " + filename);
                                System.Diagnostics.Trace.Indent();
                                System.Diagnostics.Trace.WriteLine(e.Message);
                                System.Diagnostics.Trace.Unindent();
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
        /// <summary>Reads the album and artist data from specified media file or folder. Adds it to the <see cref="mAlbums"/> collection, and if it does so, also adds it to <paramref name="addedAlbums"/>.</summary>
        /// <param name="filePathPattern">Use null to use the ID3 tags instead</param>
        /// <returns>The <see cref="Album"/> that was added to <see cref="mAlbums"/>, or <c>null</c> if none could be read.</returns>
        private void ReadMediaFile(FileSystemInfo file, Regex filePathPattern, IList <Album> addedAlbums)
        {
            if (file is DirectoryInfo && filePathPattern == null)             //If a DirectoryInfo is used, then the filePathPattern must have ended in \.
            {
                throw new ArgumentException("Directories are only supported for pattern matching, not ID3 tags", "file");
            }

            Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new ThreadStart(delegate
            {
                ProgressText = "Searching... " + file.Name;
            }));

            string artistName       = null;
            string albumName        = null;
            int?   embeddedArtIndex = null;

            if (filePathPattern == null)
            {
                //Read ID3 Tags
                TagLib.File fileTags = null;
                try
                {
                    fileTags = TagLib.File.Create(file.FullName, TagLib.ReadStyle.None);
                    if (fileTags.Tag.AlbumArtists.Length == 0)
                    {
                        artistName = String.Join(" / ", fileTags.Tag.Performers);
                    }
                    else
                    {
                        artistName = String.Join(" / ", fileTags.Tag.AlbumArtists);
                    }
                    albumName = fileTags.Tag.Album;

                    embeddedArtIndex = EmbeddedArtHelpers.GetEmbeddedFrontCoverIndex(fileTags);
                }
                catch (Exception e)
                {
                    System.Diagnostics.Trace.WriteLine("TagLib# could not get artist and album information for file: " + file.FullName);
                    System.Diagnostics.Trace.Indent();
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    System.Diagnostics.Trace.Unindent();
                    return;                     //If this media file couldn't be read, just go on to the next one.
                }
                finally
                {
                    if (fileTags != null)
                    {
                        fileTags.Mode = TagLib.File.AccessMode.Closed;
                    }
                }
            }
            else
            {
                //Read from file path
                Match match = filePathPattern.Match(file.FullName);
                if (match.Success)
                {
                    artistName = match.Groups["artist"].Value;
                    albumName  = match.Groups["album"].Value;
                }
            }

            if (!(String.IsNullOrEmpty(artistName) && String.IsNullOrEmpty(albumName)))             //No point adding it if no artist or album could be found.
            {
                string basePath;
                if (file is FileInfo)
                {
                    basePath = ((FileInfo)file).DirectoryName;
                }
                else
                {
                    System.Diagnostics.Debug.Assert(file is DirectoryInfo, "Expecting file to be one of FileInfo or DirectoryInfo");
                    basePath = ((DirectoryInfo)file).FullName;
                }

                Album album = new Album(basePath, artistName, albumName);
                if (embeddedArtIndex.HasValue)
                {
                    //Read the picture from the data
                    album.SetArtFile(EmbeddedArtHelpers.GetEmbeddedFilePath(file.FullName, embeddedArtIndex.Value));
                }

                Dispatcher.Invoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                {
                    if (mAlbums.Add(album))
                    {
                        addedAlbums.Add(album);
                    }
                }));
            }
        }
Пример #10
0
        /// <summary>Reads the album and artist data from specified media file or folder, and adds it to the <see cref="mAlbums"/> collection.</summary>
        /// <param name="filePathPattern">Use null to use the ID3 tags instead</param>
        /// <returns>The <see cref="Album"/> that was added to <see cref="mAlbums"/>, or <c>null</c> if none could be read.</returns>
        private Album ReadMediaFile(FileSystemInfo file, Regex filePathPattern)
        {
            if (file is DirectoryInfo && filePathPattern == null) //If a DirectoryInfo is used, then the filePathPattern must have ended in \.
            {
                throw new ArgumentException("Directories are only supported for pattern matching, not ID3 tags", "file");
            }

            Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new ThreadStart(delegate
            {
                ProgressText = "Searching... " + file.Name;
            }));

            string artistName       = null;
            string albumName        = null;
            int?   embeddedArtIndex = null;

            //Read ID3 Tags
            TagLib.File fileTags = null;
            if (filePathPattern == null)
            {
                try
                {
                    fileTags = TagLib.File.Create(file.FullName, TagLib.ReadStyle.None);
                    if (fileTags.Tag.AlbumArtists.Length == 0)
                    {
                        artistName = String.Join(" / ", fileTags.Tag.Performers);
                    }
                    else
                    {
                        artistName = String.Join(" / ", fileTags.Tag.AlbumArtists);
                    }
                    albumName = fileTags.Tag.Album;

                    var embeddedPictures = fileTags.Tag.Pictures;
                    if (embeddedPictures.Length > 0)
                    {
                        //There's an embedded picture
                        //Check to see if there's a picture described as the front cover, to use in preference
                        for (int i = 0; i < embeddedPictures.Length; i++)
                        {
                            if (embeddedPictures[i].Type == TagLib.PictureType.FrontCover)
                            {
                                embeddedArtIndex = i;
                                break;
                            }
                        }
                        if (!embeddedArtIndex.HasValue)
                        {
                            //None of the embedded pictures were tagged as "FrontCover", so just use the first picture
                            embeddedArtIndex = 0;
                        }
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Trace.WriteLine("TagLib# could not get artist and album information for file: " + file.FullName);
                    System.Diagnostics.Trace.Indent();
                    System.Diagnostics.Trace.WriteLine(e.Message);
                    System.Diagnostics.Trace.Unindent();
                    return(null); //If this media file couldn't be read, just go on to the next one.
                }
                finally
                {
                    if (fileTags != null)
                    {
                        fileTags.Mode = TagLib.File.AccessMode.Closed;
                    }
                }
            }
            else
            {
                //Read from file path
                Match match = filePathPattern.Match(file.FullName);
                if (match.Success)
                {
                    artistName = match.Groups["artist"].Value;
                    albumName  = match.Groups["album"].Value;
                }
            }

            if (!(String.IsNullOrEmpty(artistName) && String.IsNullOrEmpty(albumName))) //No point adding it if no artist or album could be found.
            {
                string basePath;
                bool   addTracks = false;
                if (file is FileInfo)
                {
                    basePath  = ((FileInfo)file).DirectoryName;
                    addTracks = true;
                }
                else
                {
                    System.Diagnostics.Debug.Assert(file is DirectoryInfo, "Expecting file to be one of FileInfo or DirectoryInfo");
                    basePath = ((DirectoryInfo)file).FullName;
                }

                Album album = findInAlbums(basePath, artistName, albumName);

                if (addTracks)
                {
                    album.AddTrack(fileTags);
                }

                if (embeddedArtIndex.HasValue)
                {
                    //Read the picture from the data
                    album.SetArtFile(EmbeddedArtHelpers.GetEmbeddedFilePath(file.FullName, embeddedArtIndex.Value));
                }

                Dispatcher.Invoke(DispatcherPriority.DataBind, new ThreadStart(delegate
                {
                    mAlbums.Add(album);
                }));

                return(album);
            }

            return(null);
        }