Пример #1
0
 public void ReadID3v1(string file)
 {
     // read id3 stuff
     id3v1 = new ID3v1(file);
     id3v1.Read();
     this.hasID3v1 = id3v1.hasTag;;
 }
Пример #2
0
        public void LoadTags(string filename)
        {
            ID3v2 t2 = ID3v2.FromFile(filename);
            ID3v1 t1 = ID3v1.FromFile(filename);

            if (t2 != null)
            {
                Title          = t2.QuickInfo.Title;
                Artist         = t2.QuickInfo.Artist;
                Album          = t2.QuickInfo.Album;
                Year           = t2.QuickInfo.Year.ToString();
                LeadPerformers = t2.QuickInfo.LeadPerformers;
                Genre          = t2.QuickInfo.Genre.ToString();
                TrackNumber    = t2.QuickInfo.TrackNumber.ToString();
                Comments       = t2.QuickInfo.Comments;

                if (t2.QuickInfo.Image != null)
                {
                    if (Image != null)
                    {
                        (Image as BitmapImage).StreamSource.Dispose();
                        Image = null;
                    }

                    MemoryStream imgstream = new MemoryStream();
                    t2.QuickInfo.Image.Save(imgstream, System.Drawing.Imaging.ImageFormat.Png);
                    var img = new BitmapImage();
                    img.BeginInit();
                    imgstream.Seek(0, SeekOrigin.Begin);
                    img.StreamSource = imgstream;
                    img.EndInit();
                    Image = img;
                }
            }
            if (t1 != null)
            {
                if (String.IsNullOrWhiteSpace(Title))
                {
                    Title = t1.Title;
                }
                if (String.IsNullOrWhiteSpace(Artist))
                {
                    Artist = t1.Artist;
                }
                if (String.IsNullOrWhiteSpace(Album))
                {
                    Album = t1.Album;
                }
                if (String.IsNullOrWhiteSpace(Year))
                {
                    Year = t1.Year.ToString();
                }
                if (string.IsNullOrWhiteSpace(Comments))
                {
                    Comments = t1.Comment;
                }
                Genre = t1.Genre.ToString();
            }
        }
Пример #3
0
        public void CommentTest()
        {
            ID3v1  target   = new ID3v1(filePath, true);
            string expected = string.Empty;
            string actual   = target.Comment;

            Assert.AreEqual(expected, actual);
        }
