使用第三方Java类库jaudiotagger完成Flac音频文件metadata(元数据)的读和修改

  最近须要使用Java Swing作个读写Flac格式音频文件的小GUI工具,虽然Mp3tag彻底能够完成Flac的读写(编辑)任务,可是为了简化工做流程(编辑Flac信息后调用其它系统的接口完成部分信息上传等功能),须要开发一个集成相似Mp3tag功能和额外功能于一体的小工具。html

  开发前的思考~~,“用JDK提供的IO(NIO)读写Flac?...”,“Flac的格式?...”,“一直潜心于JavaWeb和服务端接口开发...几乎没作过Java的GUI(Swing/AWT)!...”。。java

  后来,在网上Google了一下是否有第三方专门处理音频文件(包括MP三、ape等等)的Java类库可使用:结果用中文关键字检索很难找到满意的答案,最后在Stack Overflow搜索到一个标题为“Reading metadata from FLAC files with Java”的Answer中找到了答案“Try using JAudiotagger. It supports MP3, MP4, Ogg Vorbis, FLAC and WMA, and it has limited support for WAV and Real.”,接着,下载jar包,或者使用Maven构建工程的话,添加dependency便可。api

<dependency>
    <groupId>org</groupId>
    <artifactId>jaudiotagger</artifactId>
    <version>2.0.3</version>
</dependency>       

  其实,在读写Flac文件以前,仍是要先了解Flac是什么...Free Lossless Audio Codec-自由无损音频压缩编码...(貌似目前愈来愈流行无损音乐,不管是硬件播放器仍是音频的高保真文件格式,或者原本就流行,奈我从未发现~~app

  Wiki   官网   Flac的格式less

  而后就是查看JAudiotagger API,编写代码,就简单多了...maven

  此文不对Flac中的每个Tag信息进行英-中文对照说明,若是在音乐技术方面有深刻研究的朋友能够私下交流沟通或有更好的网站方便提供一下,不胜感激~~PS:能够根据Tag映射中的英文key与Mp3tag中文版对照,或许能够找到答案。。。工具

  下面说明一下读取和写入(编辑)Tag信息的通常步骤及可能出现的困惑或卡壳(Stuck):测试

  1,阅JAudiotagger API知,使用FlacFileReader对象的read方法读取一个Flac文件,返回一个AudioFile(接口)类型的对象(实现了该接口的类的实例),再经过AudioFile中的方法getAudioHeadergetTag分别得到AudioHeader(接口)类型的对象和FlacTag类(实现了Tag接口)的对象。网站

  2, 利用得到的AudioHeader和FlacTag的对象便可得到想要的元数据(Metadata)信息,包括采样率(SampleRate)、制做格式或制做技术(Format)、单曲名(TITLE)、单曲艺术家(ARTIST)、专辑名(ALBUM)、专辑艺术家(ALBUM_ARTIST)、音轨号(TRACK)、语言(LANGUAGE)、版权方(COPYRIGHT)等等,使用FlacTag对象的getFirstArtwork方法能够得到图片。编码

  3,关于FlacTag中的Tag信息的Key值,有三种状况,一个是枚举FieldKey中的Key,另外一个是FieldKey中没有的可是Tag映射表中有的Key;在读取Key对应的value值时,有两个重载的方法:getFirst(FieldKey id) 和getFirst(java.lang.String id),后面的方法包含了Tag映射中全部的key,固然也包括FieldKey枚举中的Key;最后一个就是Tag映射表中没有的,也就是自定义的key。

  获取单曲名称时,两个方法均可以,以下:

tag.getFirst("TITLE")
tag.getFirst(FieldKey.TITLE)

  可是获取版权方Copyright(flac中对应的key是COPYRIGHT,能够从Tag映射表中查到),可是FieldKey的枚举中没有(这个能够经过修改JAudiotagger源代码在枚举里面加上须要的key,不过彻底不必,JAudiotagger也只是把主要的可能比较重要比较经常使用的、通常Flac文件中都有的key放到枚举里面,经过重载的方法只要传入key的字符串id参数便可),像Copyright只好使用tag.getFirst("COPYRIGHT")方法读取版权信息。

 4,在修改Tag信息时,也是有两个方法, 和 ,缘由同3,像Copyright这样的Tag信息只好使用tag.setField("COPYRIGHT", "XX唱片公司");了。setField(FieldKey genericKey, java.lang.String value)setField(java.lang.String vorbisCommentKey, java.lang.String value)
 修改单曲名时,两个方法均可以,以下:
tag.setField(FieldKey.TITLE, "让一切随风");
tag.setField("TITLE", "让一切随风");

  仔细一点会从API发现FlacTag对象有以下方法(判读一个Tag的key是否存在):

tag.hasField("COPYRIGHT")

  若是返回true,则读取时可能有版权信息,由于有可能只是在Flac文件中加了COPYRIGHT却没有设置值,没有值则返回"",不返回null;若是返回false,显然Flac文件中尚未COPYRIGHT;不管hasField方法返回的是true仍是false,只要被判断的key在Tag映射表存在,均可以直接调用tag.setField("COPYRIGHT", "XX唱片公司");方法为COPYRIGHT或者其它key设置值。

  5,3和4中讨论的Tag(FlacTag)信息中的key都是Tag映射中有的Key,若是想要自定义一个key,并为自定义的key设置值,且在下次读取该Flac文件时能够读出这个自定义key的值,就须要另外的方法addField(java.lang.String vorbisCommentKey, java.lang.String value) ,例如自定义一个假设叫作ISTEST的key,以下:

tag.addField("ISTEST", "true");

  6, 再仔细一点就会发现,还有一个addField的重载方法,addField(FieldKey genericKey, java.lang.String value) ,这是什么意思呢?若是执行

tag.addField("COPYRIGHT")又会怎样呢?蛮奇怪的,为何读取Tag信息的时候是getFirst方法?为何有个First呢?
  假设Flac文件中已经有TITLE和COPYRIGHT,而后再执行下面两条语句:
tag.addField(FieldKey.TITLE,"让一切随心");
tag.addField("COPYRIGHT","YY唱片公司");
经过调用tag.getVorbisCommentTag()方法,观察一下OGG Tag content的内容以下:

  若是分别调用getFirst方法去获取TITLE和COPYRIGHT的值,显然分别是“让一切随风”和“XX唱片公司”。

  7,4中所言能够为Tag映射表中存在的key,即便Flac文件中没有,也能够经过setField方法设置值,那么自定义的key可不能够呢?答案是确定的,便可以使用setField为Flac文件添加一个自定义的Tag信息。

  经过API和代码测试,addField和setField的区别固然也很容易就会想到,addField会不断的create,而setField只在第一次设置值时发现key不存在才会create并设置值,不然只是改变value的值。

   8, 删除Tag信息,直接删除key便可,方法deleteField(FieldKey fieldKey) 和deleteField(java.lang.String id) ,这两个方法均会删除6中所add的全部相同key的Tag信息,表现就是删除后调用hasField方法返回false。

   9, API中还有createField以及对图片的获取、图片信息的添加修改如setField(Artwork artwork) 等,暂不叙述。

  10, 关于Tag信息修改后的保存到flac文件中去:在Tag信息经过setField方法修改后,使用FlacFileWriter对象的write方法将读出来的AudioFile对象“写回去”便可(flac文件只会改变set的key-value或者添加一个新的key或者删除相同的某个key及对应value,其它的信息不会丢失)。

相关文章
相关标签/搜索