開源的.NET媒體文件操做組件TagLib#解析

  人生得意須盡歡 莫使金樽空對月。寫博客都會在吃飯後,每次吃飯都要喝上二兩小酒,寫博客前都要閒扯,這些都是我的愛好,改不掉了,看不慣的人,還望多多包含一下,有相同愛好的同窗,我們能夠一塊兒喝着小酒一邊吹牛逼。總有人跟我說要作正事,可是這個世界什麼叫作正事什麼叫作閒事呢?看法各不相同吧,我本身喜歡的在個人世界就是正事。git

   萬事急不得,須要等待時機和足夠的積累方可一舉成事。github

   接着前面的組件進行一個簡單的介紹,在寫博文以前,本身都會作一個簡單的瞭解和應用,畢竟利人必須先利己嘛。有時候沒有必要去寫一些簡單的demo,拿出來會佔用篇幅,在實際的項目中使用起來也不會是那麼順暢,只須要了解其原理和使用場景,在項目中都應該能夠很好的應用,真正好的代碼是須要通過實際的業務需求打磨和從實際的業務去修改和提煉。因此在這些博文中,會簡單的介紹背景、應用方法,以及組件的核心對象。真正深刻的瞭解,須要本身去學習。框架

   知識就是如此,站在前人的肩膀上去展望。有人發現了0和1,因此咱們現在不須要再去設計陰和陽作替代。那些所謂的項目中的乾貨,我只能說,項目千千萬,每個都有不一樣的需求和場景,若是要想都學完,那只是一些人拿來裝逼的笑話,只要把握核心原理,結合真實業務,以本身的思惟去整合,獲得的就是最合適的技術和框架。 函數

   前面扯淡半天,下面就直接進入正題。(若是有人有意見,我以爲沒有什麼不是一瓶酒解決不掉了,對我有意見,能夠約出來幹一架,也能夠喝一頓,我請...哈哈哈...)學習

一.TagLib#組件概述

   TagLib#用於處理媒體文件,例如視頻,音頻和照片等等,TagLib#採用LGPL和MPL兩種開源協議。TagLib#是用於讀取和編輯幾種流行音頻格式的元數據的庫。目前,它支持 MP3文件的ID3v1和ID3v2,FLAC,MPC,Speex,WavPack,TrueAudio,WAV,AIFF,MP4和ASF文件中的Ogg Vorbis註釋和ID3標籤和Vorbis註釋。ui

   該組件屬於比較老的一種了,在GitHub上一直都在更新修改。該庫由2001年開始建立,可是該庫一直有人在維護,須要使用到相關功能的同窗,能夠看看該組件。該組件的當前版本爲2.1 。該庫的地址:https://github.com/mono/taglib-sharp。spa

   TagLib#(又名taglib-sharp)是一個用於閱讀和寫做的庫媒體文件中的元數據,包括視頻,音頻和照片格式。設計

   這個玩意的文檔真是少,國內國外翻遍了,也沒找到多少,寫一篇不容易啊。code

   在這裏提供一個該庫的擴展:https://github.com/timheuer/taglib-sharp-portable,該擴展庫支持.NET Framework 4.5+,Windows 8+,Windows Phone 8.1,Windows Phone Silverlight 8,Xamarin.Android,Xamarin.iOS。orm

二.TagLib#組件應用

   上面介紹了組件的背景和簡單的敘述,下面就該介紹一下簡單的應用,畢竟沒法應用的組件,沒有介紹的意義。這裏若是須要編寫較爲通用的組件代碼,能夠本身根據項目需求進行總結,歡迎你們將本身的知識進行分享,分享本身的知識積累。

   1.解析照片

  public static TagLib.File ParsePhoto(string path)
        {
           if (string.IsNullOrEmpty(path))
           {
                throw new ArgumentNullException(path);
           }
           TagLib.File file;
            try
            {
                file = TagLib.File.Create(path);
            }
            catch (UnsupportedFormatException uex)
            {
                throw uex;
            }
            var image = file as TagLib.Image.File;
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
           return image;
        }

   2.從文件中加載圖片

public static void Main(string [] args)
    {
        if(args.Length < 2) {
            Console.Error.WriteLine("USAGE: mono SetPictures.exe AUDIO_PATH IMAGE_PATH_1[...IMAGE_PATH_N]");
            return;
        }    
        TagLib.File file = TagLib.File.Create(args[0]);
        Console.WriteLine("Current picture count: " + file.Tag.Pictures.Length);        
        Picture [] pictures = new Picture[args.Length - 1];   
        for(int i = 1; i < args.Length; i++) {
            Picture picture = new Picture(args[i]);
            pictures[i - 1] = picture;
        }        
        file.Tag.Pictures = pictures;
        file.Save();      
        Console.WriteLine("New picture count: " + file.Tag.Pictures.Length);
    }

   3.加載音頻文件