Пример #4
0
        public void SaveTest()
        {
            string filePath = string.Empty;                  // TODO: Initialize to an appropriate value
            bool   LoadData = false;                         // TODO: Initialize to an appropriate value
            ID3v1  target   = new ID3v1(filePath, LoadData); // TODO: Initialize to an appropriate value

            target.Save();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
Пример #5
0
        /// <summary>
        /// append or overwrite ID3v1 tag at the end of the audio
        /// </summary>
        /// <param name="stream"></param>
        private void WriteID3v1(Stream stream)
        {
            ID3v1 v1tag = new ID3v1();

            v1tag.FrameModel = TagModel;

            stream.Seek(_audioStart + _audio.NumPayloadBytes, SeekOrigin.Begin);
            v1tag.WriteAtStreamPosition(stream);
        }
Пример #6
0
 /// <summary>
 /// Create new ID3 Info class
 /// </summary>
 /// <param name="FileAddress">FileAddress for read ID3 info</param>
 /// <param name="LoadData">Indicate load data in constructor or not</param>
 public ID3Info(string FilePath, bool LoadData)
 {
     _ID3v1 = new ID3v1(FilePath, LoadData);
     try
     {
         _ID3v2 = new ID3v2(FilePath, LoadData);
     }
     catch
     {
         // Falls oben was schiefging haben wir immerhin noch die Daten aus id3v1
     }
 }
Пример #7
0
 public ID3vDetails(string filename)
 {
     ImageMP3 = new ID3Info(filename, true);
     foreach (AttachedPictureFrame frame in ImageMP3.ID3v2Info.AttachedPictureFrames)
     {
         Image temp = frame.Picture;
         attach = temp;
     }
     MP3 = new ID3v1(filename, true);
     namemp3 = MP3.FileName;
     title = MP3.Title;
     artist = MP3.Artist;
     album = MP3.Album;
     year = MP3.Year;
 }
Пример #8
0
        public MpegAudio(String path)
        {
            const int dataLength = MaxMpegFrameLength * 2;

            ResetData();

            using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                int startPos = ID3v2.GetTagSize(br.BaseStream);

                // Get file length
                m_FileLength = br.BaseStream.Length;

                // Seek past ID3v2 tag
                br.BaseStream.Seek(startPos, SeekOrigin.Begin);

                // Read first block of data and search for a frame
                Byte[] data = br.ReadBytes(dataLength);
                FindFrame(data, ref m_VBR);
                m_VendorID = FindVendorID(data);

                // Try to search in the middle of the file if no frame at the beginning found
                if (!m_Frame.Found)
                {
                    br.BaseStream.Seek((m_FileLength - startPos) / 2, SeekOrigin.Begin);
                    data = br.ReadBytes(dataLength);
                    FindFrame(data, ref m_VBR);
                }

                // Search for vendor ID at the end if CBR encoded
                if (m_Frame.Found && String.IsNullOrEmpty(m_VendorID))
                {
                    br.BaseStream.Seek(-(data.Length + ID3v1.GetTagSize(br.BaseStream)), SeekOrigin.End);

                    data = br.ReadBytes(dataLength);
                    FindFrame(data, ref m_VBR);
                    m_VendorID = FindVendorID(data);
                }
            }

            if (m_Frame.Found == false)
            {
                ResetData();
            }
        }
Пример #9
0
        public MP3FileReader(Stream stream)
        {
            CSCore.Tags.ID3.ID3v2.SkipTag(stream);
            dataStartIndex = stream.Position;

            var id3v1Tag = ID3v1.FromStream(stream);

            if (id3v1Tag != null)
            {
                dataLength = stream.Length - dataStartIndex - 128; //128 = id3v1 length
            }
            else
            {
                dataLength = stream.Length - dataStartIndex;
            }

            stream.Position = dataStartIndex;

            dataStream = new MP3Stream(stream, true, id3v1Tag != null ? 128 : 0);
        }
Пример #10
0
        /// <summary>
        /// Creates a new MP3Reader for the specified stream.
        /// </summary>
        /// <param name="stream">The stream to load.</param>
        public MP3Reader(Stream stream)
        {
            Name = stream.ToString();
            long endOfStream = 0;

            if (stream.CanSeek && (stream.Position == 0) && (stream.Length > 128))
            {
                // try loading ID3v1 first
                try
                {
                    stream.Seek(-128, SeekOrigin.End);
                    var buffer = new byte[128];
                    stream.Read(buffer, 0, 128);
                    if ((buffer[0] == (byte)'T') && (buffer[1] == (byte)'A') && (buffer[2] == (byte)'G'))
                    {
                        m_ID3v1     = new ID3v1(buffer);
                        endOfStream = stream.Length - 128;
                    }
                }
                catch { }
                stream.Seek(0, SeekOrigin.Begin);
            }
            m_Reader = new DataFrameReader(stream, endOfStream);
        }
