Skip to content

Commit

Permalink
MP4 : Setting a single Year or a comprehensive DateTime now reflects …
Browse files Browse the repository at this point in the history
…properly on the saved value
  • Loading branch information
Zeugma440 committed Feb 26, 2023
1 parent 90d914b commit 77f21db
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 17 deletions.
118 changes: 114 additions & 4 deletions ATL.test/IO/HighLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using static ATL.Logging.Log;
using System;
using ATL.Logging;
using Commons;

namespace ATL.test.IO
{
Expand Down Expand Up @@ -1028,7 +1029,7 @@ public void StreamedIO_RW_Meta()
}

[TestMethod]
public void ID3v1_Ignore_RW()
public void TagIO_RW_ID3v1_Ignore()
{
string resource = "MP3/id3v1.mp3";
string testFileLocation = TestUtils.CopyAsTempTestFile(resource);
Expand Down Expand Up @@ -1059,7 +1060,7 @@ public void ID3v1_Ignore_RW()
}

[TestMethod]
public void ID3v1_Focus_RW()
public void TagIO_RW_ID3v1_Focus()
{
string resource = "MP3/id3v1.mp3";
string testFileLocation = TestUtils.CopyAsTempTestFile(resource);
Expand Down Expand Up @@ -1088,7 +1089,7 @@ public void ID3v1_Focus_RW()
}

[TestMethod]
public void Chapters_Consistency()
public void TagIO_RW_Chapters_Consistency()
{
ArrayLogger log = new ArrayLogger();

Expand All @@ -1112,7 +1113,7 @@ public void Chapters_Consistency()
}

[TestMethod]
public void Lyrics_Consistency()
public void TagIO_RW_Lyrics_Consistency()
{
ArrayLogger log = new ArrayLogger();

Expand All @@ -1133,5 +1134,114 @@ public void Lyrics_Consistency()
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);
}

[TestMethod]
public void TagIO_RW_MP4_Year_or_Date_On_File()
{
// == 1a- Add a YEAR to an empty file
string emptyResource = "MP4/empty.m4a";
string testFileLocation = TestUtils.CopyAsTempTestFile(emptyResource);
Track theTrack = new Track(testFileLocation);

theTrack.Year = 1993;
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(1993, theTrack.Year);
Assert.AreEqual(20, getDayFieldLength(testFileLocation)); // Date stored as Year

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);


// == 1b- Add a DATE to an empty file
testFileLocation = TestUtils.CopyAsTempTestFile(emptyResource);
theTrack = new Track(testFileLocation);

DateTime date = new DateTime(2001, 4, 20);
theTrack.Date = date;
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(date.ToString(), theTrack.Date.ToString());
Assert.AreEqual(26, getDayFieldLength(testFileLocation)); // Date stored as Date

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);



// == 2a- Add a YEAR to a file tagged with a DATE
testFileLocation = TestUtils.CopyAsTempTestFile("MP4/mp4_date_in_©day.m4a");
theTrack = new Track(testFileLocation);

theTrack.Year = 1993;
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(1993, theTrack.Year);
Assert.AreEqual(20, getDayFieldLength(testFileLocation)); // Date stored as Year

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);


// == 2b- Add a DATE to a file tagged with a YEAR
testFileLocation = TestUtils.CopyAsTempTestFile("MP4/mp4.m4a");
theTrack = new Track(testFileLocation);

theTrack.Date = date;
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(date.ToString(), theTrack.Date.ToString());
Assert.AreEqual(26, getDayFieldLength(testFileLocation)); // Date stored as Date

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);



// == 3a- Keep YEAR after rewriting file
testFileLocation = TestUtils.CopyAsTempTestFile("MP4/mp4.m4a");
theTrack = new Track(testFileLocation);

int year = theTrack.Year.Value;
theTrack.Title = "That's some new title you got here!";
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(year, theTrack.Year);
Assert.AreEqual(20, getDayFieldLength(testFileLocation)); // Date stored as Year

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);


// == 3b- Keep DATE after rewriting file
testFileLocation = TestUtils.CopyAsTempTestFile("MP4/mp4_date_in_©day.m4a");
theTrack = new Track(testFileLocation);

date = theTrack.Date.Value;
theTrack.Title = "That's some new title you got here!";
Assert.IsTrue(theTrack.Save());

theTrack = new Track(testFileLocation);
Assert.AreEqual(date.ToString(), theTrack.Date.ToString());
Assert.AreEqual(26, getDayFieldLength(testFileLocation)); // Date stored as Date

// Get rid of the working copy
if (Settings.DeleteAfterSuccess) File.Delete(testFileLocation);
}

private int getDayFieldLength(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
Assert.AreEqual(true, StreamUtils.FindSequence(fs, Utils.Latin1Encoding.GetBytes("©day")));
byte[] buffer = new byte[4];
fs.Read(buffer, 0, 4);
return StreamUtils.DecodeBEInt32(buffer);
}
}
}
}
8 changes: 4 additions & 4 deletions ATL/ATL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
<Description>Fully managed, portable and easy-to-use C# library to read and edit audio data and metadata (tags) from various audio formats, playlists and CUE sheets</Description>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Company />
<AssemblyVersion>4.19.0.0</AssemblyVersion>
<AssemblyVersion>4.20.0.0</AssemblyVersion>
<PackageId>z440.atl.core</PackageId>
<PackageVersion>4.18.0</PackageVersion>
<PackageVersion>4.19.0</PackageVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageTags>audio metadata tag mp3 mp4 aac id3v2 ogg vorbis opus flac playlist cue</PackageTags>
<PackageLicenseUrl></PackageLicenseUrl>
<PackageProjectUrl>https://github.com/Zeugma440/atldotnet</PackageProjectUrl>
<Authors>Zeugma440</Authors>
<Product>Audio Tools Library (ATL) for .NET</Product>
<FileVersion>4.19.0.0</FileVersion>
<FileVersion>4.20.0.0</FileVersion>
<PackageReleaseNotes></PackageReleaseNotes>
<Version>4.19.0</Version>
<Version>4.20.0</Version>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net30|AnyCPU'">
Expand Down
20 changes: 17 additions & 3 deletions ATL/AudioData/CrossMetadataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public CrossMetadataReader(AudioDataManager audioManager, MetaDataIOFactory.TagT
/// <inheritdoc/>
public bool Exists
{
get { return (metaReaders.Count > 0); }
get { return metaReaders.Count > 0; }
}
/// <inheritdoc/>
public IList<Format> MetadataFormats
Expand Down Expand Up @@ -204,12 +204,26 @@ public DateTime Date
return date;
}
}

