关于fb2k专辑列表(Album List)分层tag的一些蛋疼小研究

专辑列表(foo_albumlist)是foobar2000原始携带的一个有关媒体库的扩展,用于将媒体库的歌曲以树状图的方式展示出来,便于挑选歌曲。对应的CUI版本是foo_uie_albumart。如图所示:

专辑列表的运作方式是,通过一系列的字段,将歌曲按照相应的tag、元数据等分割成不同的层次,形成一个树状图。下面是一个范例:

%<genre>%|[%album artist% – ]%album%|[[%discnumber%.]%tracknumber%. ][%track artist% – ]%title%

这是其自带的一个按流派分割的格式字符串。其中“|”分割了不同层次。而对于每一层次 只要某些歌曲的那些tag属性所形成的字符串一致,那么就会被分在一起。比如两首歌都具有JPOP的genre,那么他们将会分在同一个第一级;如果album artist和album都相同的话那么在第二级也会处于同一个分支中。

本次要研究的是其中一个很微小的问题。请看第一级:

%<genre>%

我们都知道%genre%表示歌曲tag中的genre属性即流派,那么这一对尖括号代表了什么呢?我曾试着将它改成%genre%,也没有发现有什么区别。但经过参阅一些文档,我基本搞清了其中的差别,故记录于此。

首先,其实可用的远不止%genre%和%<genre>%,而是有下面这么多种(为了便于说明remapping的概念,我改用artist来做例子):

%<artist>%
%artist%
$meta_branch(artist)
$meta_branch_remap(artist)
$meta(artist)

先从$meta(artist)说起,这个最简单,就是读取歌曲文件metatag中的“artist”字段,没有其他处理了。但是我们可以观察到,很多歌曲都有诸如album artist、track artist等一大串相似的字符串,有些时候可能一个歌曲只填写了album artist没写artist字段,但是很显然这里的album artist就是我们想要的,如果用$meta(artist)却只会读到?。为了解决这一问题,foobar中默认的字段读取时都有“remap”这一概念——就是依次读取多个字段以获得理想的值——

%artist% 艺术家名。依次检查下列元数据字段: “artist”, “album artist”, “composer”, “performer”。

上面这段是从titleformat_help里摘录的。所以,%artist%这种写法,实际上就相当于是$meta_remap(artist)(但是注意,这种写法实际并不存在)——除了一点点小区别,就是%artist%碰到没有值的情况下(由于有remap,所以即artist、album artist、composer以及performer这几个字段均没有值),会输出?号,也就是说它等价于$if2($meta_remap(artist),?);而上面列的那几个$meta_****(artist)系列都不会输出?值,这样意味着,对于一个没有任何艺术家信息的歌曲,那么在以类似$meta_branch(artist)这类字符串分层时,将会完全被忽略掉,而如果用的是%artist%,这类将会被统一分配到?中。

OK既然明白了remap,那么应该各位很快就会注意到另外一个词语——branch。没错,这也是本次的重点,也就是%<artist>%和%artist%的不同点所在。Branch,意为分割,分支,这里的意思是指,会将拥有多值的tag按每个值分开。相信很多人都没用过吧(包括我,这也是我为何一直没发现%<artists>%和%artist%区别的原因),foobar支持在一个字段中填入多个值(编辑的时候,用;分割),比如artist=artist1;artist2。而所谓branch,就是如果一个歌曲a有俩artist,那么在形成artist级时将会出现两个分支树一个是artist1一个是artist2,里面都含有歌曲a;如果没branch,那么将有一个分支树,名字叫做artist1, artist2,里面含有歌曲a。前者的优点显而易见——如果你有歌曲b的artist是artist2;artist3,那么将可以在artist2的分支里同时找到歌曲a和b。%<artist>%和%artist%的区别就是,前者带branch,后者不带;也就是说前者基本和$meta_branch_remap(artist)同义——依然除了一点,就是无值时的问题啦,所以准确地说,%<artist>%=%if2($meta_branch_remap(artist),?)。

OK既然搞清楚了这俩概念,那么上面那5个字符串的意思也就明了了:

%<artist>% – 按artist tag分类,含branch和remap,含空值处理
%artist% – 按artist tag分类,含remap,含空值处理
$meta_branch(artist) – 按artist tag分类,含branch
$meta_branch_remap(artist) – 按artist tag分类,含branch和remap
$meta(artist) – 仅按artist tag分类

我们来看个范例。

这里有5首歌。1有3个artist字段,2、5没有artist字段,3、4各有一个artist字段;1-3有album artist字段,4、5没有。

按%<artist>%分类——3、4分别分配到了对应的artist里,1同时出现在artist1、2、3中(branch),有album artist没有artist的2被分到了album artist的分支里(remap),而两者皆无的5被分到了?里。

按$meta_branch(artist)分类。3、4分别分配到了对应的artist里,1同时出现在artist1、2、3中。两个没有artist字段的歌曲2、5从其中消失了。

按$meta_branch_remap(artist)分类。3、4分别分配到了对应的artist里,1同时出现在artist1、2、3中,有album artist没有artist的2被分到了album artist的分支里,而由于不设空值分支,5依旧消失。

按%artist%分类。3、4分别分配到了对应的artist里,1被分配到了一个叫做“artist1, artist2, artist3”的分类中。5在?,2被remap到Album artist中。

按$meta(artist)分类。3、4分别分配到了对应的artist里,1被分配到了一个叫做“artist1, artist2, artist3”的分类中。没有remap也没有空值分支,那么2、5就只能继续玩消失。

看了这个范例,是不是很清楚了呢?不过需要补充几点:

1. 在同时有branch和remap的情况下($meta_branch_remap(artist)以及%<artist>%),remap过来的字段也会branch哦。即是说:如果一个歌曲没有artist字段但有两个album artist字段,那么将会被同时分支到album artist1和album artist2中。

2. 分支后面若有括号数字,是此分支下子分支的数量,并不是曲目数量哦(虽然很多时候是相等的)。

3. 一个很遗憾的消息——cuesheet并不支持字段多值。所以branch那些玩意玩无损的都玩不上。不得不说,无损音频+cue(无论是内嵌还是外挂)这种形式对于数据库整理实在太不方便,这不但体现在这里,还有插入专辑封面等一堆鸟事儿。

参考:

1. Foobar2000:Components/Facets (foo facets)
—因为Facets采用和album list一样的语法 故可参考其说明。
2. Foobar2000:Title Formatting Reference
3. Foobar2000:Titleformat Album List

Advertisements

一个有关“关于fb2k专辑列表(Album List)分层tag的一些蛋疼小研究”的想法

  1. 也就是说我们可写为
    %% – %artist_withBranch%
    %artist% – %artist%
    $meta_branch(artist) – $meta( artist_branch_noEmpty )
    $meta_branch_remap(artist) – %artist_branch_noEmpty%
    $meta(artist) – $meta(artist)

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s