Пример #11
0
        private void AddSongs(string[] FileNames)
        {
            if (FileNames == null)
            {
                return;
            }
            if (FileNames.Length >= 100)
            {
                if (ShowMessageBoxOkCancel("您选择的歌曲数量超过100,这样可能会导致软件占用较多内存,确定要继续吗?\n(推荐您分次处理,每次处理的歌曲控制在100以内)") == 0)
                {
                    return;
                }
            }
            char[] CharToDelete = { '\0', ' ' };

            Image_Helper.Visibility = Visibility.Hidden;
            Label_URL.Visibility    = Visibility.Hidden;

            foreach (string FileName in FileNames)
            {
                if (System.IO.Path.GetExtension(FileName).ToUpper() != ".MP3")
                {
                    continue;
                }
                BitmapImage HasAlbum  = null;
                string      HasLyrics = null;


                string Title = "", Artist = "", Album = "";
                ID3v2  id3v2 = new ID3v2(FileName, true);
                if (id3v2.TextWithLanguageFrames.Count > 0)
                {
                    for (int i = 0; i < id3v2.TextWithLanguageFrames.Count; i++)
                    {
                        if (id3v2.TextWithLanguageFrames.Items[i].FrameID == "USLT")
                        {
                            HasLyrics = id3v2.TextWithLanguageFrames.Items[i].Text.Trim();
                            break;
                        }
                    }
                }
                if (id3v2.AttachedPictureFrames.Count > 0)
                {
                    for (int i = 0; i < id3v2.AttachedPictureFrames.Count; i++)
                    {
                        if (id3v2.AttachedPictureFrames.Items[i].FrameID == "APIC")
                        {
                            HasAlbum = new BitmapImage();
                            HasAlbum.BeginInit();
                            HasAlbum.StreamSource = id3v2.AttachedPictureFrames.Items[0].Data;
                            try
                            {
                                HasAlbum.EndInit();
                            }
                            catch
                            {
                                HasAlbum = null;
                            }
                            break;
                        }
                    }
                }
                if (id3v2.TextFrames.Count > 0)
                {
                    for (int i = 0; i < id3v2.TextFrames.Count; i++)
                    {
                        if (id3v2.TextFrames.Items[i].FrameID == "TIT2")
                        {
                            Title = id3v2.TextFrames.Items[i].Text;
                        }
                        if (id3v2.TextFrames.Items[i].FrameID == "TPE1")
                        {
                            Artist = id3v2.TextFrames.Items[i].Text;
                        }
                        if (id3v2.TextFrames.Items[i].FrameID == "TALB")
                        {
                            Album = id3v2.TextFrames.Items[i].Text;
                        }
                    }
                }


                ID3v1 id3v1 = new ID3v1(FileName, true);

                Title  = IsStringNullOrEmpry(Title) ? id3v1.Title : Title;
                Artist = IsStringNullOrEmpry(Artist) ? id3v1.Artist : Artist;
                Album  = IsStringNullOrEmpry(Album) ? id3v1.Album : Album;

                if (IsStringNullOrEmpry(Title))
                {
                    Title = "";
                }
                if (IsStringNullOrEmpry(Artist))
                {
                    Artist = "";
                }
                if (IsStringNullOrEmpry(Album))
                {
                    Album = "";
                }

                SongList.Add(new Song(FileName, Title.TrimEnd(CharToDelete), Artist.TrimEnd(CharToDelete), Album.TrimEnd(CharToDelete), HasAlbum, HasLyrics));



                System.Windows.Forms.Application.DoEvents();

                //这个地方加多线程实在是不好加 因为有一个OpenFileDialog 而且结果是一个string[] 直接用object传到多线程里面会出问题
                //其实DoEvents的效果也挺好的 就用这个代替了!
            }
        }
Пример #12
0
 public ID3Wrapper(ID3v1 id3v1Tag, ID3v2 id3v2Tag)
 {
     this.id3v1Tag = id3v1Tag;
     this.id3v2Tag = id3v2Tag;
 }
Пример #13
0
        public void ID3v1ConstructorTest()
        {
            ID3v1 target = new ID3v1(filePath, false);

            Assert.IsNotNull(target);
        }