var tagFile = TagLib.File.Create("ironlionzion.mp3");
var tags = tagFile.GetTag(TagTypes.Id3v2);
string album = tags.Album;
string genre = "Hip-Hop, Rock"; 
var matchingFiles = Directory.GetFiles(@"Folder\SubFolder", "*.mp3", 
SearchOption.AllDirectories).Where(x => { var f = TagLib.File.Create(x);
return ((TagLib.Id3v2.Tag) f.GetTag(TagTypes.Id3v2)).JoinedGenres == genre; }); foreach (string f in matchingFiles) { System.IO.File.Move(f, Path.Combine(@"D:\NewFolder", new FileInfo(f).Name)); }

    4.執行Tag

 public byte[] ExecuteTagging(byte[] inputFile, string title, string artist, 
            string album, string comment, uint year, string copyright, byte[] image)
        {
            var stream = new MemoryStream();
            var writer = new BinaryWriter(stream);
            writer.Write(inputFile);
            using (var audioFile = TagLib.File.Create(new SimpleFileAbstraction(stream)))
            {
                audioFile.Tag.Title = title;
                audioFile.Tag.Performers = new[] { artist };
                audioFile.Tag.Album = album;
                audioFile.Tag.Comment = comment;
                audioFile.Tag.Genres = new[] { "Podcast" };
                audioFile.Tag.Year = year;
                audioFile.Tag.Copyright = copyright;
                audioFile.Tag.Pictures = new[] { new Picture(image) };
                audioFile.Save();
            }

            stream.Position = 0;
            using (var reader = new BinaryReader(stream))
            {
                return reader.ReadBytes((int)stream.Length);
            }
        }

三.TagLib#組件核心對象解析

    介紹完基本的用法,若是須要了解更多,能夠取GitHub自行下載查看源碼,有比較詳細的介紹,這裏就再也不作贅述,下面介紹一個該組件的一些核心對象。

  1.File.Create()

 public static File Create (IFileAbstraction abstraction,string mimetype,ReadStyle propertiesStyle)
        {
            if(mimetype == null) {
                string ext = String.Empty;                
                int index = abstraction.Name.LastIndexOf (".") + 1;            
                if(index >= 1 && index < abstraction.Name.Length)
                    ext = abstraction.Name.Substring (index,abstraction.Name.Length - index);              
                mimetype = "taglib/" + ext.ToLower(CultureInfo.InvariantCulture);
            }            
            foreach (FileTypeResolver resolver in file_type_resolvers) {
                File file = resolver(abstraction, mimetype,propertiesStyle);            
                if(file != null)return file;
            }        
            if (!FileTypes.AvailableTypes.ContainsKey(mimetype))
                throw new UnsupportedFormatException (
                    String.Format (CultureInfo.InvariantCulture,"{0} ({1})",abstraction.Name,mimetype));        
            Type file_type = FileTypes.AvailableTypes[mimetype];        
            try {
                File file = (File) Activator.CreateInstance(file_type,new object [] {abstraction, propertiesStyle});                
                file.MimeType = mimetype;
                return file;
            } catch (System.Reflection.TargetInvocationException e) {
                PrepareExceptionForRethrow(e.InnerException);
                throw e.InnerException;
            }
        }

    該方法用於建立一個File子類的新實例對於指定的文件抽象,mime類型和讀取風格。該方法存在6個重載,接受兩個參數,abstraction一個IFileAbstraction對象要使用的時候從當前實例讀取和寫入。mimetype包含mime類型的string對象在選擇要使用的適當類時使用,或langword =null若是擴展名name abstraction被使用。propertiesStyle一個ReadStyle值指定的級別從...閱讀媒體信息時使用的細節新實例。該方法返回一個File對象,一個新的實例File從中讀取指定抽象。Activator.CreateInstance()指定參數匹配程度最高的構造函數建立指定類型的實例。

   2.File.WriteBlock()

 public void WriteBlock (ByteVector data)
        {
            if (data == null)
                throw new ArgumentNullException ("data");            
            Mode = AccessMode.Write;            
            file_stream.Write (data.Data, 0, data.Count);
        }

    該方法將一個數據塊寫入該表明的文件當前實例在當前查找位置,參數data一個ByteVector包含數據的對象寫入當前實例。AccessMode是一個枚舉類型,指定當前文件訪問操做的類型容許在File的實例上。file_stream.Write (data.Data, 0, data.Count)向當前流中寫入字節序列,並將此流中的當前位置提高寫入的字節數。

四.總結

  技術沒有最好,只有最合適。不是你項目應用了當前最早進的技術,就說你的項目就是最早進的,只有你項目使用了最合適的技術,才能夠展示最富有生命力的一面。你在團隊寫出了你們都不熟悉的方式,即便再新潮,也未見得是最富有生命力的。

  寫代碼,且寫且珍惜。代碼是你思想的見證,也是你對生活的主張。

相關文章
相關標籤/搜索