Zeugma440 / atldotnet

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
MIT License
442 stars 60 forks source link

Clearing all metadata fields on M4A File Corrupts File #218

Closed nlogozzo closed 11 months ago

nlogozzo commented 11 months ago

I have this file: (removed) It loads correctly, shows the tag and pictures no problem.

Then I go to clear the tag with this function:

/// <summary>
/// Clears a file's tag (does not save to disk)
/// </summary>
public void ClearTag()
{
    _filename = System.IO.Path.GetFileName(Path);
    Title = "";
    Artist = "";
    Album = "";
    Year = 0;
    Track = 0;
    TrackTotal = 0;
    AlbumArtist = "";
    Genre = "";
    Comment = "";
    BeatsPerMinute = 0;
    Composer = "";
    Description = "";
    Publisher = "";
    _track.EmbeddedPictures.Clear();
    _track.AdditionalFields.Clear();
    Lyrics = new LyricsInfo();
}

Note that properties like Title, Artist, etc.. are just _track.Title, _track.Artist abstractions...

then Save with this function:

/// <summary>
/// Saves the tag of the music file to disk
/// </summary>
/// <param name="preserveModificationTimestamp">Whether or not to preserve (not change) a file's modification timestamp</param>
/// <returns>True if successful, else false</returns>
public bool SaveTagToDisk(bool preserveModificationTimestamp)
{
    if (IsReadOnly)
    {
        return false;
    }
    var res = _track.Save();
    if(res)
    {
        if(System.IO.Path.GetFileName(Path) != Filename)
        {
            var newPath = $"{System.IO.Path.GetDirectoryName(Path)}{System.IO.Path.DirectorySeparatorChar}{Filename}";
            File.Move(Path, newPath);
            Path = newPath;
            _track = new Track(Path);
        }
        if(preserveModificationTimestamp)
        {
            File.SetLastWriteTime(Path, _modificationTimestamp);
        }
        else
        {
            _modificationTimestamp = File.GetLastWriteTime(Path);
        }
    }
    return res;
}

no issue.

Upon reloading the file, I get the error:

Data should be at least 4 bytes long; found 0 bytes
   at ATL.StreamUtils.DecodeBEUInt32(Byte[] data)
   at ATL.AudioData.IO.MP4.readTag(BinaryReader source, ReadTagParams readTagParams)
   at ATL.AudioData.IO.MP4.readUserData(BinaryReader source, ReadTagParams readTagParams, Int64 moovPosition, UInt32 moovSize)
   at ATL.AudioData.IO.MP4.readMP4(BinaryReader source, ReadTagParams readTagParams)
   at ATL.AudioData.IO.MP4.read(Stream source, ReadTagParams readTagParams)
   at ATL.AudioData.IO.MP4.Read(Stream source, SizeInfo sizeInfo, ReadTagParams readTagParams)
   at ATL.AudioData.AudioDataManager.read(Stream source, ReadTagParams readTagParams)
   at ATL.AudioData.AudioDataManager.read(Stream source, Boolean readEmbeddedPictures, Boolean readAllMetaFrames, Boolean prepareForWriting)
   at ATL.AudioData.AudioDataManager.ReadFromFile(Boolean readEmbeddedPictures, Boolean readAllMetaFrames)

and I'm unable to edit the track and save it again as then I get the error Stream was not readable.

I'm assume it's the empty picture list causing the corruption as if I comment out the line

_track.EmbeddedPictures.Clear();

in ClearTag(), i get no corruption and am able to reload the file and modify the tag and save changes and everything no problem

nlogozzo commented 11 months ago

Just happens on that m4a file...all my other flac and mp3 files work no problem even with clearing the pictures

Zeugma440 commented 11 months ago

Thanks for the feedback, I'm gonna look into it.

Btw, do you know you can also remove the tag using Track.Remove ?

nlogozzo commented 11 months ago

Btw, do you know you can also remove the tag using Track.Remove ?

Yes but that writes to disk right away no?

Zeugma440 commented 11 months ago

You're right, it has immediate effect

btw I managed to repro your problem. Stay tuned~

Zeugma440 commented 11 months ago

Fixed ! b11c681e3f701ba9b79ca10dddf36cf3f57b816e

The problem wasn't linked to the picture in particular, but happened when clearing all fields manually. The ILST atom header, which remained empty and alone, wasn't written with its correct size.

I guess you're expecting a release soon-ish? 😁

nlogozzo commented 11 months ago

The problem wasn't linked to the picture in particular, but happened when clearing all fields manually. The ILST atom header, which remained empty and alone, wasn't written with its correct size.

Ah ok...thanks for fixing!!

I guess you're expecting a release soon-ish? 😁

Yes please 🙂

Zeugma440 commented 11 months ago

Fix is available in today's v5.03

nlogozzo commented 11 months ago

Works! Thank you so much :)