Пример #14
0
        public async Task RetagFileAsync(string mp3FilePath)
        {
            VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"File: \"{mp3FilePath}\""));

            using (var stream = new FileStream(mp3FilePath, FileMode.Open, _options.DryRunMode ? FileAccess.Read : FileAccess.ReadWrite))
            {
                TagHandler tag1      = null;
                TagHandler tag2      = null;
                ID3v1      tagModel1 = null;

                try
                {
                    // Read ID3v1 tags...
                    stream.Seek(0, SeekOrigin.Begin);
                    tagModel1 = new ID3v1();
                    tagModel1.Deserialize(stream);

                    tag1 = new TagHandler(tagModel1.FrameModel);
                }
                catch (Exception ex)
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(3, () => $"    Could not read ID3v1 tags: {ex.ToString()}", isError: true));
                }

                try
                {
                    // Read ID3v2 tags...
                    stream.Seek(0, SeekOrigin.Begin);
                    var tagModel2 = TagManager.Deserialize(stream);

                    tag2 = new TagHandler(tagModel2);
                }
                catch (Exception ex)
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(3, () => $"    Could not read ID3v2 tags: {ex.ToString()}", isError: true));
                }

                if (tag1 == null && tag2 == null)
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    No ID3 tags found. No changes.", isError: true));
                    return;
                }

                if (string.IsNullOrWhiteSpace(tag1?.Year) && tag2 != null)
                {
                    tag1 = null;                     // prefer storing the year in v2 by checking v1 first
                }
                if (string.IsNullOrWhiteSpace(tag2?.Year) && tag1 != null)
                {
                    tag2 = null;                     // The year is stored in the v1 tag only
                }
                string artist = (tag2?.Artist ?? tag1?.Artist).Trim(new char[] { ' ', '\n', '\0' }).Trim();
                string title  = (tag2?.Title ?? tag1?.Title).Trim(new char[] { ' ', '\n', '\0' }).Trim();
                string year   = (tag2?.Year ?? tag1?.Year).Trim(new char[] { ' ', '\n', '\0' }).Trim();

                if (tag1 != null && tag2 != null && tag1.Year != tag2.Year)
                {
                    year = $"{tag1.Year} & {tag2.Year}";
                }

                if (string.IsNullOrWhiteSpace(artist) || string.IsNullOrWhiteSpace(title))
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    Title and/or artist tags are missing or contain empty values. No changes.", isError: true));
                    return;
                }

                VerboseOutput?.Invoke(this, new VerboseInfo(1, () => $"    Found MP3 Tags: \"{artist}\" \"{title}\" ({year})"));
                var oldestReleaseDate = await GetOldestReleaseDateAsync(artist, title);

                if (oldestReleaseDate == null)
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    Oldest release date could not be determined. Online lookup failed. No changes.", isError: true));
                    return;
                }

                if (year == oldestReleaseDate.Value.Year.ToString())
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    Year is already correct. No changes."));
                    return;
                }

                if (_options.DryRunMode)
                {
                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    DRY RUN MODE: Year WOULD HAVE BEEN updated to ({oldestReleaseDate.Value.Year})."));
                }
                else
                {
                    // Update the year with the new looked up year
                    if (tag1 != null)
                    {
                        tag1.Year = oldestReleaseDate.Value.Year.ToString();

                        tagModel1.FrameModel = tag1.FrameModel;
                        tagModel1.Serialize(stream);
                    }

                    if (tag2 != null)
                    {
                        tag2.Year = oldestReleaseDate.Value.Year.ToString();

                        TagManager.Serialize(tag2.FrameModel, stream);
                    }

                    VerboseOutput?.Invoke(this, new VerboseInfo(0, () => $"    Year updated to ({oldestReleaseDate.Value.Year})."));
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Parse ID3 tags from stream and calculate where the audio must be
        /// </summary>
        /// <remarks>
        /// if this throws an exception, the File is not usable.
        /// </remarks>
        private void Initialise()
        {
            // create an empty framemodel, to use if we don't parse anything better
            FrameModel tagModel = new FrameModel();

            // clear out any previous taghandler
            _tagHandler = null;

            // don't know how big the audio is until we've parsed the tags
            _audio = null;
            UInt32 audioNumBytes;

            using (FileStream sourceStream = _sourceFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // all the header calculations use UInt32;
                // this guarantees all the file offsets we have to deal with fit in a UInt32
                if (sourceStream.Length > UInt32.MaxValue)
                {
                    throw new InvalidAudioFrameException("MP3 file can't be bigger than 4gb");
                }

                // in the absence of any recognised tags,
                // audio starts at the start
                _audioStart = 0;
                // audio is entire file length
                audioNumBytes = (UInt32)sourceStream.Length;

                // try to read an ID3v1 block.
                // If ID3v2 block exists, its values overwrite these
                // Otherwise, if ID3V1 block exists, its values are used
                // The audio is anything that's left after all the tags are excluded.
                try
                {
                    ID3v1 id3v1 = new ID3v1();
                    id3v1.Deserialize(sourceStream);

                    // fill in ID3v2 block from the ID3v1 data
                    tagModel = id3v1.FrameModel;

                    // audio is shorter by the length of the id3v1 tag
                    audioNumBytes -= ID3v1.TagLength;
                }
                catch (TagNotFoundException)
                {
                    // ignore "no ID3v1 block"
                    // everything else isn't caught here, and throws out to the caller
                }

                try
                {
                    sourceStream.Seek(0, SeekOrigin.Begin);
                    tagModel = FrameManager.Deserialize(sourceStream);

                    // audio starts after the tag
                    _audioStart = (uint)sourceStream.Position;
                    // audio is shorter by the length of the id3v2 tag
                    audioNumBytes -= _audioStart;
                }
                catch (TagNotFoundException)
                {
                    // ignore "no ID3v2 block"
                    // everything else isn't caught here, and throws out to the caller
                }

                // create a taghandler to hold the tagmodel we've parsed, if any
                _tagHandler = new TagHandler(tagModel);
            } // closes sourceStream

            // save the location of the audio in the original file
            // passing in audio size and id3 length tag (if any) to help with bitrate calculations
            _audio         = new AudioFile(_sourceFileInfo, _audioStart, audioNumBytes, _tagHandler.Length);
            _audioReplaced = false;
        }
Пример #16
0
 public virtual void SetId3v1Tag(ID3v1 id3v1Tag)
 {
     this.id3v1Tag = id3v1Tag;
 }
Пример #17
0
        public void FilePathTest()
        {
            ID3v1 target = new ID3v1(filePath, false);

            Assert.AreEqual(filePath, target.FilePath);
        }
Пример #18
0
 public virtual void RemoveId3v1Tag()
 {
     this.id3v1Tag = null;
 }
Пример #19
0
        public void HaveTagTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual(true, target.HaveTag);
        }
