Cog/Plugins/TagLib/TagLibMetadataWriter.m
Christopher Snowhill 2e884b9e85 TagLib: Implement preliminary writer class
This is not currently being used anywhere, but may function eventually.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-02-17 04:25:36 -08:00

189 lines
6 KiB
Objective-C

//
// TagLibMetadataWriter.m
// TagLib
//
// Created by Safari on 08/11/17.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "TagLibMetadataWriter.h"
#import <tag/fileref.h>
#import <tag/tag.h>
#import "Logging.h"
static NSString *toString(id value) {
if([value isKindOfClass:[NSString class]])
return (NSString *)value;
else if([value isKindOfClass:[NSArray class]]) {
NSArray *arrayValue = value;
return [arrayValue componentsJoinedByString:@", "];
} else if([value isKindOfClass:[NSNumber class]]) {
NSNumber *numberValue = value;
return [NSString stringWithFormat:@"%@", numberValue];
} else {
return @"";
}
}
static int toInt(id value) {
if([value isKindOfClass:[NSNumber class]]) {
NSNumber *numberValue = value;
return [numberValue intValue];
} else {
return 0;
}
}
static TagLib::Tag::ReplayGain toReplaygain(NSDictionary *tags) {
TagLib::Tag::ReplayGain rg;
NSNumber *lReplaygainAlbumGain = [tags valueForKey:@"replaygain_album_gain"];
NSNumber *lReplaygainAlbumPeak = [tags valueForKey:@"replaygain_album_peak"];
NSNumber *lReplaygainTrackGain = [tags valueForKey:@"replaygain_track_gain"];
NSNumber *lReplaygainTrackPeak = [tags valueForKey:@"replaygain_track_peak"];
if(lReplaygainAlbumGain)
rg.setAlbumGain([lReplaygainAlbumGain floatValue]);
if(lReplaygainAlbumPeak)
rg.setAlbumPeak([lReplaygainAlbumPeak floatValue]);
if(lReplaygainTrackGain)
rg.setTrackGain([lReplaygainTrackGain floatValue]);
if(lReplaygainTrackPeak)
rg.setTrackPeak([lReplaygainTrackPeak floatValue]);
return rg;
}
@implementation TagLibMetadataWriter
+ (int)putMetadataInURL:(NSURL *)url tagData:(NSDictionary *)tagData {
NSString *lTitle = @"", *lAlbumArtist = @"", *lArtist = @"", *lComposer = @"", *lAlbum = @"", *lUnsyncedLyrics = @"", *lComment = @"", *lGenre = @"", *lCuesheet = @"";
int lYear = 0, lTrack = 0, lDisc = 0;
TagLib::Tag::ReplayGain lReplaygain;
try {
TagLib::FileRef f((const char *)[[url path] UTF8String], false);
if(!f.isNull()) {
const TagLib::Tag *tag = f.tag();
if(tag) {
bool altered = false;
TagLib::String pTitle, pAlbumArtist, pArtist, pComposer, pAlbum, pUnsyncedLyrics, pComment, pGenre, pCuesheet;
int pYear, pTrack, pDisc;
TagLib::Tag::ReplayGain pReplaygain;
lTitle = toString([tagData valueForKey:@"title"]);
lAlbumArtist = toString([tagData valueForKey:@"albumartist"]);
lArtist = toString([tagData valueForKey:@"artist"]);
lComposer = toString([tagData valueForKey:@"composer"]);
lAlbum = toString([tagData valueForKey:@"album"]);
lUnsyncedLyrics = toString([tagData valueForKey:@"unsyncedlyrics"]);
lComment = toString([tagData valueForKey:@"comment"]);
lGenre = toString([tagData valueForKey:@"genre"]);
lCuesheet = toString([tagData valueForKey:@"cuesheet"]);
lYear = toInt([tagData valueForKey:@"year"]);
lTrack = toInt([tagData valueForKey:@"track"]);
lDisc = toInt([tagData valueForKey:@"disc"]);
lReplaygain = toReplaygain(tagData);
pTitle = tag->title();
pAlbumArtist = tag->albumartist();
pArtist = tag->artist();
pComposer = tag->composer();
pAlbum = tag->album();
pUnsyncedLyrics = tag->unsyncedlyrics();
pComment = tag->comment();
pGenre = tag->genre();
pCuesheet = tag->cuesheet();
pYear = tag->year();
pTrack = tag->track();
pDisc = tag->disc();
pReplaygain = tag->replaygain();
if(pTitle.isEmpty() != ![lTitle length] ||
![lTitle isEqualToString:[NSString stringWithUTF8String:pTitle.toCString(true)]]) {
f.tag()->setTitle(TagLib::String([lTitle UTF8String]));
altered = true;
}
if(pAlbumArtist.isEmpty() != ![lAlbumArtist length] ||
![lAlbumArtist isEqualToString:[NSString stringWithUTF8String:pAlbumArtist.toCString(true)]]) {
f.tag()->setAlbumArtist(TagLib::String([lAlbumArtist UTF8String]));
altered = true;
}
if(pArtist.isEmpty() != ![lArtist length] ||
![lArtist isEqualToString:[NSString stringWithUTF8String:pArtist.toCString(true)]]) {
f.tag()->setArtist(TagLib::String([lArtist UTF8String]));
altered = true;
}
if(pComposer.isEmpty() != ![lComposer length] ||
![lComposer isEqualToString:[NSString stringWithUTF8String:pComposer.toCString(true)]]) {
f.tag()->setComposer(TagLib::String([lComposer UTF8String]));
altered = true;
}
if(pAlbum.isEmpty() != ![lAlbum length] ||
![lAlbum isEqualToString:[NSString stringWithUTF8String:pAlbum.toCString(true)]]) {
f.tag()->setAlbum(TagLib::String([lComposer UTF8String]));
altered = true;
}
if(pUnsyncedLyrics.isEmpty() != ![lUnsyncedLyrics length] ||
![lUnsyncedLyrics isEqualToString:[NSString stringWithUTF8String:pUnsyncedLyrics.toCString(true)]]) {
f.tag()->setUnsyncedLyrics(TagLib::String([lUnsyncedLyrics UTF8String]));
altered = true;
}
if(pComment.isEmpty() != ![lComment length] ||
![lComment isEqualToString:[NSString stringWithUTF8String:pComment.toCString(true)]]) {
f.tag()->setComment(TagLib::String([lComment UTF8String]));
altered = true;
}
if(pGenre.isEmpty() != ![lGenre length] ||
![lGenre isEqualToString:[NSString stringWithUTF8String:pGenre.toCString(true)]]) {
f.tag()->setGenre(TagLib::String([lGenre UTF8String]));
altered = true;
}
if(pCuesheet.isEmpty() != ![lCuesheet length] ||
![lCuesheet isEqualToString:[NSString stringWithUTF8String:pCuesheet.toCString(true)]]) {
f.tag()->setCuesheet(TagLib::String([lCuesheet UTF8String]));
altered = true;
}
if(pYear != lYear) {
f.tag()->setYear(lYear);
altered = true;
}
if(pTrack != lTrack) {
f.tag()->setTrack(lTrack);
altered = true;
}
if(pDisc != lDisc) {
f.tag()->setDisc(lDisc);
altered = true;
}
if(pReplaygain != lReplaygain) {
f.tag()->setReplaygain(lReplaygain);
altered = true;
}
if(altered)
f.save();
}
}
} catch (std::exception &e) {
ALog(@"Exception caught writing with TagLib: %s", e.what());
return -1;
}
return 0;
}
@end