NET媒体文件操作组件TagLib

开源的.NET媒体文件操作组件TagLib#解析

人生得意须尽欢 莫使金樽空对月。写博客都会在吃饭后,每次吃饭都要喝上二两小酒,写博客前都要闲扯,这些都是个人爱好,改不掉了,看不惯的人,还望多多包含一下,有相同爱好的同学,咱们可以一起喝着小酒一边吹牛逼。总有人跟我说要做正事,但是这个世界什么叫做正事什么叫做闲事呢?见解各不相同吧,我自己喜欢的在我的世界就是正事。

万事急不得,需要等待时机和足够的积累方可一举成事。

接着前面的组件进行一个简单的介绍,在写博文之前,自己都会做一个简单的了解和应用,毕竟利人必须先利己嘛。有时候没有必要去写一些简单的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注释。

该组件属于比较老的一种了,在GitHub上一直都在更新修改。该库由2001年开始创建,但是该库一直有人在维护,需要使用到相关功能的同学,可以看看该组件。该组件的当前版本为2.1 。该库的地址:https://github.com/mono/taglib-sharp。

TagLib#(又名taglib-sharp)是一个用于阅读和写作的库媒体文件中的元数据,包括视频,音频和照片格式。

这个玩意的文档真是少,国内国外翻遍了,也没找到多少,写一篇不容易啊。

在这里提供一个该库的扩展: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。

二.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)向当前流中写入字节序列,并将此流中的当前位置提升写入的字节数。

四.总结

技术没有最好,只有最合适。不是你项目应用了当前最先进的技术,就说你的项目就是最先进的,只有你项目使用了最合适的技术,才可以展现最富有生命力的一面。你在团队写出了大家都不熟悉的方式,即使再新潮,也未见得是最富有生命力的。

时间: 2024-10-21 15:49:04

NET媒体文件操作组件TagLib的相关文章

ATL使用.rgs注册脚本文件操作注册表注册Com组件

1.      ATL注册组件 1.1     创建注册脚本 注册脚本通过操作 系统注册表完成Com服务的注册,通过数字形式而非代码API的形式完成,这种形式显得更加简单有效,因为它只需要几行数字代码就可以将一个Key添加到注册表中. 使用ATL向导时,会自动的生成一个后缀为.rgs的注册脚本文件,ATL在服务安装时,会自动的调用脚本文件,实现对注册表的修改,完成Com服务的注册. 1.1.1       基本术语 符号释义 符号 解释 ::= 相等 | 或 X+ 一个或多个Xs [X] X是可

Java文件操作系列[2]——使用JXL操作Excel文件

由于java流无法实现对Excel文件的读写操作,因此在项目中经常利用第三方开源的组件来实现.支持Excel文件操作的第三方开源组件主要有Apache的POI和开源社区的JXL. 总体来说,二者的区别是:JXL较为轻量级,如果是对Excel文件的简单操作,建议使用JXL:POI的功能相当强大,但同时处理问题也相当的繁琐. 1.准备工作 [必需]下载JXL的jar包:jxl.jar [非必需]JXL API  (提取密码:zgqj) 2.一些必要的说明 主要是对Excel结构的说明: Excel后

微信企业号上传媒体文件之服务器文件上传

微信企业号上传媒体文件之服务器文件上传 企业在使用接口时,对多媒体文件.多媒体消息的获取和调用等操作,是通过media_id来进行的. 通过接口https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE,企业可以上传多媒体文件. 注意,每个多媒体文件(media_id)会在上传到微信服务器3天后自动删除,以节省服务器资源. 通常文件上传是通过html表单进行的,通过HttpURLConn

DotNet二维码操作组件ThoughtWorks.QRCode

DotNet二维码操作组件ThoughtWorks.QRCode 在生活中有一种东西几乎已经快要成为我们的另一个电子"身份证",那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) ,又称二维条码,是在一维条码的基础上扩展出的一种具有可读性的条码.设备扫描二维条码,通过识别条码的长度和宽度中所记载的二进制数据,可获取其中所包含的信息.相比一维条码,二维码记载更复杂的数据,比如图片.网络链接等. 今天介绍一

Win8.1应用开发之文件操作

在操作文件之前,先相应用的应用功能声明进行设定.用户通过C#(非UI)对win8.1上的文件进行訪问,仅仅能局限于图片,音乐,视频和文档四个目录. 而通过文件选取器则能訪问到整个系统的文件. (一)应用功能声明 对于win8应用商店应用,打开Package.appxmanifest文件.点击"功能"选项卡,勾选"音乐库","图片库"和"视频库",这样你就能够通过代码对这里面的文件和目录进行操作: 音乐 musicLibrary

Java文件操作源码大全

1.创建文件夹 52.创建文件 53.删除文件 54.删除文件夹 65.删除一个文件下夹所有的文件夹 76.清空文件夹 87.读取文件 88.写入文件 99.写入随机文件 910.读取文件属性 911.写入属性 1012.枚举一个文件夹中的所有文件 1013.复制文件夹 1114.复制一个目录下所有的文件夹到另一个文件夹下 1215.移动文件夹 1316.移动一个目录下所有的文件夹到另一个目录下 1517.以一个文件夹的框架在另一个目录创建文件夹和空文件 1618.复制文件 1719.复制一个目

C++ 写文件操作

亲爱的网友,我这里有套课程想和大家分享,如果对这个课程有兴趣的,可以加我的QQ2059055336和我联系. 课程内容简介 我们软件是基于移动设备的.所以我们必然的选择了安卓作为我们的开发工具.课程中,我们将简要的介绍Android的基本概念,然后进行我们的实战开发.在开发中,大家讲学习到基本的组件,适配UI,数据的存储,多线程下载,开机广播,闹钟提醒,短信发送等实际项目开发中碰到的有用的知识点.通过课程学习,让大家能够掌握Android软件开发的流程,注意点,及优化.帮助大家迅速的掌握Andr

微信企业号上传媒体文件之本地文件上传

微信企业号上传媒体文件之本地文件上传 企业在使用接口时,对多媒体文件.多媒体消息的获取和调用等操作,是通过media_id来进行的. 通过接口https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE,企业可以上传多媒体文件. 注意,每个多媒体文件(media_id)会在上传到微信服务器3天后自动删除,以节省服务器资源. 通常文件上传是通过html表单进行的,通过HttpURLConne

SSIS 自测题-文件操作类

说明:以下是自己的理解答案,不是标准的答案,如有不妥烦请指出.         有些题目暂时没有答案,有知道的请留言,互相学习,一起进步. 1.什么是控制流,什么是数据流,控制流和数据流之间的关系是什么?    控制流:对执行流程中任务的控制     数据流:主要是用来定义数据从源到目标的过程,中间包含数据的转换,查找,分类等等.     每个控制流中包含多个数据流.2.Connection Manager 连接管理器的作用是什么?不同的数据流组件可以使用同一个 Connection Manag