From 8a45f31cd0769bcf69fe02fabb6fa3de7b6a94d1 Mon Sep 17 00:00:00 2001 From: David Warner Date: Thu, 4 Apr 2024 14:49:23 +1100 Subject: [PATCH 01/14] Fix typo AttachementFrame -> AttachmentFrame --- .../Id3v2/Frames/AttachmentFrame.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/TaglibSharp/Id3v2/Frames/AttachmentFrame.cs b/src/TaglibSharp/Id3v2/Frames/AttachmentFrame.cs index 7bd1cd3ab..31c049751 100644 --- a/src/TaglibSharp/Id3v2/Frames/AttachmentFrame.cs +++ b/src/TaglibSharp/Id3v2/Frames/AttachmentFrame.cs @@ -965,7 +965,7 @@ public override Frame Clone () /// generic way or getting and setting pictures which is preferable /// to format specific code. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public class AttachedPictureFrame : AttachmentFrame { #region Constructors @@ -974,7 +974,7 @@ public class AttachedPictureFrame : AttachmentFrame /// cref="AttachmentFrame" /> with no contents and the /// default values. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public AttachedPictureFrame () { } @@ -1025,7 +1025,7 @@ public AttachedPictureFrame () /// } /// /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public AttachedPictureFrame (IPicture picture) : base (picture) { @@ -1046,7 +1046,7 @@ public AttachedPictureFrame (IPicture picture) /// A indicating the ID3v2 version the /// raw frame is encoded in. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public AttachedPictureFrame (ByteVector data, byte version) : base (data, version) { @@ -1073,7 +1073,7 @@ public AttachedPictureFrame (ByteVector data, byte version) /// A indicating the ID3v2 version the /// raw frame is encoded in. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] protected internal AttachedPictureFrame (ByteVector data, int offset, FrameHeader header, byte version) : base (data, offset, header, version) { @@ -1092,7 +1092,7 @@ protected internal AttachedPictureFrame (ByteVector data, int offset, FrameHeade /// used for storing files and other objects relevant to the file but /// not supported by other frames. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public class GeneralEncapsulatedObjectFrame : AttachmentFrame { @@ -1103,7 +1103,7 @@ public class GeneralEncapsulatedObjectFrame : AttachmentFrame /// cref="GeneralEncapsulatedObjectFrame" /> with no /// contents. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public GeneralEncapsulatedObjectFrame () { Type = PictureType.NotAPicture; @@ -1122,7 +1122,7 @@ public GeneralEncapsulatedObjectFrame () /// A indicating the ID3v2 version the /// raw frame is encoded in. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public GeneralEncapsulatedObjectFrame (ByteVector data, byte version) : base (data, version) { @@ -1151,7 +1151,7 @@ public GeneralEncapsulatedObjectFrame (ByteVector data, byte version) /// A indicating the ID3v2 version the /// raw frame is encoded in. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] protected internal GeneralEncapsulatedObjectFrame (ByteVector data, int offset, FrameHeader header, byte version) : base (data, offset, header, version) { @@ -1172,7 +1172,7 @@ protected internal GeneralEncapsulatedObjectFrame (ByteVector data, int offset, /// A containing the file name of the /// object stored in the current instance. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public string FileName { get { if (Filename != null) @@ -1191,7 +1191,7 @@ public string FileName { /// A containing the object data /// stored in the current instance. /// - [Obsolete ("Use AttachementFrame instead")] + [Obsolete ("Use AttachmentFrame instead")] public ByteVector Object { get { return Data ?? new ByteVector (); } set { Data = value; } From b2b21107ba078f66d827571ce64541f5db000b10 Mon Sep 17 00:00:00 2001 From: William Brockhus Date: Mon, 2 Oct 2023 11:00:11 +1100 Subject: [PATCH 02/14] feat(id3): support apple MVNM/MVIN frame --- .../TaggingFormats/Id3V2Test.cs | 48 +++++++++++++++++++ src/TaglibSharp/Id3v2/FrameFactory.cs | 5 +- src/TaglibSharp/Id3v2/FrameHeader.cs | 6 ++- src/TaglibSharp/Id3v2/FrameTypes.cs | 2 + .../Id3v2/Frames/TextIdentificationFrame.cs | 4 +- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs index 8b2ea676c..095da3399 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs @@ -1499,6 +1499,54 @@ public void TestUserTextInformationFrame () }); } + [Test] + public void TestMovementNameFrame () + { + ByteVector id = "MVNM"; + var frame = new TextInformationFrame (id) { + Text = val_mult + }; + + FrameTest (frame, 2, + delegate (Frame f, StringType e) { + (f as TextInformationFrame).TextEncoding = e; + }, + (d, v) => new TextInformationFrame (d, v), + + delegate (Frame f, string m) { + var g = (f as TextInformationFrame); + Assert.AreEqual (id, g.FrameId, m); + Assert.AreEqual (val_mult.Length, g.Text.Length, m); + for (int i = 0; i < val_mult.Length; i++) { + Assert.AreEqual (val_mult[i], g.Text[i], m); + } + }); + } + + [Test] + public void TestMovementNumberFrame () + { + ByteVector id = "MVIN"; + var frame = new TextInformationFrame (id) { + Text = val_mult + }; + + FrameTest (frame, 2, + delegate (Frame f, StringType e) { + (f as TextInformationFrame).TextEncoding = e; + }, + (d, v) => new TextInformationFrame (d, v), + + delegate (Frame f, string m) { + var g = (f as TextInformationFrame); + Assert.AreEqual (id, g.FrameId, m); + Assert.AreEqual (val_mult.Length, g.Text.Length, m); + for (int i = 0; i < val_mult.Length; i++) { + Assert.AreEqual (val_mult[i], g.Text[i], m); + } + }); + } + [Test] public void TestUniqueFileIdentifierFrame () { diff --git a/src/TaglibSharp/Id3v2/FrameFactory.cs b/src/TaglibSharp/Id3v2/FrameFactory.cs index 9a1b9c5c6..3754539f4 100644 --- a/src/TaglibSharp/Id3v2/FrameFactory.cs +++ b/src/TaglibSharp/Id3v2/FrameFactory.cs @@ -216,7 +216,10 @@ public static Frame CreateFrame (ByteVector data, File file, ref int offset, byt if (header.FrameId == FrameType.TXXX) return new UserTextInformationFrame (data, position, header, version); - if (header.FrameId[0] == (byte)'T') + // Apple proprietary MVNM (Movement Name), MVIN (Movement Number) are in fact text frames. + if (header.FrameId[0] == (byte)'T' || + header.FrameId == "MVNM" || + header.FrameId == "MVIN") return new TextInformationFrame (data, position, header, version); // Involved People List (frames 4.4 in 2.3. in 2.4 this is a TIPL frame) diff --git a/src/TaglibSharp/Id3v2/FrameHeader.cs b/src/TaglibSharp/Id3v2/FrameHeader.cs index 877947f14..783818d96 100644 --- a/src/TaglibSharp/Id3v2/FrameHeader.cs +++ b/src/TaglibSharp/Id3v2/FrameHeader.cs @@ -381,7 +381,7 @@ static ReadOnlyByteVector ConvertId (ByteVector id, byte version, bool toVersion } static readonly ReadOnlyByteVector[,] version2_frames = - new ReadOnlyByteVector[59, 2] { + new ReadOnlyByteVector[61, 2] { { "BUF", "RBUF" }, { "CNT", "PCNT" }, { "COM", "COMM" }, @@ -440,7 +440,9 @@ static ReadOnlyByteVector ConvertId (ByteVector id, byte version, bool toVersion { "WCP", "WCOP" }, { "WPB", "WPUB" }, { "WXX", "WXXX" }, - { "XRV", "RVA2" } + { "XRV", "RVA2" }, + { "MVN", "MVNM" }, + { "MVI", "MVIN" } }; static readonly ReadOnlyByteVector[,] version3_frames = diff --git a/src/TaglibSharp/Id3v2/FrameTypes.cs b/src/TaglibSharp/Id3v2/FrameTypes.cs index 2fda85de8..e430af85a 100644 --- a/src/TaglibSharp/Id3v2/FrameTypes.cs +++ b/src/TaglibSharp/Id3v2/FrameTypes.cs @@ -101,5 +101,7 @@ static class FrameType public static readonly ReadOnlyByteVector WPUB = "WPUB"; public static readonly ReadOnlyByteVector WXXX = "WXXX"; public static readonly ReadOnlyByteVector ETCO = "ETCO"; + public static readonly ReadOnlyByteVector MVNM = "MVNM"; // Movement Name + public static readonly ReadOnlyByteVector MVIN = "MVIN"; // Movement Number/Count } } diff --git a/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs b/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs index 541adf2a7..053563a37 100644 --- a/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs +++ b/src/TaglibSharp/Id3v2/Frames/TextIdentificationFrame.cs @@ -875,7 +875,9 @@ protected void ParseRawData () FrameId == FrameType.TPE1 || FrameId == FrameType.TPE2 || FrameId == FrameType.TPE3 || - FrameId == FrameType.TPE4) { + FrameId == FrameType.TPE4 || + FrameId == FrameType.MVNM || + FrameId == FrameType.MVIN) { field_list.AddRange (value.Split ('/')); } else if (FrameId == FrameType.TCON) { while (value.Length > 1 && value[0] == '(') { From a8421d90d548aa1f077213edff4245709c87b8ea Mon Sep 17 00:00:00 2001 From: IS4 Date: Wed, 12 Jun 2024 18:17:44 +0200 Subject: [PATCH 03/14] Comment TAGLIB# DEBUG line --- src/TaglibSharp/Xmp/XmpTag.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TaglibSharp/Xmp/XmpTag.cs b/src/TaglibSharp/Xmp/XmpTag.cs index 5c9fa548a..a603db304 100644 --- a/src/TaglibSharp/Xmp/XmpTag.cs +++ b/src/TaglibSharp/Xmp/XmpTag.cs @@ -1022,7 +1022,7 @@ static void EnsureNamespacePrefix (string ns) { if (!NamespacePrefixes.ContainsKey (ns)) { NamespacePrefixes.Add (ns, $"ns{++anon_ns_count}"); - Console.WriteLine ("TAGLIB# DEBUG: Added {0} prefix for {1} namespace (XMP)", NamespacePrefixes[ns], ns); + // Console.WriteLine ("TAGLIB# DEBUG: Added {0} prefix for {1} namespace (XMP)", NamespacePrefixes[ns], ns); } } From 32dff4350afae1b4df232e4acf404ac06eb6b3c8 Mon Sep 17 00:00:00 2001 From: Roberto Basile Date: Thu, 24 Aug 2023 17:08:44 -0400 Subject: [PATCH 04/14] Added method to check if file is supported instead of waiting for exception --- src/TaglibSharp/File.cs | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/TaglibSharp/File.cs b/src/TaglibSharp/File.cs index 40f691c69..a9b1d8147 100644 --- a/src/TaglibSharp/File.cs +++ b/src/TaglibSharp/File.cs @@ -1235,6 +1235,37 @@ public static File Create (string path, string mimetype, ReadStyle propertiesSty return Create (new LocalFileAbstraction (path), mimetype, propertiesStyle); } + /// + /// Returns true if the file is supported + /// + /// The file path + /// True if supported, false otherwise + public static bool IsSupportedFile (string path) + { + var abstraction = new LocalFileAbstraction (path); + + return IsSupportedFile (abstraction); + } + + private static bool IsSupportedFile(IFileAbstraction abstraction) + { + string mimetype = GetMimeType (abstraction); + + return FileTypes.AvailableTypes.ContainsKey (mimetype); + } + + private static string GetMimeType (IFileAbstraction abstraction) + { + string ext = string.Empty; + + int index = abstraction.Name.LastIndexOf (".") + 1; + + if (index >= 1 && index < abstraction.Name.Length) + ext = abstraction.Name.Substring (index, abstraction.Name.Length - index); + + return $"taglib/{ext.ToLower (CultureInfo.InvariantCulture)}"; + } + /// /// Creates a new instance of a subclass /// for a specified file abstraction, mime-type, and read @@ -1269,16 +1300,7 @@ public static File Create (string path, string mimetype, ReadStyle propertiesSty /// public static File Create (IFileAbstraction abstraction, string mimetype, ReadStyle propertiesStyle) { - if (mimetype == null) { - string ext = string.Empty; - - int index = abstraction.Name.LastIndexOf (".") + 1; - - if (index >= 1 && index < abstraction.Name.Length) - ext = abstraction.Name.Substring (index, abstraction.Name.Length - index); - - mimetype = "taglib/" + ext.ToLower (CultureInfo.InvariantCulture); - } + mimetype ??= GetMimeType (abstraction); foreach (var resolver in file_type_resolvers) { var file = resolver (abstraction, mimetype, propertiesStyle); @@ -1287,7 +1309,7 @@ public static File Create (IFileAbstraction abstraction, string mimetype, ReadSt return file; } - if (!FileTypes.AvailableTypes.ContainsKey (mimetype)) + if (!IsSupportedFile(abstraction)) throw new UnsupportedFormatException ( string.Format (CultureInfo.InvariantCulture, "{0} ({1})", abstraction.Name, mimetype)); From 1c812810baff706ca7a0a0fcc4f64cdb923d4392 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Fri, 28 Jul 2023 21:01:19 +0200 Subject: [PATCH 05/14] - Fix Wrong Frame used for MusicBrainz Track Id - See #304 - Add MusicBrainzRecordingId - Add MusicBrainzWorkId --- .github/workflows/ubuntu.yml | 4 ++-- src/TaglibSharp/Id3v2/Tag.cs | 36 +++++++++++++++++++++++++++++++++++- src/TaglibSharp/Tag.cs | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index bb0cde499..cb9cd6965 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.302 - name: Build with dotnet diff --git a/src/TaglibSharp/Id3v2/Tag.cs b/src/TaglibSharp/Id3v2/Tag.cs index 1c3676ff7..cd669dc0a 100644 --- a/src/TaglibSharp/Id3v2/Tag.cs +++ b/src/TaglibSharp/Id3v2/Tag.cs @@ -1973,14 +1973,48 @@ public override string MusicBrainzReleaseArtistId { /// instance, or null if no value is present. /// /// - /// This property is implemented using the "UFID:http://musicbrainz.org" frame. + /// This property is implemented using the "TXXX:MusicBrainz Release Track Id" frame. /// http://musicbrainz.org/doc/PicardTagMapping /// public override string MusicBrainzTrackId { + get { return GetUfidText ("MusicBrainz Release Track Id"); } + set { SetUfidText ("MusicBrainz Release Track Id", value); } + } + + /// + /// Gets and sets the MusicBrainz RecordingID + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "UFID:http://musicbrainz.org" frame. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzRecordingId { get { return GetUfidText ("http://musicbrainz.org"); } set { SetUfidText ("http://musicbrainz.org", value); } } + /// + /// Gets and sets the MusicBrainz WorkID + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "TXXX:MusicBrainz Work Id" frame. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzWorkId { + get { return GetUfidText ("MusicBrainz Work Id"); } + set { SetUfidText ("MusicBrainz Work Id", value); } + } + /// /// Gets and sets the MusicBrainz DiscID /// diff --git a/src/TaglibSharp/Tag.cs b/src/TaglibSharp/Tag.cs index 9e5c00b8b..953a216af 100644 --- a/src/TaglibSharp/Tag.cs +++ b/src/TaglibSharp/Tag.cs @@ -848,6 +848,42 @@ public virtual string MusicBrainzTrackId { set { } } + /// + /// Gets and sets the MusicBrainz Recording ID of the media represented by + /// the current instance. + /// + /// + /// A containing the MusicBrainz RecordingID of the + /// media represented by the current instance or an empty + /// array if no value is present. + /// + /// + /// This field represents the MusicBrainz RecordingID, and is used + /// to uniquely identify a particular recording. + /// + public virtual string MusicBrainzRecordingId { + get { return null; } + set { } + } + + /// + /// Gets and sets the MusicBrainz Work ID of the media represented by + /// the current instance. + /// + /// + /// A containing the MusicBrainz WorkID of the + /// media represented by the current instance or an empty + /// array if no value is present. + /// + /// + /// This field represents the MusicBrainz WorkID, and is used + /// to uniquely identify a particular work. + /// + public virtual string MusicBrainzWorkId { + get { return null; } + set { } + } + /// /// Gets and sets the MusicBrainz Disc ID of the media represented by /// the current instance. From 57c08502a40ae07c625df393650f1a66c7160d99 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 16:56:50 +0200 Subject: [PATCH 06/14] fix Ape Tags: MusicBrainzTrackId + Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/Ape/Tag.cs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/TaglibSharp/Ape/Tag.cs b/src/TaglibSharp/Ape/Tag.cs index c3b631b6b..4ad703c25 100644 --- a/src/TaglibSharp/Ape/Tag.cs +++ b/src/TaglibSharp/Ape/Tag.cs @@ -1420,14 +1420,48 @@ public override string MusicBrainzReleaseArtistId { /// or if no value is present. /// /// - /// This property is implemented using the "MUSICBRAINZ_TRACKID" item. + /// This property is implemented using the "MUSICBRAINZ_RELEASETRACKID" item. /// http://musicbrainz.org/doc/PicardTagMapping /// public override string MusicBrainzTrackId { + get { return GetItemAsString ("MUSICBRAINZ_RELEASETRACKID"); } + set { SetValue ("MUSICBRAINZ_RELEASETRACKID", value); } + } + + /// + /// Gets and sets the MusicBrainz RecordingID + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "MUSICBRAINZ_TRACKID" frame. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzRecordingId { get { return GetItemAsString ("MUSICBRAINZ_TRACKID"); } set { SetValue ("MUSICBRAINZ_TRACKID", value); } } + /// + /// Gets and sets the MusicBrainz WorkID + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "MUSICBRAINZ_WORKID" frame. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzWorkId { + get { return GetItemAsString ("MUSICBRAINZ_WORKID"); } + set { SetValue ("MUSICBRAINZ_WORKID", value); } + } + /// /// Gets and sets the MusicBrainz Disc ID of the media /// represented by the current instance. From 31919c69b2997434ebf3dcc23887c57bbe8fafa4 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 17:10:50 +0200 Subject: [PATCH 07/14] fix Asf Tags: MusicBrainzTrackId + Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/Asf/Tag.cs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/TaglibSharp/Asf/Tag.cs b/src/TaglibSharp/Asf/Tag.cs index 84717ba22..72872b32b 100644 --- a/src/TaglibSharp/Asf/Tag.cs +++ b/src/TaglibSharp/Asf/Tag.cs @@ -1176,15 +1176,49 @@ public override string MusicBrainzReleaseArtistId { /// instance or null if no value is present. /// /// - /// This property is implemented using the "MusicBrainz/Track Id" + /// This property is implemented using the "MusicBrainz/Release Track Id" /// field. /// http://musicbrainz.org/doc/PicardTagMapping /// public override string MusicBrainzTrackId { + get { return GetDescriptorString ("MusicBrainz/Release Track Id"); } + set { SetDescriptorString (value, "MusicBrainz/Release Track Id"); } + } + + /// + /// Gets and sets the MusicBrainz RecordingID + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "MusicBrainz/Track Id" field. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzRecordingId { get { return GetDescriptorString ("MusicBrainz/Track Id"); } set { SetDescriptorString (value, "MusicBrainz/Track Id"); } } + /// + /// Gets and sets the MusicBrainz WorkID + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "MusicBrainz/Work Id" field. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzWorkId { + get { return GetDescriptorString ("MusicBrainz/Work Id"); } + set { SetDescriptorString (value, "MusicBrainz/Work Id"); } + } + /// /// Gets and sets the MusicBrainz Disc ID of /// the media described by the current instance. From acb4abb7b01abe83fc986aef11809ba9f3f66450 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 17:16:41 +0200 Subject: [PATCH 08/14] CombinedTag: Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/CombinedTag.cs | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/TaglibSharp/CombinedTag.cs b/src/TaglibSharp/CombinedTag.cs index 009eb8faa..5d5b57fc1 100644 --- a/src/TaglibSharp/CombinedTag.cs +++ b/src/TaglibSharp/CombinedTag.cs @@ -1408,6 +1408,82 @@ public override string MusicBrainzTrackId { tag.MusicBrainzTrackId = value; } } + + /// + /// Gets and sets the MusicBrainz Recording ID. + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the + /// current instance or null if no value is present. + /// + /// + /// When getting the value, the child tags are looped + /// through in order and the first non- + /// and non-empty value is returned. + /// When setting the value, it is stored in each child + /// tag. + /// + /// + public override string MusicBrainzRecordingId { + get { + foreach (Tag tag in tags) { + if (tag == null) + continue; + + string value = tag.MusicBrainzRecordingId; + + if (value != null) + return value; + } + + return null; + } + + set { + foreach (Tag tag in tags) + if (tag != null) + tag.MusicBrainzRecordingId = value; + } + } + + /// + /// Gets and sets the MusicBrainz Work ID. + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the + /// current instance or null if no value is present. + /// + /// + /// When getting the value, the child tags are looped + /// through in order and the first non- + /// and non-empty value is returned. + /// When setting the value, it is stored in each child + /// tag. + /// + /// + public override string MusicBrainzWorkId { + get { + foreach (Tag tag in tags) { + if (tag == null) + continue; + + string value = tag.MusicBrainzWorkId; + + if (value != null) + return value; + } + + return null; + } + + set { + foreach (Tag tag in tags) + if (tag != null) + tag.MusicBrainzWorkId = value; + } + } /// /// Gets and sets the MusicBrainz Disc ID. From 62eda56f25d7ff96bc40fffe4cd1754697c836f0 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 17:25:30 +0200 Subject: [PATCH 09/14] fix Mpeg4 AppleTags: MusicBrainzTrackId + Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/Mpeg4/AppleTag.cs | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/TaglibSharp/Mpeg4/AppleTag.cs b/src/TaglibSharp/Mpeg4/AppleTag.cs index 020aab182..272662309 100644 --- a/src/TaglibSharp/Mpeg4/AppleTag.cs +++ b/src/TaglibSharp/Mpeg4/AppleTag.cs @@ -1474,10 +1474,44 @@ public override string MusicBrainzReleaseArtistId { /// http://musicbrainz.org/doc/PicardTagMapping /// public override string MusicBrainzTrackId { + get { return GetDashBox ("com.apple.iTunes", "MusicBrainz Release Track Id"); } + set { SetDashBox ("com.apple.iTunes", "MusicBrainz Release Track Id", value); } + } + + /// + /// Gets and sets the MusicBrainz RecordingID + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "dash"/"----" box type. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzRecordingId { get { return GetDashBox ("com.apple.iTunes", "MusicBrainz Track Id"); } set { SetDashBox ("com.apple.iTunes", "MusicBrainz Track Id", value); } } + /// + /// Gets and sets the MusicBrainz WorkID + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the current + /// instance, or null if no value is present. + /// + /// + /// This property is implemented using the "dash"/"----" box type. + /// http://musicbrainz.org/doc/PicardTagMapping + /// + public override string MusicBrainzWorkId { + get { return GetDashBox ("com.apple.iTunes", "MusicBrainz Work Id"); } + set { SetDashBox ("com.apple.iTunes", "MusicBrainz Work Id", value); } + } + /// /// Gets and sets the MusicBrainz DiscID /// From 0c301f19be73389e9945026a176db5121d9ba7ed Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 17:30:29 +0200 Subject: [PATCH 10/14] Ogg/GroupedComment: Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/Ogg/GroupedComment.cs | 60 +++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/TaglibSharp/Ogg/GroupedComment.cs b/src/TaglibSharp/Ogg/GroupedComment.cs index 80f2a9004..9fc251002 100644 --- a/src/TaglibSharp/Ogg/GroupedComment.cs +++ b/src/TaglibSharp/Ogg/GroupedComment.cs @@ -1110,6 +1110,66 @@ public override string MusicBrainzTrackId { set { if (tags.Count > 0) tags[0].MusicBrainzTrackId = value; } } + /// + /// Gets and sets the MusicBrainz Recording ID. + /// + /// + /// A containing the MusicBrainz + /// RecordingID for the media described by the + /// current instance or null if no value is present. + /// + /// + /// When getting the value, the child comments are looped + /// through in order and the first non- + /// and non-empty value is returned. + /// When setting the value, it is stored in the first + /// comment. + /// + /// + public override string MusicBrainzRecordingId { + get { + foreach (XiphComment tag in tags) { + string value = tag?.MusicBrainzRecordingId; + + if (!string.IsNullOrEmpty (value)) + return value; + } + + return null; + } + set { if (tags.Count > 0) tags[0].MusicBrainzRecordingId = value; } + } + + /// + /// Gets and sets the MusicBrainz Work ID. + /// + /// + /// A containing the MusicBrainz + /// WorkID for the media described by the + /// current instance or null if no value is present. + /// + /// + /// When getting the value, the child comments are looped + /// through in order and the first non- + /// and non-empty value is returned. + /// When setting the value, it is stored in the first + /// comment. + /// + /// + public override string MusicBrainzWorkId { + get { + foreach (XiphComment tag in tags) { + string value = tag?.MusicBrainzWorkId; + + if (!string.IsNullOrEmpty (value)) + return value; + } + + return null; + } + set { if (tags.Count > 0) tags[0].MusicBrainzWorkId = value; } + } + /// /// Gets and sets the MusicBrainz Disc ID. /// From 95d6343ef8d7591933942d53cba6d2298f9ac757 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 17:36:59 +0200 Subject: [PATCH 11/14] fix Ogg/XiphComment: MusicBrainzTrackId + Add MusicBrainzRecordingId, MusicBrainzWorkId --- src/TaglibSharp/Ogg/XiphComment.cs | 36 +++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/TaglibSharp/Ogg/XiphComment.cs b/src/TaglibSharp/Ogg/XiphComment.cs index dd1f98e89..9598baf61 100644 --- a/src/TaglibSharp/Ogg/XiphComment.cs +++ b/src/TaglibSharp/Ogg/XiphComment.cs @@ -1291,13 +1291,47 @@ public override string MusicBrainzReleaseArtistId { /// instance or if no value present. /// /// - /// This property is implemented using the "MUSICBRAINZ_TRACKID" field. + /// This property is implemented using the "MUSICBRAINZ_RELEASETRACKID" field. /// public override string MusicBrainzTrackId { + get { return GetFirstField ("MUSICBRAINZ_RELEASETRACKID"); } + set { SetField ("MUSICBRAINZ_RELEASETRACKID", value); } + } + + /// + /// Gets and sets the MusicBrainz Recording ID for the media + /// represented by the current instance. + /// + /// + /// A object containing the MusicBrainz + /// RecordingID for the media represented by the current + /// instance or if no value present. + /// + /// + /// This property is implemented using the "MUSICBRAINZ_TRACKID" field. + /// + public override string MusicBrainzRecordingId { get { return GetFirstField ("MUSICBRAINZ_TRACKID"); } set { SetField ("MUSICBRAINZ_TRACKID", value); } } + /// + /// Gets and sets the MusicBrainz Work ID for the media + /// represented by the current instance. + /// + /// + /// A object containing the MusicBrainz + /// WorkID for the media represented by the current + /// instance or if no value present. + /// + /// + /// This property is implemented using the "MUSICBRAINZ_WORKID" field. + /// + public override string MusicBrainzWorkId { + get { return GetFirstField ("MUSICBRAINZ_WORKID"); } + set { SetField ("MUSICBRAINZ_WORKID", value); } + } + /// /// Gets and sets the MusicBrainz Disc ID for the media /// represented by the current instance. From 65b54af002ba2a55a8c9a95d5db6592f6542b1b2 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 18:14:09 +0200 Subject: [PATCH 12/14] Add TaggingFormats Tests. --- .../TaggingFormats/ApeTest.cs | 52 ++++++++++++++++- .../TaggingFormats/AsfTest.cs | 50 +++++++++++++++++ .../TaggingFormats/Id3V2Test.cs | 56 +++++++++++++++++++ .../TaggingFormats/Mpeg4Test.cs | 50 +++++++++++++++++ .../TaggingFormats/XiphTest.cs | 50 +++++++++++++++++ 5 files changed, 257 insertions(+), 1 deletion(-) diff --git a/src/TaglibSharp.Tests/TaggingFormats/ApeTest.cs b/src/TaglibSharp.Tests/TaggingFormats/ApeTest.cs index 2082f6b80..dd375bae1 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/ApeTest.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/ApeTest.cs @@ -634,6 +634,56 @@ public void TestMusicBrainzTrackID () }); } + [Test] + public void TestMusicBrainzRecordingID () + { + Tag tag = new Tag (); + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Initial (Null): " + m); + }); + + tag.MusicBrainzRecordingId = val_sing; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzRecordingId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzRecordingId = string.Empty; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Value Cleared (Null): " + m); + }); + } + + [Test] + public void TestMusicBrainzWorkID () + { + Tag tag = new Tag (); + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Initial (Null): " + m); + }); + + tag.MusicBrainzWorkId = val_sing; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzWorkId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzWorkId = string.Empty; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Value Cleared (Null): " + m); + }); + } + [Test] public void TestMusicBrainzDiscID () { @@ -842,4 +892,4 @@ void TagTestWithSave (ref Tag tag, TagTestFunc testFunc) testFunc (tag, "After Save"); } } -} \ No newline at end of file +} diff --git a/src/TaglibSharp.Tests/TaggingFormats/AsfTest.cs b/src/TaglibSharp.Tests/TaggingFormats/AsfTest.cs index 232e9db95..d0ad98459 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/AsfTest.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/AsfTest.cs @@ -633,6 +633,56 @@ public void TestMusicBrainzTrackID () }); } + [Test] + public void TestMusicBrainzRecordingID () + { + var file = CreateFile (out var abst); + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Initial (Null): " + m); + }); + + file.Tag.MusicBrainzRecordingId = val_sing; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzRecordingId, "Value Set (!Null): " + m); + }); + + file.Tag.MusicBrainzRecordingId = string.Empty; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Value Cleared (Null): " + m); + }); + } + + [Test] + public void TestMusicBrainzWorkID () + { + var file = CreateFile (out var abst); + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Initial (Null): " + m); + }); + + file.Tag.MusicBrainzWorkId = val_sing; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzWorkId, "Value Set (!Null): " + m); + }); + + file.Tag.MusicBrainzWorkId = string.Empty; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Value Cleared (Null): " + m); + }); + } + [Test] public void TestMusicBrainzDiscID () { diff --git a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs index 095da3399..6c6b23818 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/Id3V2Test.cs @@ -744,6 +744,62 @@ public void TestMusicBrainzTrackID () } } + [Test] + public void TestMusicBrainzRecordingID () + { + var tag = new Tag (); + for (byte version = 2; version <= 4; version++) { + tag.Version = version; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Initial (Null): " + m); + }); + + tag.MusicBrainzRecordingId = val_sing; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzRecordingId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzRecordingId = string.Empty; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Value Cleared (Null): " + m); + }); + } + } + + [Test] + public void TestMusicBrainzWorkID () + { + var tag = new Tag (); + for (byte version = 2; version <= 4; version++) { + tag.Version = version; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Initial (Null): " + m); + }); + + tag.MusicBrainzWorkId = val_sing; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzWorkId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzWorkId = string.Empty; + + TagTestWithSave (ref tag, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Value Cleared (Null): " + m); + }); + } + } + [Test] public void TestMusicBrainzDiscID () { diff --git a/src/TaglibSharp.Tests/TaggingFormats/Mpeg4Test.cs b/src/TaglibSharp.Tests/TaggingFormats/Mpeg4Test.cs index dbc0ca5d6..d36e160ec 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/Mpeg4Test.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/Mpeg4Test.cs @@ -634,6 +634,56 @@ public void TestMusicBrainzTrackID () }); } + [Test] + public void TestMusicBrainzRecordingID () + { + var file = CreateFile (out var abst); + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Initial (Null): " + m); + }); + + file.Tag.MusicBrainzRecordingId = val_sing; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzRecordingId, "Value Set (!Null): " + m); + }); + + file.Tag.MusicBrainzRecordingId = string.Empty; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Value Cleared (Null): " + m); + }); + } + + [Test] + public void TestMusicBrainzWorkID () + { + var file = CreateFile (out var abst); + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Initial (Null): " + m); + }); + + file.Tag.MusicBrainzWorkId = val_sing; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzWorkId, "Value Set (!Null): " + m); + }); + + file.Tag.MusicBrainzWorkId = string.Empty; + + TagTestWithSave (ref file, abst, delegate (Tag t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Value Cleared (Null): " + m); + }); + } + [Test] public void TestMusicBrainzDiscID () { diff --git a/src/TaglibSharp.Tests/TaggingFormats/XiphTest.cs b/src/TaglibSharp.Tests/TaggingFormats/XiphTest.cs index c103d1257..5f8db0803 100644 --- a/src/TaglibSharp.Tests/TaggingFormats/XiphTest.cs +++ b/src/TaglibSharp.Tests/TaggingFormats/XiphTest.cs @@ -659,6 +659,56 @@ public void TestMusicBrainzTrackID () }); } + [Test] + public void TestMusicBrainzRecordingID () + { + var tag = new XiphComment (); + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Initial (Null): " + m); + }); + + tag.MusicBrainzRecordingId = val_sing; + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzRecordingId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzRecordingId = string.Empty; + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzRecordingId, "Value Cleared (Null): " + m); + }); + } + + [Test] + public void TestMusicBrainzWorkID () + { + var tag = new XiphComment (); + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsTrue (t.IsEmpty, "Initial (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Initial (Null): " + m); + }); + + tag.MusicBrainzWorkId = val_sing; + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsFalse (t.IsEmpty, "Value Set (!IsEmpty): " + m); + Assert.AreEqual (val_sing, t.MusicBrainzWorkId, "Value Set (!Null): " + m); + }); + + tag.MusicBrainzWorkId = string.Empty; + + TagTestWithSave (ref tag, delegate (XiphComment t, string m) { + Assert.IsTrue (t.IsEmpty, "Value Cleared (IsEmpty): " + m); + Assert.IsNull (t.MusicBrainzWorkId, "Value Cleared (Null): " + m); + }); + } + [Test] public void TestMusicBrainzDiscID () { From 5aab236f833027564b3ce2e17f273351ced3699c Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sat, 29 Jul 2023 18:24:49 +0200 Subject: [PATCH 13/14] Update Test: Change MusicBrainzTrackId to MusicBrainzRecordingId --- src/TaglibSharp.Tests/FileFormats/M4aFormatTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TaglibSharp.Tests/FileFormats/M4aFormatTest.cs b/src/TaglibSharp.Tests/FileFormats/M4aFormatTest.cs index 8bb33a89b..62dc9b87e 100644 --- a/src/TaglibSharp.Tests/FileFormats/M4aFormatTest.cs +++ b/src/TaglibSharp.Tests/FileFormats/M4aFormatTest.cs @@ -54,10 +54,10 @@ public void bgo_676934 () [Test] public void bgo_701689 () { - // This file contains a musicbrainz track id "883821fc-9bbc-4e04-be79-b4b12c4c4a4e" + // This file contains a musicbrainz recording id "883821fc-9bbc-4e04-be79-b4b12c4c4a4e" // This case also handles bgo #701690 as a proper value for the tag must be returned var file = TagLib.File.Create (TestPath.Samples + "bgo_701689.m4a"); - Assert.AreEqual ("883821fc-9bbc-4e04-be79-b4b12c4c4a4e", file.Tag.MusicBrainzTrackId, "#1"); + Assert.AreEqual ("883821fc-9bbc-4e04-be79-b4b12c4c4a4e", file.Tag.MusicBrainzRecordingId, "#1"); } [Test] From 228d5cb816e68537076ef3cf61f680a739831213 Mon Sep 17 00:00:00 2001 From: Ma <101021254+CodeWithMa@users.noreply.github.com> Date: Sun, 30 Jul 2023 08:43:07 +0200 Subject: [PATCH 14/14] undo github actions change --- .github/workflows/ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index cb9cd6965..bb0cde499 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v1 - name: Setup .NET Core - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v1 with: dotnet-version: 6.0.302 - name: Build with dotnet