////------------------------------------------------------------------------------------------------------------------------------ /// <inheritdoc/> public IAudioTagOffset ReadFromStream(Stream stream, TagOrigin tagOrigin) { if (stream == null) throw new ArgumentNullException("stream"); if (!stream.CanRead) throw new InvalidOperationException("stream can not be read"); if (!stream.CanSeek) throw new InvalidOperationException("stream can not be seeked"); StreamBuffer sb = stream as StreamBuffer ?? new StreamBuffer(stream); long startOffset = FindIdentifier(sb, tagOrigin); if (startOffset < 0) return null; Id3v1Tag tag = new Id3v1Tag(); string extendedTrackTitle = String.Empty; string extendedArtist = String.Empty; string extendAlbumTitle = String.Empty; if ((startOffset - Id3v1Tag.ExtendedSize) >= 0) { sb.Position = startOffset - Id3v1Tag.ExtendedSize; string extendedHeaderIdentifier = sb.ReadString(ExtendedHeaderIdentifierBytes.Length); if (String.Equals(extendedHeaderIdentifier, Id3v1Tag.ExtendedHeaderIdentifier, StringComparison.OrdinalIgnoreCase)) { startOffset = startOffset - ExtendedHeaderIdentifierBytes.Length; extendedTrackTitle = sb.ReadString(60, _encoding); extendedArtist = sb.ReadString(60, _encoding); extendAlbumTitle = sb.ReadString(60, _encoding); Id3v1TrackSpeed trackSpeed = (Id3v1TrackSpeed)sb.ReadByte(); tag.TrackSpeed = Id3v1Tag.IsValidTrackSpeed(trackSpeed) ? trackSpeed : Id3v1TrackSpeed.Unset; tag.ExtendedTrackGenre = sb.ReadString(30, _encoding); tag.StartTime = GetTimeSpan(sb.ReadString(6, _encoding)); tag.EndTime = GetTimeSpan(sb.ReadString(6, _encoding)); tag.UseExtendedTag = true; } else sb.Position = startOffset + HeaderIdentifierBytes.Length; } // Read the rest of the tag. tag.TrackTitle = sb.ReadString(30, _encoding) + extendedTrackTitle; tag.Artist = sb.ReadString(30, _encoding) + extendedArtist; tag.AlbumTitle = sb.ReadString(30, _encoding) + extendAlbumTitle; tag.AlbumYear = sb.ReadString(4); byte[] comment = new byte[30]; if ((sb.Read(comment, 30) == 30) && (comment[28] == '\0') && (comment[29] != '\0')) { tag.TrackNumber = comment[29]; tag.TrackComment = _encoding.GetString(comment, 0, 28); } else tag.TrackComment = _encoding.GetString(comment); Id3v1Genre genre = (Id3v1Genre)sb.ReadByte(); tag.Genre = Id3v1Tag.IsValidGenre(genre) ? genre : Id3v1Genre.Unknown; long endOffset = sb.Position; return new AudioTagOffset(tagOrigin, startOffset, endOffset, tag); }
/// <summary> /// Equals the specified <see cref="Id3v1Tag"/>. /// </summary> /// <param name="tag">The <see cref="Id3v1Tag"/>.</param> /// <returns>true if equal; false otherwise.</returns> public bool Equals(Id3v1Tag tag) { if (ReferenceEquals(null, tag)) return false; if (ReferenceEquals(this, tag)) return true; return (tag.Version == Version) && (tag.AlbumTitle == AlbumTitle) && (tag.AlbumYear == AlbumYear) && (tag.Artist == Artist) && (tag.TrackComment == TrackComment) && (tag.Genre == Genre) && (tag.TrackNumber == TrackNumber) && (tag.TrackTitle == TrackTitle) && (tag.UseExtendedTag == UseExtendedTag) && (tag.TrackSpeed == TrackSpeed) && (tag.ExtendedTrackGenre == ExtendedTrackGenre) && (tag.StartTime == StartTime) && (tag.EndTime == EndTime); }