benrr101 / node-taglib-sharp

A node.js port of mono/taglib-sharp
GNU Lesser General Public License v2.1
42 stars 11 forks source link

Cannot open files with metadata edited in windows apps #36

Closed javalsai closed 3 years ago

javalsai commented 3 years ago

When I save i file that I have changed it's metadata and I try to open it, windows apps says that it's corrupted, but I can open it with VLC or chrome.

My code:

const myFile = taglib.File.createFromPath('path/to/audioFile.mp3');
const pic = {
   data: taglib.ByteVector.fromPath('path/to/cover.jpg'),
   mimeType: 'image/jpg',
   type: taglib.PictureType.FrontCover,
};
myFile.tag.title = "Some Title";
myFile.tag.album = "Some Album";
myFile.tag.albumArtists = ["Some Artist"];
myFile.tag.comment = "Some comment";
myFile.tag.performers = ["Some Artist"];
myFile.tag.pictures = [pic];
myFile.tag.year = 2020;
myFile.tag.track = 3;
myFile.tag.trackCount = 7;
myFile.tag.lyrics = 'Some lyrics...';
myFile.save();
myFile.dispose();

Thanks!

benrr101 commented 3 years ago

Hi, can you supply some more information so I can reproduce the problem? What windows apps are telling you the file is corrupted after editing? Is this the case with all MP3 files you try to edit or only specific ones? Can you supply a file that this happens with?

Corrupting files is the last thing I want this library to do. Any information you can supply to help me eliminate these issues will go a long way.

javalsai commented 3 years ago

The apps that tell that the file is corrupted is "Groove Music" and "Windows Media Player".l I just make probes with two songs: "Believer - Imagine Dragons" and "Wrecked- Imagine Dragons". The first one I can open with VLC and chrome and the second just works in chrome (in VLC appears the cover for a few milliseconds and then closes).

javalsai commented 3 years ago

corrupted.zip Here are the files if you want to check them.

benrr101 commented 3 years ago

Thank you for the information! I'll give it a look after work today and see what's going on.

benrr101 commented 3 years ago

One other thing, which version of the library are you using? There was a significant bug in v3.3.0 that caused pictures on ID3v2 tags to fail if the mimetype of a picture was read (or possibly stored) as latin1 text encoding. This was fixed in v3.3.1.

javalsai commented 3 years ago

I think I'm using the latest, but I can't confirm it now.

benrr101 commented 3 years ago

Ok, so I was able to inspect the files you gave me... It looks like you're downloading youtube videos, which are coming in as webm files with ogg/opus audio, renaming them to mp3, and running the library over them. Cracking open the files in a hex editor to verify the structure of the ID3v2.3 tags, everything looked fine, but then I saw the webm headers after the ID3 info image

VLC also confirms this on the file that can be read: image

Unfortunately, this won't work. node-taglib-sharp determines how to read/write tags based on file extension, primarily. You can override this by providing a mimetype to the File.createFromPath method, but that won't help in this case. So, by having the webm file renamed to mp3, node-taglib-sharp will try to load the tags of the file as if it were an mp3 - by looking for ID3 and 3DI control words at the beginning and end of the file. Finding none, it will create a blank ID3v2.3 tag that, when saved, will be written to the beginning of the file or end of the file.

Some media players will use "magic" to determine how to play a media file and can probably work around being fed a webm file with the wrong extension. Adding ID3 at the beginning of a file is a pretty strong hint to a media player that a file is an mp3, so some players may try to treat it as mp3 audio and get upset when they can't decode it. Oddly though, VLC was able to figure one of the files out and still determine it's ogg/opus audio. Also interesting, I was able to get both to play in VLC if I renamed them back to webm, though the tagging information was ignored.

So what can we do to get you back on track? Assuming you're using youtube-dl to download the videos, it's actually pretty easy to get audio. You can specify the --extract-audio flag to just get the audio from the video. This will give you a .opus file for the videos you listed. Ogg/Opus files aren't supported in node-taglib-sharp yet, but it's on its way. Although I don't recommend it, you can convert the opus file to mp3 using the --extract-audio --audio-format mp3 flags to youtube-dl. This should download the opus audio and convert it to mp3. This gives you an mp3 file you can tag with node-taglib-sharp.

Let me know if you have any other questions, but for now I think that closes up this issue. Thanks again for trying out node-taglib-sharp!

javalsai commented 3 years ago

I'm not using youtube-dl for downloading, I'm using the ytdl-core node module. I tried to filter the video formats with codec mp4a.40.2, because I didn't found an mp3 codec, and finally I can play "Wrecked" with VLC, but not with Windows apps. If I transform mp4to mp3 with ffmpeg before adding metadata to it I should be able to open it with Windows app?

benrr101 commented 3 years ago

Ah, I see. Looking at the docs for ytdl-core it looks like they have support for downloading only audio, and looks like you tried that. Maybe if the video doesn't have a version in that quality, it just defaults to whatever quality is highest and that ends up being a webm? Maybe try it with the "audioonly" filter they have?

Keep in mind however that the most common audio codecs for youtube (ogg/opus and mp4/aac) are not yet supported in node-taglib-sharp 😢. Your suggestion to convert mp4/webm to mp3 before adding metadata would definitely work, however. Support for the aforementioned will probably be coming out in a few months (unless someone else wants to jump in and work on them).