Novell Home

TagLib Sharp: Examples

From Developer Community

Contents

TagLib# has a new home! Visit http://www.taglib-sharp.com/Main_Page to get the latest release!

The Most Basic Example (AKA, all you'll ever need)


99% of what you're going to want to do is in this example. This shows the basic reading and writing of a file with TagLib#.

try
{
   TagLib.File file = TagLib.File.Create ("/path/to/music/file.mp3");
   
   // Read some information.
   string    title   = file.Tag.Title;
   uint      track   = file.Tag.Track;
   string    album   = file.Tag.Album;
   string [] artists = file.Tag.Artists; // Remember, each song can have more than one artist.
   
   ... // Do stuff to title, album, artists.
   
   // Store that information in the tag.
   file.Tag.Title   = title;
   file.Tag.Track   = track;
   file.Tag.Album   = album;
   file.Tag.Artists = artists;
   
   file.Save ();
}
catch {...}

Getting Picture Data

Most tag formats support embedded images and TagLib# makes it incredably simple to access them:

try
{
   TagLib.File file = TagLib.File.Create ("/path/to/music/file.mp3");
   
   foreach (TagLib.IPicture pic in file.Tag.Pictures)
   {
      ... // Do something fancy with the pictures!
   }
}
catch {...}

Accessing Hidden Gems

More advanced features can be accessed by using TagLib.File.GetTag (TagLib.TagTypes) to get a specific tag type and using it's special features.

Reading and Writing Special Text Fields

Below is some code (from MuineTagger) that will get and set a specified text field from any tag type. This is useful for accessing less common features like "Moods" or "Disc Name".

public static string [] GetTextField (TagLib.File file, 
  TagLib.ByteVector apple_name, TagLib.ByteVector id3v2_name, 
  string xiph_name, string ape_name)
{
   TagLib.Mpeg4.AppleTag  apple = (TagLib.Mpeg4.AppleTag)  file.GetTag (TagLib.TagTypes.Apple);
   TagLib.Id3v2.Tag       id3v2 = (TagLib.Id3v2.Tag)       file.GetTag (TagLib.TagTypes.Id3v2);
   TagLib.Ogg.XiphComment xiph  = (TagLib.Ogg.XiphComment) file.GetTag (TagLib.TagTypes.Xiph);
   TagLib.Ape.Tag         ape   = (TagLib.Ape.Tag)         file.GetTag (TagLib.TagTypes.Ape);
     
   if (apple != null)
   {
      string [] text = apple.GetText (apple_name);
      if (text.Length != 0)
         return text;
   }
        
   if (id3v2 != null)
      foreach (TagLib.Id3v2.TextIdentificationFrame f in id3v2.GetFrames (id3v2_name))
         return f.FieldList.ToArray ();
    
   if (xiph != null)
   {
      TagLib.StringList l = xiph.GetField (xiph_name);
      if (l != null && l.Count != 0)
         return l.ToArray ();
   }
        
   if (ape != null)
   {
      TagLib.Ape.Item item = ape.GetItem (ape_name);
      if (item != null)
         return item.ToStringArray ();
   }
   
   return new string [] {};
}
     
public static void SetTextField (TagLib.File file, 
   TagLib.ByteVector apple_name, TagLib.ByteVector id3v2_name, 
   string xiph_name, string ape_name, string [] values)
{
   TagLib.Mpeg4.AppleTag  apple = (TagLib.Mpeg4.AppleTag)  file.GetTag (TagLib.TagTypes.Apple, true);
   TagLib.Id3v2.Tag       id3v2 = (TagLib.Id3v2.Tag)       file.GetTag (TagLib.TagTypes.Id3v2, true);
   TagLib.Ogg.XiphComment xiph  = (TagLib.Ogg.XiphComment) file.GetTag (TagLib.TagTypes.Xiph,  true);
   TagLib.Ape.Tag         ape   = (TagLib.Ape.Tag)         file.GetTag (TagLib.TagTypes.Ape,   (file is TagLib.Mpc.File));
        
   if (apple != null)
      apple.SetText (apple_name, values);
        
   if (id3v2 != null)
      id3v2.SetTextFrame (id3v2_name, new TagLib.StringList (values));
   
   if (xiph != null)
      xiph.AddFields (xiph_name, values);
   
   if (ape != null)
      ape.AddValues (ape_name, values, true);
}

...

string [] moods = GetTextField (file, "mood", "TMOO", "MOOD", "MOOD");

...

SetTextFields (file, "mood", "TMOO", "MOOD", "MOOD", moods);


Setting Up Your Own File Type Resolver

The first thing you need to set up a file type resolver is a class that extends TagLib.File. This could be one provided by the TagLib# library or one you create yourself. You would most likely use the former if you were using more sophistocated method for reading mime types than file extentions (say Gnome.VFS).

The below example creates two file type resolvers, one for FooFile and the other for BarFile. What a file type resolver does is simply check whether the file at path is is of the right type and send the arguments into the proper constructor, returning null if not found. In order for TagLib# to work with these files, they need to be added to TagLib.File's internal list. This is done through TagLib.File.AddFileTypeResolver (MyResolver);. This line needs to be placed in the code before any call is made to TagLib.File.Create (...), preferably in Main or a similar function.

TagLib.File FooResolver (string path, TagLib.AudioProperties.ReadStyle style)
{
   if (/* is foo type */)
      return new FooFile (path, style);
   return null;
}

TagLib.File BarResolver (string path, TagLib.AudioProperties.ReadStyle style)
{
   if (/* is bar type */)
      return new BarFile (path, style);
   return null;
}

...

TagLib.File.AddFileTypeResolver (BarResolver);
TagLib.File.AddFileTypeResolver (FooResolver); // Foo resolver will be called first.

Special attention should be made to the fact that resolvers are called in the opposite order of which they are added. This is so that if library x creates a resolver and subsequent library y wants to make a better one, the one by y will be called first.

If you're resolving muliple types, there is no reason why you couldn't combine your resolvers into a single function. The below code will behave identically to the example above.

TagLib.File FooBarResolver (string path, bool read_properties, TagLib.AudioProperties.ReadStyle style)
{
   if (/* is foo type */)
      return new FooFile (path, read_properties, style);
   if (/* is bar type */)
      return new BarFile (path, read_properties, style);
   return null;
}

...

TagLib.File.AddFileTypeResolver (FooBarResolver);


Reading From The Web or Anywhere

Reading a file from some abitrary file system is simple with TagLib#. The below example shows how to read from Gnome.Vfs.

public class VfsFileAbstraction : TagLib.File.IFileAbstraction
{
   private string name;
   private FilePermissions permissions;
   
   public VfsFileAbstraction (string file)
   {
      name = file;
      
      permissions = (new FileInfo (name, FileInfoOptions.FollowLinks | FileInfoOptions.GetAccessRights)).Permissions;
      
      if (!IsReadable)
         throw new System.Exception ("File is not readable.");
   }
   
   public string Name {get {return name;}}
   
   public System.IO.Stream ReadStream
   {
      get {return new VfsStream (Name, System.IO.FileMode.Open);}
   }
   
   public System.IO.Stream WriteStream
   {
      get {return new VfsStream (Name, System.IO.FileMode.Open);}
   }
            
   public bool IsReadable
   {
      get {return (permissions | FilePermissions.AccessReadable) != 0;}
   }
   
   public bool IsWritable
   {
      get {return (permissions | FilePermissions.AccessWritable) != 0;}
   }
   
   public static TagLib.File.IFileAbstraction CreateFile (string path)
   {
      return new VfsFileAbstraction (path);
   }
}

...

Gnome.Vfs.Vfs.Initialize ();
TagLib.File.SetFileAbstractionCreator (new TagLib.File.FileAbstractionCreator (VfsFileAbstraction.CreateFile));

TagLib.File file = TagLib.File.Create ("smb://WindowsShare/Music/Devil%20Went%20Down%20To%20Georgia.mp3");

// normal tagging operations

Gnome.Vfs.Vfs.Shutdown ();

Using TagLib# in Other Languages

There's no real reason for this, I just think it's fun.

Nemerle

$ nemish
Welcome to Nemerle interpreter (using ncc 0.9.2.0).

Please enter expressions appended with ";;".
Type "Help;;" for more info.

Please wait while evaluating the config file..
- Ref = "/usr/lib/mono/taglib-sharp/taglib-sharp.dll";;
def it : void 
- def file= TagLib.File.Create ("/media/shared/Music/Bon Jovi/Slippery When Wet/03 - Livin' on  a Prayer.mp3");;
def file = TagLib.Mpeg.File : TagLib.File
def it : void 
- file.Tag.Title;;
def it = Livin' on  a Prayer : System.String
- file.Tag.Album;;
def it = Slippery When Wet : System.String
- System.String.Join (", ", file.Tag.AlbumArtists);;
def it = Bon Jovi : System.String
- System.String.Join (", ", file.Tag.Genres);;
def it =  : System.String
- file.Tag.Year;;                             
def it = 1986 : System.UInt32
- file.Tag.Track.ToString () + "/" + file.Tag.TrackCount.ToString ();;
def it = 3/10 : System.String
-

Novell® Making IT Work As One

© 2008 Novell, Inc. All Rights Reserved.