Пример #20
0
        public void TitleTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual("Perfumed Planet", target.Title);
        }
Пример #21
0
        public void TrackNumberTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual(1, target.TrackNumber);
        }
Пример #22
0
        public void YearTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual(string.Empty, target.Year);
        }
Пример #23
0
 /// <exception cref="System.IO.IOException"></exception>
 private void InitId3v1Tag(RandomAccessFile file)
 {
     byte[] bytes = new byte[ID3v1Tag.TAG_LENGTH];
     file.Seek(GetLength() - ID3v1Tag.TAG_LENGTH);
     int bytesRead = file.Read(bytes, 0, ID3v1Tag.TAG_LENGTH);
     if (bytesRead < ID3v1Tag.TAG_LENGTH)
     {
         throw new IOException("Not enough bytes read");
     }
     try
     {
         id3v1Tag = new ID3v1Tag(bytes);
     }
     catch (NoSuchTagException)
     {
         id3v1Tag = null;
     }
 }
Пример #24
0
 /// <summary>
 /// Create new ID3 Info class
 /// </summary>
 /// <param name="FileAddress">FileAddress for read ID3 info</param>
 /// <param name="LoadData">Indicate load data in constructor or not</param>
 public ID3Info(string FilePath, bool LoadData)
 {
     _ID3v1 = new ID3v1(FilePath, LoadData);
     _ID3v2 = new ID3v2(FilePath, LoadData);
     file   = TagLib.File.Create(FilePath); // InvariantStartPosition
 }
