Exemplo n.º 1
0
 private Index lastTrackIndex(Track track)
 {
   return track.Indices[track.Indices.Length - 1];
 }
Exemplo n.º 2
0
        /// <summary>
        /// Read MusicTag information from cueFakeTrack
        /// Not thread safe!
        /// </summary>
        /// <param name="cueFakeTrackFileName">Cue fake track file name</param>
        /// <returns>MusicTag filled with cue track information</returns>
        public static MusicTag CueFakeTrackFile2MusicTag(string cueFakeTrackFileName)
        {
            lock (cacheLock)
            {
                // This metod called twice for each one file. So, cache data!
                if (cueFakeTrackFileName == cueFakeTrackFileNameCache)
                {
                    return(musicTagCache);
                }
                cueFakeTrackFileNameCache = cueFakeTrackFileName;

                // Cache CueSheet to pervent parsing it for each track in the album
                CueFakeTrack cueFakeTrack = parseCueFakeTrackFileName(cueFakeTrackFileName);
                if (cueSheetCacheFileNameCache != cueFakeTrack.CueFileName)
                {
                    cueSheetCache = new CueSheet(cueFakeTrack.CueFileName);
                    cueSheetCacheFileNameCache = cueFakeTrack.CueFileName;
                }

                int   trackPosition = cueFakeTrack.TrackNumber - cueSheetCache.Tracks[0].TrackNumber;
                Track track         = cueSheetCache.Tracks[trackPosition];

                musicTagCache = new MusicTag();
                if (track.TrackNumber < cueSheetCache.Tracks[cueSheetCache.Tracks.Length - 1].TrackNumber)
                {
                    Track nextTrack = cueSheetCache.Tracks[trackPosition + 1];
                    musicTagCache.Duration = cueIndexToIntTime(nextTrack.Indices[0]) - cueIndexToIntTime(track.Indices[0]);
                }

                string fname = Path.Combine(Path.GetDirectoryName(cueFakeTrack.CueFileName), track.DataFile.Filename);

                try
                {
                    if (fname != cacheFName)
                    {
                        tagCache = TagLib.File.Create(fname);
                    }
                    cacheFName = fname;

                    musicTagCache.FileType  = tagCache.MimeType;
                    musicTagCache.Year      = (int)tagCache.Tag.Year;
                    musicTagCache.BitRate   = tagCache.Properties.AudioBitrate;
                    musicTagCache.DiscID    = (int)tagCache.Tag.Disc;
                    musicTagCache.DiscTotal = (int)tagCache.Tag.DiscCount;
                    ;

                    if (musicTagCache.Duration == 0)
                    {
                        musicTagCache.Duration = (int)tagCache.Properties.Duration.TotalSeconds -
                                                 cueIndexToIntTime(track.Indices[0]);
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn("CueFakeTrackFile2MusicTag: Exception reading file {0}. {1}", fname, ex.Message);
                }

                // In case of having a multi file Cue sheet, we're not able to get the duration
                // from the index entries. use MediaInfo then
                if (musicTagCache.Duration == 0)
                {
                    try
                    {
                        MediaInfo mi = new MediaInfo();
                        mi.Open(fname);
                        int durationms = 0;
                        int.TryParse(mi.Get(StreamKind.General, 0, "Duration"), out durationms);
                        musicTagCache.Duration = durationms / 1000;
                        mi.Close();
                    }
                    catch (Exception ex1)
                    {
                        Log.Warn("CueFakeTrackFile2MusicTag: Exception retrieving duration for file {0}. {1}", fname, ex1.Message);
                    }
                }

                if (string.IsNullOrEmpty(musicTagCache.Artist))
                {
                    // if track has a performer set use this value for artist tag
                    // else use global performer defined for cue sheet
                    if (!string.IsNullOrEmpty(track.Performer))
                    {
                        musicTagCache.Artist = track.Performer;
                    }
                    else
                    {
                        musicTagCache.Artist = cueSheetCache.Performer;
                    }
                }

                if (string.IsNullOrEmpty(musicTagCache.Album))
                {
                    musicTagCache.Album = cueSheetCache.Title;
                }

                if (string.IsNullOrEmpty(musicTagCache.AlbumArtist))
                {
                    if (!string.IsNullOrEmpty(cueSheetCache.Performer))
                    {
                        musicTagCache.AlbumArtist    = cueSheetCache.Performer;
                        musicTagCache.HasAlbumArtist = true;
                    }
                    else
                    {
                        musicTagCache.HasAlbumArtist = false;
                    }
                }

                // let tagged genre override cuesheet genre
                if (string.IsNullOrEmpty(musicTagCache.Genre) &&
                    !string.IsNullOrEmpty(cueSheetCache.Genre))
                {
                    musicTagCache.Genre = cueSheetCache.Genre;
                }

                // let tagged year override cuesheet year
                if (musicTagCache.Year == 0 && cueSheetCache.Year != 0)
                {
                    musicTagCache.Year = cueSheetCache.Year;
                }

                // let tagged composer override cuesheet songwriter
                if (string.IsNullOrEmpty(musicTagCache.Composer) &&
                    !string.IsNullOrEmpty(cueSheetCache.Songwriter))
                {
                    musicTagCache.Composer = cueSheetCache.Songwriter;
                }


                //musicTagCache.CoverArtImageBytes = pics[0].Data.Data;
                musicTagCache.FileName   = cueFakeTrackFileName;
                musicTagCache.Title      = track.Title;
                musicTagCache.Track      = track.TrackNumber;
                musicTagCache.TrackTotal = cueSheetCache.Tracks.Length;

                return(musicTagCache);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Add a track to the current cuesheet
 /// </summary>
 /// <param name="track">Track object to add to the cuesheet.</param>
 public void AddTrack(Track track)
 {
   m_Tracks = (Track[])ResizeArray(m_Tracks, m_Tracks.Length + 1);
   m_Tracks[m_Tracks.Length - 1] = track;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Read MusicTag information from cueFakeTrack
        /// Not thread safe!
        /// </summary>
        /// <param name="cueFakeTrackFileName">Cue fake track file name</param>
        /// <returns>MusicTag filled with cue track information</returns>
        public static MusicTag CueFakeTrackFile2MusicTag(string cueFakeTrackFileName)
        {
            lock (cacheLock)
            {
                // This metod called twice for each single file. So, cache data!
                if (cueFakeTrackFileName == cueFakeTrackFileNameCache)
                {
                    return(musicTagCache);
                }
                cueFakeTrackFileNameCache = cueFakeTrackFileName;

                // Cache CueSheet to pervent parsing it for each track in the album
                CueFakeTrack cueFakeTrack = parseCueFakeTrackFileName(cueFakeTrackFileName);
                if (cueSheetCacheFileNameCache != cueFakeTrack.CueFileName)
                {
                    cueSheetCache = new CueSheet(cueFakeTrack.CueFileName);
                    cueSheetCacheFileNameCache = cueFakeTrack.CueFileName;
                }

                int   trackPosition = cueFakeTrack.TrackNumber - cueSheetCache.Tracks[0].TrackNumber;
                Track track         = cueSheetCache.Tracks[trackPosition];

                musicTagCache = new MusicTag();
                if (track.TrackNumber < cueSheetCache.Tracks[cueSheetCache.Tracks.Length - 1].TrackNumber)
                {
                    Track nextTrack = cueSheetCache.Tracks[trackPosition + 1];
                    musicTagCache.Duration = cueIndexToIntTime(nextTrack.Indices[0]) - cueIndexToIntTime(track.Indices[0]);
                }

                string fname = Path.Combine(Path.GetDirectoryName(cueFakeTrack.CueFileName), track.DataFile.Filename);

                try
                {
                    if (fname != cacheFName)
                    {
                        TagLib.File file = TagLib.File.Create(fname);
                        tagCache = new TagCache();
                        tagCache.CopyTags(file);
                    }
                    cacheFName = fname;

                    musicTagCache.FileType    = tagCache.FileType;
                    musicTagCache.Codec       = tagCache.Codec;
                    musicTagCache.Year        = tagCache.Year;
                    musicTagCache.BitRate     = tagCache.BitRate;
                    musicTagCache.DiscID      = tagCache.DiscId;
                    musicTagCache.DiscTotal   = tagCache.DiscTotal;
                    musicTagCache.Channels    = tagCache.Channels;
                    musicTagCache.SampleRate  = tagCache.SampleRate;
                    musicTagCache.BitRateMode = tagCache.BitRateMode;

                    if (musicTagCache.Duration == 0)
                    {
                        musicTagCache.Duration = tagCache.Duration - cueIndexToIntTime(track.Indices[0]);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("CueUtil:CueFakeTrackFile2MusicTag {0}", ex.Message);
                    // If we end up here this means that we were not able to read the file
                    // Most probably because of taglib-sharp not supporting the audio file
                    // For example DTS file format has no Tags, but can be replayed by BASS
                    // Use MediaInfo to read the properties
                    if (fname != cacheFName)
                    {
                        tagCache = new TagCache();
                        if (tagCache.CopyMediaInfo(fname))
                        {
                            musicTagCache.FileType    = tagCache.FileType;
                            musicTagCache.Codec       = tagCache.Codec;
                            musicTagCache.BitRate     = tagCache.BitRate;
                            musicTagCache.Channels    = tagCache.Channels;
                            musicTagCache.SampleRate  = tagCache.SampleRate;
                            musicTagCache.BitRateMode = tagCache.BitRateMode;

                            if (musicTagCache.Duration == 0)
                            {
                                musicTagCache.Duration = tagCache.Duration - cueIndexToIntTime(track.Indices[0]);
                            }
                        }
                    }
                    cacheFName = fname;
                }

                // In case of having a multi file Cue sheet, we're not able to get the duration
                // from the index entries. use MediaInfo then
                if (musicTagCache.Duration == 0)
                {
                    try
                    {
                        var logger = GlobalServiceProvider.Get <MediaInfo.ILogger>();
                        var mi     = new MediaInfoWrapper(fname, logger);
                        if (!mi.MediaInfoNotloaded)
                        {
                            mi.WriteInfo();
                            musicTagCache.Duration = (int?)mi.BestAudioStream?.Duration.TotalSeconds ?? 0;
                        }
                    }
                    catch (Exception ex1)
                    {
                        Log.Warn("CueFakeTrackFile2MusicTag: Exception retrieving duration for file {0}. {1}", fname, ex1.Message);
                    }
                }

                if (string.IsNullOrEmpty(musicTagCache.Artist))
                {
                    // if track has a performer set use this value for artist tag
                    // else use global performer defined for cue sheet
                    if (!string.IsNullOrEmpty(track.Performer))
                    {
                        musicTagCache.Artist = track.Performer;
                    }
                    else
                    {
                        musicTagCache.Artist = cueSheetCache.Performer;
                    }
                }

                if (string.IsNullOrEmpty(musicTagCache.Album))
                {
                    musicTagCache.Album = cueSheetCache.Title;
                }

                if (string.IsNullOrEmpty(musicTagCache.AlbumArtist))
                {
                    if (!string.IsNullOrEmpty(cueSheetCache.Performer))
                    {
                        musicTagCache.AlbumArtist    = cueSheetCache.Performer;
                        musicTagCache.HasAlbumArtist = true;
                    }
                    else
                    {
                        musicTagCache.HasAlbumArtist = false;
                    }
                }

                // let tagged genre override cuesheet genre
                if (string.IsNullOrEmpty(musicTagCache.Genre) &&
                    !string.IsNullOrEmpty(cueSheetCache.Genre))
                {
                    musicTagCache.Genre = cueSheetCache.Genre;
                }

                // let tagged year override cuesheet year
                if (musicTagCache.Year == 0 && cueSheetCache.Year != 0)
                {
                    musicTagCache.Year = cueSheetCache.Year;
                }

                // let tagged composer override cuesheet songwriter
                if (string.IsNullOrEmpty(musicTagCache.Composer) &&
                    !string.IsNullOrEmpty(cueSheetCache.Songwriter))
                {
                    musicTagCache.Composer = cueSheetCache.Songwriter;
                }

                // in case we were not able to read the file type via taglib, we will get it vai extension
                if (string.IsNullOrEmpty(musicTagCache.FileType))
                {
                    var extension = Path.GetExtension(fname);
                    if (extension != null)
                    {
                        musicTagCache.FileType = extension.Substring(1).ToLowerInvariant();
                    }
                }

                musicTagCache.FileName   = cueFakeTrackFileName;
                musicTagCache.Title      = track.Title;
                musicTagCache.Track      = track.TrackNumber;
                musicTagCache.TrackTotal = cueSheetCache.Tracks.Length;

                return(musicTagCache);
            }
        }