/// <inheritdoc/>
public bool IsDateYearOnly
{
get
{
foreach (IMetaDataIO reader in metaReaders)
{
if (reader.Date != DateTime.MinValue) return reader.IsDateYearOnly;
}
return false;
}
}

/// <inheritdoc/>
public String Album
public string Album
{
get
{
String album = "";
string album = "";
foreach (IMetaDataIO reader in metaReaders)
{
album = reader.Album;
Expand Down
9 changes: 7 additions & 2 deletions ATL/AudioData/Interfaces/IMetaData.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using ATL.AudioData.IO;
using System;
using System.Collections.Generic;
using System.IO;

namespace ATL.AudioData
{
Expand Down Expand Up @@ -89,6 +87,13 @@ DateTime Date
get;
}
/// <summary>
/// True if the provided Date only has Year as a valid field
/// </summary>
bool IsDateYearOnly
{
get;
}
/// <summary>
/// Title of the album
/// </summary>
string Album
Expand Down
11 changes: 11 additions & 0 deletions ATL/Entities/MetadataHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ public DateTime Date
tagData.IntegrateValue(Field.RECORDING_TIME, (value > DateTime.MinValue) ? value.ToString("HHmm", CultureInfo.InvariantCulture) : null);
}
}
/// <inheritdoc/>
public bool IsDateYearOnly
{
get
{
if (Utils.ProtectValue(tagData[Field.RECORDING_DATE]).Length > 4) return false;
if (Utils.ProtectValue(tagData[Field.RECORDING_DATE_OR_YEAR]).Length > 4) return false;
return Utils.ProtectValue(tagData[Field.RECORDING_YEAR]).Length > 0;
}
}

/// <inheritdoc/>
public DateTime PublishingDate
{
Expand Down
36 changes: 32 additions & 4 deletions ATL/Entities/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,15 @@ public Track(Stream stream, string mimeType)
/// <summary>
/// Recording Date (set to DateTime.MinValue to remove)
/// </summary>
public DateTime? Date { get; set; }
public DateTime? Date
{
get => date;
set
{
date = value;
isYearExplicit = false;
}
}
/// <summary>
/// Recording Year
/// </summary>
Expand All @@ -176,6 +184,7 @@ public int? Year
if (canUseValue(value) && value.Value > DateTime.MinValue.Year) Date = new DateTime(value.Value, 1, 1);
else if (Settings.NullAbsentValues) Date = null;
else Date = DateTime.MinValue;
isYearExplicit = true;
}
}
/// <summary>
Expand Down Expand Up @@ -229,6 +238,9 @@ public int? Year
private IList<PictureInfo> currentEmbeddedPictures { get; set; } = null;
private ICollection<PictureInfo> initialEmbeddedPictures; // Initial fields, used to identify removed ones

private DateTime? date = null;
private bool isYearExplicit = false;

/// <summary>
/// Format of the tagging systems
/// </summary>
Expand Down Expand Up @@ -388,7 +400,15 @@ protected void Update(bool onlyReadEmbeddedPictures = false)
SeriesPart = Utils.ProtectValue(processString(metadata.SeriesPart));
LongDescription = Utils.ProtectValue(processString(metadata.LongDescription));
Album = Utils.ProtectValue(processString(metadata.Album));
Date = update(metadata.Date);
isYearExplicit = metadata.IsDateYearOnly;
if (metadata.IsDateYearOnly)
{
Year = update(metadata.Date.Year);
}
else
{
Date = update(metadata.Date);
}
PublishingDate = update(metadata.PublishingDate);
TrackNumber = update(metadata.TrackNumber);
TrackTotal = update(metadata.TrackTotal);
Expand Down Expand Up @@ -454,8 +474,16 @@ private TagData toTagData()
result.IntegrateValue(Field.SERIES_TITLE, SeriesTitle);
result.IntegrateValue(Field.SERIES_PART, SeriesPart);
result.IntegrateValue(Field.LONG_DESCRIPTION, LongDescription);
result.IntegrateValue(Field.RECORDING_DATE, toTagValue(Date));
result.IntegrateValue(Field.RECORDING_YEAR, toTagValue(Year));
if (isYearExplicit)
{
result.IntegrateValue(Field.RECORDING_YEAR, toTagValue(Year));
result.IntegrateValue(Field.RECORDING_DATE, toTagValue(Year));
}
else
{
result.IntegrateValue(Field.RECORDING_DATE, toTagValue(Date));
result.IntegrateValue(Field.RECORDING_YEAR, "");
}
result.IntegrateValue(Field.ALBUM, Album);
result.IntegrateValue(Field.TRACK_NUMBER, toTagValue(TrackNumber));
result.IntegrateValue(Field.TRACK_TOTAL, toTagValue(TrackTotal));
Expand Down

0 comments on commit 77f21db

Please sign in to comment.