Пример #25
0
        public void ArtistTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual("Andre Norton", target.Artist);
        }
Пример #26
0
 /// <summary>
 /// Create new ID3 Info class
 /// </summary>
 /// <param name="FileAddress">FileAddress for read ID3 info</param>
 /// <param name="LoadData">Indicate load data in constructor or not</param>
 public ID3Info(string FilePath, bool LoadData)
 {
     _ID3v1 = new ID3v1(FilePath, LoadData);
     _ID3v2 = new ID3v2(FilePath, LoadData);
 }
Пример #27
0
        public void AlbumTest()
        {
            ID3v1 target = new ID3v1(filePath, true);

            Assert.AreEqual("Plague Ship", target.Album);
        }
Пример #28
0
        public void GenreTest()
        {
            ID3v1 target = new ID3v1(filePath, false);

            Assert.AreEqual(Genre.Blues, target.Genre);
        }
Пример #29
0
        /// <summary>
        /// Gets the next frame.
        /// </summary>
        /// <returns>Returns the next frame or null (at end of stream).</returns>
        public AudioFrame GetNextFrame()
        {
            while (true)
            {
                #region return buffered frames first (if any)
                // got a decoded frame at the cache ?
                if (m_BufferedFrame != null)
                {
                    AudioFrame result;
                    if (m_InvalidFrame != null)
                    {
                        result         = m_InvalidFrame;
                        m_InvalidFrame = null;
                    }
                    else
                    {
                        result          = m_BufferedFrame;
                        m_BufferedFrame = null;
                    }
                    return(result);
                }
                #endregion

                #region search next frame start

                // search the next interesting position
                var searchResult = FindFrame();
                if (searchResult == null)
                {
                    #region end of stream cleanup
                    // invalid data at end of stream ?
                    if (m_Reader.Available > 0)
                    {
                        // yes buffer
                        InvalidData(m_Reader.GetBuffer());
                    }

                    // got an invalid frame ?
                    if (m_InvalidFrame != null)
                    {
                        // return invalid frame
                        AudioFrame result = m_InvalidFrame;
                        m_InvalidFrame = null;
                        return(result);
                    }

                    // got an id3v1 ?
                    if (m_ID3v1 != null)
                    {
                        // return id3v1
                        AudioFrame result = m_ID3v1;
                        m_ID3v1 = null;
                        return(result);
                    }

                    // everything done, return null
                    return(null);

                    #endregion
                }
                #endregion

                #region check search result

                // got garbage at the beginning?
                if (searchResult.Index > 0)
                {
                    // yes, invalid data
                    InvalidData(m_Reader.GetBuffer(searchResult.Index));
                    continue;
                }
                #endregion

                #region decode frame

                // try to decode frame
                try
                {
                    var        valid = false;
                    AudioFrame frame = null;
                    switch (searchResult.Match)
                    {
                        #region decode mp3 frame
                    case MatchType.MP3Frame:
                        var audioFrame = new MP3AudioFrame();
                        valid = audioFrame.Parse(m_Reader);
                        frame = audioFrame;
                        break;
                        #endregion

                        #region decode id3 frame
                    case MatchType.ID3Frame:
                        frame = new ID3v2();
                        valid = frame.Parse(m_Reader);
                        break;
                        #endregion

                    default: throw new NotImplementedException(string.Format("Unknown frame type {0}", searchResult.Match));
                    }

                    // parsed successfully?
                    if (valid)
                    {
                        // yes, cache frame
                        m_BufferedFrame = frame;
                    }
                    else
                    {
                        // no invalidate
                        InvalidData(m_Reader.GetBuffer(1));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(string.Format("Error while decoding {0} in stream {1}", searchResult.Match, m_Reader));
                    Trace.TraceError(ex.ToString());

                    // invalid frame or decoder error, move ahead
                    var count = (searchResult.Index < 0) ? 1 : searchResult.Index + 1;
                    InvalidData(m_Reader.GetBuffer(count));
                }
                #endregion
            }
        }