Search code examples
c#.netmetadataitunestaglib-sharp

Setting Explicit tag for Apple .m4a file with TagLib#


I'm using this method to add the ITUNESADVISORY tag:

static void SetExplicit(string file)
{
    var f = TagLib.File.Create(file);
    TagLib.Mpeg4.AppleTag customTag = (TagLib.Mpeg4.AppleTag)f.GetTag(TagLib.TagTypes.Apple, true);
    var vector = new TagLib.ByteVector();
    vector.Add((byte)1);
    customTag.SetData("ITUNESADVISORY", vector, (int)TagLib.Mpeg4.AppleDataBox.FlagType.ContainsData);
    f.Save();
}

Except it doesn't work. It throws and exception (type cannot be null) on the SetData(type, vector, flags) line. Do I need to somehow add the DataBox first, or something?

Thanks!


Solution

  • The type parameter of customTag.SetData() must be exactly 4 bytes, since it is used as the BoxType property for the TagLib.Mpeg4.AppleTag object that holds the tag data. The ITUNESADVISORY tag is actually identified using a BoxType containing {114, 116, 110, 103}, which translates into a string value of rtng.

    static void SetExplicit(string file)
    {
        var f = TagLib.File.Create(file);
        TagLib.Mpeg4.AppleTag customTag = (TagLib.Mpeg4.AppleTag)f.GetTag(TagLib.TagTypes.Apple, true);
        var vector = new TagLib.ByteVector();
        vector.Add((byte)1);
        customTag.SetData("rtng", vector, (int)TagLib.Mpeg4.AppleDataBox.FlagType.ContainsData);
        f.Save();
    }
    

    Note: By default, the Taglib.ByteVector methods create a 4-byte array, however, the data value of the rtng tag must contain only a single byte value.

    Valid values of the rtng tag are:

    • 0 - No Rating (Content was never explicit to begin with).
    • 1 - Explicit (Content contains offensive language).
    • 2 - Clean (Content has been sanitized of offensive language).

    Alternate Code Example

    I rewrote your sample code in a way which was easier for me to read at a glance. I am a beginning programmer, so I may have violated some de facto standards. I also changed the names of most of the variables to better reflect what they actually contain. For instance, the tags variable you called customTag holds nearly all of the tag and song data; it is not just the single tag you are trying to create or edit. Hopefully this helps some newbies like me.

    static void SetExplicit(string file)
    {
        var f = TagLib.File.Create(file);
    
        var tags = (TagLib.Mpeg4.AppleTag) f.GetTag(TagLib.TagTypes.Apple);
    
        TagLib.ByteVector customTagName = "rtng";
        TagLib.ByteVector customTagData = new byte[] { 1 };
        var customTagFlag = (UInt32)TagLib.Mpeg4.AppleDataBox.FlagType.ContainsData;
    
        tags.SetData(customTagName, customTagData, customTagFlag);
    
        f.Save();
    }