抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

CUE 文件,即 CUESheets ,光盘镜像辅助文件。通常用于光盘刻录、音乐播放等等。

比如用 EAC 刻录CD光盘,或者用 Foobar2000 播放整轨音乐文件。

CUE 文件是非常好的音乐专辑信息载体,使用它可以使专辑信息和音乐文件分离,从而达到播放整轨 WAV、FLAC、APE 等文件的目的。

由于篇幅有限,本文只描述音乐文件播放相关的内容,因此和刻录有关的信息可能不大详细,敬请原谅。

本文档分为三部分:

  一、CUE 基本规范

  二、CUE 命令参考

  三、范例解析

=====================================================

一、CUE 基本规范

  1、CUE 是使用 ANSI 编码文本 格式储存的,以 .cue 为后缀储存的文件。

  2、其内容分为 Header 文件头,和 Tracks-Info 数据轨描述表两部分。其中 Header 文件头是可选的。

  3、CUE 文件必须与文件内描述的数据文件位于同一目录下。(FLAC 音频文件可以内嵌 CUE 文件)

  4、CUE 文件的修改与数据文件无关,因而 CUE 文件的丢失对数据文件无实质影响。

=====================================================

二、CUE 命令参考

  首先我们来看看 Header 文件头,其常见格式如下:(文件头是可选的,其全部内容都不是必须的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TITLE <cd-title>

PERFORMER <performer-name>

SONGWRITER <writer-name>

CATALOG <catalog-id>

REM DATE <date>

REM DISCID <discid-id>

REM GENRE <classes>

REM COMMENT <comments>

CDTEXTFILE <cd-text-file-name>

这里出现了如下命令:(也许你发现了,这些命令全部用大写,其实大小写没关系,但是为了格式化,所以命令再次统一用大写的)

   TITLE、CATALOG、SONGWRITER、PERFORMER、REM、CDTEXTFILE

下面我们对上面的命令逐行分析,记住 头部信息全部都是可有可无的,当然有就最好不过了。

-———————————————————-

TITLE 命令(头部)

  这条命令很明显,指定唱片标题。格式为:

  TITLE </em></p> <p>  比如MJ的专辑《Thriller》</p> <p>TITLE “Thriller”</p> <p>  注意:</p> <p>  1、<title>必须小于80个字符。</p> <p>  2、对于长且有空格的名称,必须用<strong>半角双引号</strong>引起来。这里建议在任何情况下都把<title>用双引号引起来。</p> <p>  3、刻录时,如果刻录机不支持 CD-TEXT,则此命令将被忽略。但是在播放器里是有效的。</p> <p>-———————————————————-</p> <p><strong>PERFORMER 命令(头部)</strong></p> <p>  这条命令也很简单,指定唱片演唱者。格式为:</p> <p>  <em>PERFORMER <performer-name></em></p> <p>  比如MJ的专辑《Thriller》</p> <p>PERFORMER “Michelle Jackson”</p> <p>  注意:</p> <p>  1、<performer-name>必须小于80个字符。</p> <p>  2、对于长且有空格的名称,必须用<strong>半角双引号</strong>引起来。这里建议在任何情况下都把<performer-name>用双引号引起来。</p> <p>  3、刻录时,如果刻录机不支持 CD-TEXT,则此命令将被忽略。但是在播放器里是有效的。</p> <p>-———————————————————-</p> <p><strong>SONGWRITER 命令(头部)</strong></p> <p>  这条命令也很简单,指定唱片乐曲编曲者。格式为:</p> <p>  <em>SONGWRITER <writer-name></em></p> <p>  比如冯曦妤的歌曲《幸运儿》</p> <p>SONGWRITER “冯曦妤”</p> <p>  注意:</p> <p>  1、<writer-name>必须小于80个字符。</p> <p>  2、对于长且有空格的名称,必须用<strong>半角双引号</strong>引起来。这里建议在任何情况下都把<writer-name>用双引号引起来。</p> <p>  3、刻录时,如果刻录机不支持 CD-TEXT,则此命令将被忽略。但是在播放器里是有效的。</p> <p>-———————————————————-</p> <p><strong>REM 命令(头部)</strong></p> <p>  这条命令表示注释,通常用来标明一些 CUE 阅读说明。格式为:</p> <p>  <em>REM <comments></em></p> <p>  比如</p> <p>REM 这是说明哦。</p> <p>  但是 REM 命令通常不会被这么使用,因为 CUE 文件格式简单,不需要写什么注释。于是 REM 就被用来指定各种 CUE 的扩展命令,这些扩展命令一般也是用于头部信息(音轨信息部分也有,后面会提到),一般作用于 Foobar2000 等音乐播放器。下面将逐个说明:</p> <table> <thead> <tr> <th>指令</th> <th>说明</th> <th>示例</th> </tr> </thead> <tbody><tr> <td><em>REM GENRE <class-names></em></td> <td>用于指定唱片、专辑的分类,建议后面的 <class-names> 用<strong>半角双引号</strong>引起来。</td> <td>贝多芬精选集里其中一张 CD:<br/><code>REM GENRE "Classical"</code></td> </tr> <tr> <td><em>REM DISCID <cd-id></em></td> <td>用于指定 CD 的唯一编号,建议后面的 <cd-id> 用<strong>半角双引号</strong>引起来。</td> <td>贝多芬精选集里其中一张 CD:<br/><code>REM DISCID "5C0D6808"</code></td> </tr> <tr> <td><em>REM DATE <date></em></td> <td>用于指定光盘的发行时间,精确到年。其中<date>可以用<strong>半角双引号</strong>引起来。</td> <td>一张 2009 年发布的 CD:<br/><code>REM DATE 2009</code></td> </tr> <tr> <td>*REM COMMENT <comment-string></td> <td>用于指定 CUE 的生成说明,建议后面的 <comment-string> 用<strong>半角双引号</strong>引起来。</td> <td>使用 EAC 生成的 CUE 文件一般都带如下类似信息:<br/><code>REM COMMENT "ExactAudioCopy v0.99pb4"</code></td> </tr> </tbody></table> <p>-———————————————————-</p> <p><strong>CATALOG 命令</strong></p> <p>  这条命令用于指定唱片的唯一 EAN 编号。格式为:</p> <p>    <em>CATALOG <catalog-id></em></p> <p>  比如 George Michael 的专辑 《Songs From The Last Century》。</p> <p>    CATALOG “7243848740251”</p> <p>  这是个比较重要的玩意儿,它表示这张唱片的身份证,是一个 13 位的数字,通常和唱片的 EAN 码一致。也就是说,这张唱片的唯一编号。世界上不会有两张唱片的 CATALOG 相同的。关于这个 CATALOG 码,要了解更多请参考<a target="_blank" rel="noopener" href="http://baike.baidu.com/link?url=NZrXfTVI8iiVoGLiU9wjdIc2PQgWBch9Rzbh5PT4nXdghRtgAR0zXxyPuEnkyBvnhwOaXzWmuteiZg2gzhI1Xq">百度百科</a>。</p> <p>  注意:</p> <p>  1、<catalog-id> 必须为13个字符。</p> <p>  2、这里建议把 <catalog-id> 用<strong>半角双引号</strong>引起来。</p> <p>  3、注意本命令最多只能在 CUE 文件内出现一次,可以没有。通常位于头部。</p> <p>-———————————————————-</p> <p><strong>CDTEXTFILE 命令</strong></p> <p>  这条命令用于指定光盘上使用的 CD-TEXT 信息文件的名称,具体用途不在此说明,需要的请自行查阅相关文献。格式为:</p> <p>    <em>CDTEXTFILE <cd-text-filename></em></p> <p>  比如</p> <p>    CDTEXTFILE “cd-text1.cdt”</p> <p>    CDTEXTFILE “c:\cds\cd-text2.cdt”</p> <p>  注意:</p> <p>    1、<cd-text-filename> 可以是文件名,也可以包含文件路径。</p> <p>    2、如果 <cd-text-filename> 内包含空格,那么必须用<strong>半角双引号</strong>引起来。这里建议总是把 <cd-text-filename> 用<strong>半角双引号</strong>引起来。</p> <p>    3、如果刻录机不支持 CD-TEXT,那么此命令将被忽略。</p> <p>-———————————————————-</p> <p>  至此,头部信息文件介绍完毕。下面开始介绍数据轨描述表部分。</p> <p>  数据轨描述表分为两部分:</p> <p>    一、核心部分,即下面格式中未被[]包含的内容,这一部分是必须存在的;</p> <p>    二、单轨描述信息,即下面格式中被[]包含的部分。</p> <p>  数据轨描述表的格式如下:(注意[]不是内容,只是表示其里面的内容为可选</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">FILE <data-file-name> <file-type></span><br><span class="line"></span><br><span class="line"> TRACK <track-id> <track-data-type></span><br><span class="line"></span><br><span class="line">INDEX 01 <track-begin-time></span><br><span class="line"></span><br><span class="line"> [TITLE <track-title>]</span><br><span class="line"></span><br><span class="line"> [PERFORMER <performer-name>]</span><br><span class="line"></span><br><span class="line"> [SONGWRITER <writer-name>]</span><br><span class="line"></span><br><span class="line"> [ISRC <isrc-code>]</span><br><span class="line"></span><br><span class="line"> [FLAGS <flags>]</span><br><span class="line"></span><br><span class="line"> [PREGAP <pre-mute-time>]</span><br><span class="line"></span><br><span class="line"> [POSTGAP <post-mute-time>]</span><br><span class="line"></span><br><span class="line"> [REM REPLAYGAIN_TRACK_GAIN +/- *.** dB]</span><br><span class="line"></span><br><span class="line">[REM REPLAYGAIN_TRACK_PEAK *.******]</span><br><span class="line"></span><br><span class="line"> [INDEX <index> <track-begin-time>]</span><br></pre></td></tr></table></figure> <p>  数据信息描述表格式如上所示,其中 FILE 命令可以有多条,而每条 FILE 命令下又可以有多条 TRACK 命令。下面介绍各条命令。</p> <p>-———————————————————-</p> <p><strong>FILE 命令</strong></p> <p>  这条命令用于声明一个数据文件。格式为:</p> <p>  <em>FILE <data-file-name> <file-type></em></p> <p>  其中 <data-file-name> 是位于 CUE 文件 相同目录下的数据文件名称。<file-type> 为文件的数据类型:</p> <table> <thead> <tr> <th><file-type></th> <th>说明</th> </tr> </thead> <tbody><tr> <td>BINARY</td> <td>二进制数据文件,必须是 Little-Endian 编码格式。</td> </tr> <tr> <td>MOTOROLA</td> <td>二进制数据文件,必须是 Big-Endian 编码格式。</td> </tr> <tr> <td>AIFF</td> <td>AIFF 音频文件</td> </tr> <tr> <td>WAVE</td> <td>WAVE 音频文件(WAV/FLAC/APE)</td> </tr> <tr> <td>MP3</td> <td>MP3 音频文件</td> </tr> </tbody></table> <p>  不同的文件应该对应不同的文件类型。</p> <p>  比如:</p> <p>FILE “01 - Niki Nana (We’re One).flac” WAVE</p> <p>  注意:</p> <p>  1、每个 CUE 文件内至少含有一条 FILE 命令。</p> <p>  2、<data-file-name> 必须用<strong>半角双引号</strong>引起来。</p> <p>  3、注意 <data-file-name> 必须与 CUE 文件位于相同目录下。</p> <p>-———————————————————-</p> <p><strong>TRACK 命令</strong></p> <p>  这条命令用于声明某个数据文件内的一条数据轨段。格式为:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">  TRACK <track-id> <track-data-type></span><br></pre></td></tr></table></figure> <p>  其中 <track-id> 是轨段编号,取值必须在 01 到 99 之内。<track-data-type> 为轨段的数据类型,与刻录机型号有关,一般为 AUDIO,其他 <track-data-type> 类型请自行查阅相关文献。</p> <p>  比如:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TRACK 01 AUDIO</span><br></pre></td></tr></table></figure> <p>  注意:</p> <p>  1、每个 FILE 命令内至少含有一条 TRACK 命令。</p> <p>  2、<track-id> 即为播放器内识别的 音轨号。</p> <p>-———————————————————-</p> <p><strong>INDEX 命令</strong></p> <p>  这条命令对某个数据文件内的一条数据轨进行分段。格式为:</p> <p>  <em>INDEX <index> <begin-time></em></p> <p>  其中 <index> 是子轨段编号,取值必须在 00 到 99 之内。<begin-time> 为子轨段的时间起点。对于<index>,其中00和01为比较特殊的点。00 为要跳过的轨内空白段,而 01 为轨段的有效起点。</p> <p>  比如一个 TRACK 和前一个 TRACK 之间有50秒的空档:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">TRACK 01 AUDIO</span><br><span class="line"></span><br><span class="line">INDEX 01 00:00:00</span><br></pre></td></tr></table></figure> <p>REM 每个文件的第一个 TRACK 不能有 INDEX 00,其 INDEX 01 必须为 00:00:00。</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">TRACK 02 AUDIO</span><br><span class="line"></span><br><span class="line">INDEX 00 00:05:00</span><br></pre></td></tr></table></figure> <p>REM 此处跳过 50s 的空档,直接到 05:50 继续播放。</p> <p>REM 因为 INDEX 01 才是 TRACK 02 的开始,所以 INDEX 00 可以</p> <p>REM 看作是 TRACK 01 的有效结束时间。</p> <p>INDEX 01 00:05:50</p> <p>  注意:</p> <p>  1、每个 TRACK 命令内至少含有 INDEX 01。</p> <p>  2、每个文件第一个 TRACK 的 INDEX 01 都应从 00:00:00 开始,且不得有 INDEX 00。很多 CUE 文件无法被 Foobar2000 识别,就是因为这个错误。</p> <p>-———————————————————-</p> <p><strong>PREGAP 命令</strong></p> <p>  这条命令类似于 INDEX 00,但又略有所不同。格式为:</p> <p>  <em>PREGAP <skip-time></em></p> <p>  这条命令的作用和 INDEX 00 相似,但却又不相同。其中 <skip-time> 是要插入的空白时间长度。区别在于:</p> <p>  1、PREGAP 是在该<strong>轨段前</strong>硬性加入一段空白时间(数据全为0),常用于刻录中,Foobar2000 不支持。</p> <p>  2、PREGAP 是在<strong>轨段前</strong>插入真实数据,而 INDEX 00 只是跳过轨段内部的一段数据,因此两者不同。</p> <p>  3、PREGAP 可以用于文件的第一个 TRACK 中,而 INDEX 00 不可以。</p> <p>  比如:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">TRACK 01 AUDIO</span><br><span class="line"></span><br><span class="line">PREGAP 00:02:00</span><br><span class="line"></span><br><span class="line">INDEX 01 00:00:00</span><br></pre></td></tr></table></figure> <p>  注意:</p> <p>  1、每个 TRACK 命令内最多只能有一条 PREGAP 命令。</p> <p>  2、PREGAP 必须位于 TRACK 命令后,所有 INDEX 命令之前。</p> <p>-———————————————————-</p> <p><strong>POSTGAP 命令</strong></p> <p>  这条命令类似于 INDEX 00,但又略有所不同。格式为:</p> <p>  <em>POSTGAP <skip-time></em></p> <p>  这条命令的作用和 INDEX 00 相似,但却又不相同。其中 <skip-time> 是要插入的空白时间长度。区别在于:</p> <p>  1、POSTGAP 是在该<strong>轨段后</strong>硬性加入一段空白时间(数据全为0),常用于刻录中,Foobar2000 不支持。</p> <p>  2、POSTGAP 是在<strong>轨段后</strong>插入真实数据,而 INDEX 00 只是跳过轨段内部的一段数据,因此两者不同。</p> <p>  3、POSTGAP 可以文件的第一个 TRACK 中,而 INDEX 00 不可以。</p> <p>  比如:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">TRACK 01 AUDIO</span><br><span class="line"></span><br><span class="line">INDEX 01 00:00:00</span><br><span class="line"></span><br><span class="line">POSTGAP 00:02:00</span><br></pre></td></tr></table></figure> <p>  注意:</p> <p>  1、每个 TRACK 命令内最多只能有一条 POSTGAP 命令。</p> <p>  2、POSTGAP 必须位于所有 INDEX 命令之后。</p> <p>-———————————————————-</p> <p><strong>TITLE、SONGWRITER、PERFORMER 命令</strong></p> <p>  用于描述每条数据轨段的信息,用法参考 Header 部分。</p> <p>  注意:</p> <p>  1、在数据轨描述表内,这3条命令必须在 TRACK 命令后使用。</p> <p>-———————————————————-</p> <p><strong>ISRC 命令</strong></p> <p>  该命令指定数据轨的 ISRC 码(参考<a target="_blank" rel="noopener" href="http://baike.baidu.com/link?url=MY83GKCV1XD41bxrpocjoijfl5grghX8APCqrOfbCGkeLvaThrcHB93IDRHdIJLiJAS-K3LFxWPVJSAoT8F_sq">百度百科</a>)。格式为:</p> <p>  <em>ISRC <isrc-code></em></p> <p>  例如 NightWish 的《Imaginearum》专辑里第1轨:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ISRC FI3SN1100001</span><br></pre></td></tr></table></figure> <p>  注意:</p> <p>  1、该命令是单轨信息部分,必须出现在 TRACK 命令后面,且每轨只能有一条 ISRC 命令。</p> <p>  2、<isrc-code> 可以并建议用<strong>半角双引号</strong>引起来。</p> <p>-———————————————————-</p> <p><strong>FALGS 命令</strong></p> <p>  该命令指定数据轨的 SUBCODES,用于刻录中。格式为:</p> <p>  <em>FLAGS <subcodes></em></p> <p>  可用 SUBCODES 如下:</p> <table> <thead> <tr> <th><subcode></th> <th>说明</th> </tr> </thead> <tbody><tr> <td>DCP</td> <td>允许数位复制。</td> </tr> <tr> <td>PRE</td> <td>允许预加重。</td> </tr> <tr> <td>4CH</td> <td>四声道音讯。</td> </tr> <tr> <td>SCMS</td> <td>连续复制管理系统。</td> </tr> </tbody></table> <p>  例如 Bandari 的《Emerald Valley》专辑里第1轨:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">FLAGS DCP</span><br></pre></td></tr></table></figure> <p>  注意:</p> <p>  1、该命令是单轨信息部分,必须出现在 TRACK 命令后面,且每轨只能有一条 FLAGS 命令 </p> <p>  2、FLAGS 命令一次可以指定多条 subcode。</p> <p>-——————————————————–</p> <p><strong>REM 命令</strong></p> <p>  REM 命令在头部信息中已经描述过,此处对其扩展命令的用法进行补充说明,只用于 TRACK 命令中。格式为:</p> <table> <thead> <tr> <th>命令</th> <th>说明</th> <th>示例</th> </tr> </thead> <tbody><tr> <td><em>REM REPLAYGAIN_TRACK_GAIN</em> <em>+/- \</em>.<em>* dB</em></td> <td>用于指定音轨的增益回放信息,用于提高/降低音量。</td> <td>Groove Coverage的《21st Century》第02轨:<br/>REM REPLAYGAIN_TRACK_GAIN -10.22 dB</td> </tr> <tr> <td><em>REM REPLAYGAIN_TRACK_PEAK \</em>.*******</td> <td>用于指定音轨的增益回放信息,指定音轨峰值。</td> <td>Groove Coverage的《21st Century》第02轨:<br/>REM REPLAYGAIN_TRACK_PEAK 0.977142</td> </tr> </tbody></table> <p>=====================================================</p> <p><strong>三、范例解析</strong></p> <p>实例1:(此处 <code>/**/</code> 表示我的注释,注意 <code>/**/</code> 并非CUE内容</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">PERFORMER "Nightwish" /* 指定音乐光盘作者 */</span><br><span class="line"></span><br><span class="line">TITLE "Nemo, CDS, Normal Version" /* 指定光盘标题 */</span><br><span class="line"></span><br><span class="line">REM GENRE "Heavy Metal" /* 音乐分类 */</span><br><span class="line"></span><br><span class="line">REM DATE 2004 /* 发行年份 */</span><br><span class="line"></span><br><span class="line">REM DISCID 3F054305 /* 光盘 DISCID 编码 */</span><br><span class="line"></span><br><span class="line">REM COMMENT "ExactAudioCopy v0.99pb4" /* CUE 生成信息 */</span><br><span class="line"></span><br><span class="line">FILE "Nightwish - Nemo, CDS, Normal Version.ape" WAVE /* FILE 命令,指定音乐文件 */</span><br><span class="line"></span><br><span class="line"> TRACK 01 AUDIO /* 第一个音轨 */</span><br><span class="line"></span><br><span class="line"> TITLE "Nemo (From The Album 'Once')" /* 音轨标题 */</span><br><span class="line"></span><br><span class="line"> PERFORMER "Nightwish" /* 音乐演唱者 */</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:00:00 /* 第一轨 INDEX 01 必须从 00:00:00 开始 */</span><br><span class="line"></span><br><span class="line"> TRACK 02 AUDIO /* 第二个音轨 */</span><br><span class="line"></span><br><span class="line"> TITLE "Planet Hell(From The Album 'Once')" /* 音轨标题 */</span><br><span class="line"></span><br><span class="line"> PERFORMER "Nightwish" /* 音乐演唱者 */</span><br><span class="line"></span><br><span class="line"> REM REPLAYGAIN_TRACK_GAIN -8.32 dB /* 音乐增益回放信息 */</span><br><span class="line"></span><br><span class="line"> REM REPLAYGAIN_TRACK_PEAK 0.977234 /* 音乐增益回放信息 */</span><br><span class="line"></span><br><span class="line"> INDEX 00 04:29:03 /* 跳过两轨间的空档 */</span><br><span class="line"></span><br><span class="line"> INDEX 01 04:29:04 /* 第二个音轨的起点 */</span><br></pre></td></tr></table></figure> <p>实例2:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">TITLE "Imaginaerum"</span><br><span class="line"></span><br><span class="line">PERFORMER "Nightwish"</span><br><span class="line"></span><br><span class="line">REM GENRE "Symphonic Metal"</span><br><span class="line"></span><br><span class="line">REM DATE 2011</span><br><span class="line"></span><br><span class="line">REM DISCID BA118E0D</span><br><span class="line"></span><br><span class="line">REM COMMENT "ExactAudioCopy v1.0b3"</span><br><span class="line"></span><br><span class="line">FILE "01 - Taikatalvi.flac" WAVE /* 第一个文件 */</span><br><span class="line"></span><br><span class="line"> TRACK 01 AUDIO /* 只有一个 TRACK */</span><br><span class="line"></span><br><span class="line"> TITLE "Taikatalvi"</span><br><span class="line"></span><br><span class="line"> PERFORMER "Nightwish"</span><br><span class="line"></span><br><span class="line"> REM REPLAYGAIN_TRACK_GAIN -5.14 dB</span><br><span class="line"></span><br><span class="line"> REM REPLAYGAIN_TRACK_PEAK 0.977142</span><br><span class="line"></span><br><span class="line"> ISRC FI3SN1100001 /* 指定音轨的 ISRC 编号 */</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:00:00 /* 每个文件第一个 TRACK 的 INDEX 01 必须从 00:00:00 开始,且不能有 INDEX 00*/</span><br><span class="line"></span><br><span class="line">FILE "02 - Storytime.flac" WAVE /* 第二个文件 */</span><br><span class="line"></span><br><span class="line"> TRACK 02 AUDIO /* 只有一个 TRACK */</span><br><span class="line"></span><br><span class="line"> TITLE "Storytime"</span><br><span class="line"></span><br><span class="line"> PERFORMER "Nightwish"</span><br><span class="line"></span><br><span class="line"> ISRC FI3SN1100002 /* 指定音轨的 ISRC 编号 */</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:00:00 /* 每个文件第一个 TRACK 的 INDEX 01 必须从 00:00:00 开始,且不能有 INDEX 00*/</span><br></pre></td></tr></table></figure> <p>实例3:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">TITLE "Example"</span><br><span class="line"></span><br><span class="line">PERFORMER "Unknown"</span><br><span class="line"></span><br><span class="line">FILE "exp1.wav" WAVE /* 第一个文件 */</span><br><span class="line"></span><br><span class="line"> TRACK 01 AUDIO /* 文件的第一个音轨 */</span><br><span class="line"></span><br><span class="line"> TITLE "Track 01"</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:00:00</span><br><span class="line"></span><br><span class="line"> TRACK 02 AUDIO /* 文件的第二个音轨 */</span><br><span class="line"></span><br><span class="line"> TITLE "Track 02"</span><br><span class="line"></span><br><span class="line"> INDEX 00 00:04:49 /* 跳过其中 7s 空白*/</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:04:56</span><br><span class="line"></span><br><span class="line">FILE "exp2.wav" WAVE /* 第二个文件 */</span><br><span class="line"></span><br><span class="line"> TRACK 03 AUDIO /* 文件的第一个音轨 */</span><br><span class="line"></span><br><span class="line"> TITLE "Track 03"</span><br><span class="line"></span><br><span class="line"> INDEX 01 00:00:00</span><br></pre></td></tr></table></figure> <p>转载自<a target="_blank" rel="noopener" href="https://www.cnblogs.com/yanghong-hnu/p/4775287.html">CUE 文件格式说明</a></p> <div class='footer'> <div class='copyright'> <blockquote> <p>博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议</p> <p>本文永久链接是:<a href=https://outdegree.top/2021/02/40/>https://outdegree.top/2021/02/40/</a></p> </blockquote> </div> <div class='donate'> <div class='imgs'> <img src='/images/donate-alipay.png'> <img src='/images/donate-wechat.png'> </div> </div> </div> <div class='article-meta' id="bottom"> <div class='new-meta-box'> <div class="new-meta-item date" itemprop="dateUpdated" datetime="2021-02-15T20:51:20+00:00"> <a class='notlink'> <i class="fas fa-edit fa-fw" aria-hidden="true"></i> <p>更新于:2021年2月15日</p> </a> </div> <div class="new-meta-item meta-tags"><a class="tag" href="/tags/%E9%9F%B3%E4%B9%90/" rel="nofollow"><i class="fas fa-hashtag fa-fw" aria-hidden="true"></i><p>音乐</p></a></div> <div class="new-meta-item share -mob-share-list"> <div class="-mob-share-list share-body"> <a class="-mob-share-qq" title="" rel="external nofollow noopener noreferrer noopener" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=https://outdegree.top/2021/02/40/&title=CUE文件格式说明 - 出度++&summary=" > <img src="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qq.png" class="lazyload" data-srcset="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qq.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="> </a> <a class="-mob-share-qzone" title="" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=https://outdegree.top/2021/02/40/&title=CUE文件格式说明 - 出度++&summary=" > <img src="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qzone.png" class="lazyload" data-srcset="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qzone.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="> </a> <a class="-mob-share-weibo" title="" rel="external nofollow noopener noreferrer noopener" target="_blank" href="http://service.weibo.com/share/share.php?url=https://outdegree.top/2021/02/40/&title=CUE文件格式说明 - 出度++&summary=" > <img src="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/weibo.png" class="lazyload" data-srcset="https://fastly.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/weibo.png" srcset="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAALGPC/xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAaADAAQAAAABAAAAAQAAAADa6r/EAAAAC0lEQVQIHWNgAAIAAAUAAY27m/MAAAAASUVORK5CYII="> </a> </div> </div> </div> </div> <div class="prev-next"> <a class='prev' href='/2021/02/41/'> <p class='title'><i class="fas fa-chevron-left" aria-hidden="true"></i>OpenTTD专用服务器中安装NewGRF</p> <p class='content'>下载NewGRF方法一:在Windows中下载后上传到服务器打开游戏,下载需要的NewGRF下载好的文件位于:C:\Users\<username>\Documents\OpenTT...</p> </a> <a class='next' href='/2021/02/39/'> <p class='title'>使用foobar2000编辑flac/ape文件内置CUE<i class="fas fa-chevron-right" aria-hidden="true"></i></p> <p class='content'> 右键歌曲 → 工具 → 编辑CUE 如果没有这个选项的话 参考以下文章 foobar2000 工具里没有编辑cuesheet </p> </a> </div> </article> <article class="post white-box reveal shadow floatable" id="comments"> <p ct><i class='fas fa-comments'></i> 评论</p> <div id="valine_container" class="valine_thread"> <i class="fas fa-cog fa-spin fa-fw fa-2x"></i> </div> </article> </div> <aside class='l_side'> <section class="widget blogger shadow blur desktop mobile"> <div class='content'> <a class='avatar flat-box rectangle' href='/about/'> <img no-lazy src='/images/avatar.gif'/> </a> <div class="social-wrapper"> <a href="/atom.xml" class="social fas fa-rss flat-btn" target="_blank" rel="external nofollow noopener noreferrer"> </a> <a href="mailto:root@gyf.name" class="social fas fa-envelope flat-btn" target="_blank" rel="external nofollow noopener noreferrer"> </a> <a href="https://github.com/gyf9835/" class="social fab fa-github flat-btn" target="_blank" rel="external nofollow noopener noreferrer"> </a> <a href="https://music.163.com/#/user/home?id=314883160" class="social fas fa-headphones-alt flat-btn" target="_blank" rel="external nofollow noopener noreferrer"> </a> </div> </div> </section> <section class="widget tagcloud shadow blur desktop mobile"> <header> <a href='/tags/'><i class="fas fa-tags fa-fw" aria-hidden="true"></i><span class='name'>热门标签</span></a> </header> <div class='content'> <a href="/tags/htaccess/" style="font-size: 14px; color: #999">.htaccess</a> <a href="/tags/ASF/" style="font-size: 14px; color: #999">ASF</a> <a href="/tags/Alpine/" style="font-size: 15.25px; color: #919191">Alpine</a> <a href="/tags/Android/" style="font-size: 20.25px; color: #6f6f6f">Android</a> <a href="/tags/CMD/" style="font-size: 14px; color: #999">CMD</a> <a href="/tags/Calibre/" style="font-size: 15.25px; color: #919191">Calibre</a> <a href="/tags/Deepin/" style="font-size: 16.5px; color: #888">Deepin</a> <a href="/tags/Eclipse/" style="font-size: 14px; color: #999">Eclipse</a> <a href="/tags/Element/" style="font-size: 14px; color: #999">Element</a> <a href="/tags/Factorio/" style="font-size: 14px; color: #999">Factorio</a> <a href="/tags/Foobar2000/" style="font-size: 14px; color: #999">Foobar2000</a> <a href="/tags/GRUB/" style="font-size: 14px; color: #999">GRUB</a> <a href="/tags/Git/" style="font-size: 15.25px; color: #919191">Git</a> <a href="/tags/Hexo/" style="font-size: 17.75px; color: #808080">Hexo</a> <a href="/tags/JTextArea/" style="font-size: 14px; color: #999">JTextArea</a> <a href="/tags/Java/" style="font-size: 21.5px; color: #666">Java</a> <a href="/tags/Javadoc/" style="font-size: 14px; color: #999">Javadoc</a> <a href="/tags/Jellyfin/" style="font-size: 14px; color: #999">Jellyfin</a> <a href="/tags/KSWEB/" style="font-size: 14px; color: #999">KSWEB</a> <a href="/tags/Linux/" style="font-size: 24px; color: #555">Linux</a> <a href="/tags/Mac/" style="font-size: 15.25px; color: #919191">Mac</a> <a href="/tags/MySQL/" style="font-size: 15.25px; color: #919191">MySQL</a> <a href="/tags/NAS/" style="font-size: 16.5px; color: #888">NAS</a> <a href="/tags/NetBeans/" style="font-size: 19px; color: #777">NetBeans</a> <a href="/tags/Nginx/" style="font-size: 14px; color: #999">Nginx</a> <a href="/tags/OpenTTD/" style="font-size: 20.25px; color: #6f6f6f">OpenTTD</a> <a href="/tags/PDF/" style="font-size: 14px; color: #999">PDF</a> <a href="/tags/PVE/" style="font-size: 14px; color: #999">PVE</a> <a href="/tags/PlantUML/" style="font-size: 14px; color: #999">PlantUML</a> <a href="/tags/SSH/" style="font-size: 14px; color: #999">SSH</a> <a href="/tags/Steam/" style="font-size: 14px; color: #999">Steam</a> <a href="/tags/Swing/" style="font-size: 19px; color: #777">Swing</a> <a href="/tags/Tomcat/" style="font-size: 14px; color: #999">Tomcat</a> <a href="/tags/UML/" style="font-size: 14px; color: #999">UML</a> <a href="/tags/UMLDoclet/" style="font-size: 14px; color: #999">UMLDoclet</a> <a href="/tags/VS-Code/" style="font-size: 14px; color: #999">VS Code</a> <a href="/tags/VUE/" style="font-size: 14px; color: #999">VUE</a> <a href="/tags/Windows/" style="font-size: 16.5px; color: #888">Windows</a> <a href="/tags/WordPress/" style="font-size: 15.25px; color: #919191">WordPress</a> <a href="/tags/ZSH/" style="font-size: 14px; color: #999">ZSH</a> <a href="/tags/ant/" style="font-size: 14px; color: #999">ant</a> <a href="/tags/bat/" style="font-size: 14px; color: #999">bat批处理</a> <a href="/tags/bt/" style="font-size: 14px; color: #999">bt</a> <a href="/tags/devcon/" style="font-size: 14px; color: #999">devcon</a> <a href="/tags/emoji/" style="font-size: 14px; color: #999">emoji</a> <a href="/tags/foobar2000/" style="font-size: 14px; color: #999">foobar2000</a> <a href="/tags/openmediavault/" style="font-size: 19px; color: #777">openmediavault</a> <a href="/tags/proxyee-down/" style="font-size: 14px; color: #999">proxyee-down</a> <a href="/tags/pt/" style="font-size: 14px; color: #999">pt</a> <a href="/tags/%E4%B8%83%E7%89%9B%E4%BA%91/" style="font-size: 14px; color: #999">七牛云</a> <a href="/tags/host/" style="font-size: 14px; color: #999">万网虚拟机</a> <a href="/tags/download/" style="font-size: 14px; color: #999">下载</a> <a href="/tags/shuangXiTong/" style="font-size: 14px; color: #999">双系统</a> <a href="/tags/GTASA/" style="font-size: 14px; color: #999">圣安地列斯</a> <a href="/tags/Font/" style="font-size: 14px; color: #999">字体</a> <a href="/tags/Android/" style="font-size: 19px; color: #777">安卓</a> <a href="/tags/jianZhan/" style="font-size: 15.25px; color: #919191">建站</a> <a href="/tags/kaiFu/" style="font-size: 16.5px; color: #888">开服</a> <a href="/tags/%E5%BC%82%E6%98%9F%E5%B7%A5%E5%8E%82/" style="font-size: 14px; color: #999">异星工厂</a> <a href="/tags/yinDao/" style="font-size: 14px; color: #999">引导</a> <a href="/tags/shouJi/" style="font-size: 16.5px; color: #888">手机</a> <a href="/tags/youDao/" style="font-size: 14px; color: #999">有道精品课</a> <a href="/tags/Server/" style="font-size: 22.75px; color: #5e5e5e">服务器</a> <a href="/tags/Game/" style="font-size: 22.75px; color: #5e5e5e">游戏</a> <a href="/tags/Bio/" style="font-size: 14px; color: #999">生物</a> <a href="/tags/%E7%B3%BB%E7%BB%9F/" style="font-size: 14px; color: #999">系统</a> <a href="/tags/Exp/" style="font-size: 16.5px; color: #888">经验</a> <a href="/tags/Program/" style="font-size: 15.25px; color: #919191">编程</a> <a href="/tags/xuNiJi/" style="font-size: 14px; color: #999">虚拟机</a> <a href="/tags/Software/" style="font-size: 17.75px; color: #808080">软件</a> <a href="/tags/Essay/" style="font-size: 17.75px; color: #808080">随笔</a> <a href="/tags/%E9%9F%B3%E4%B9%90/" style="font-size: 16.5px; color: #888">音乐</a> </div> </section> </aside> <!--此文件用来存放一些不方便取值的变量--> <!--思路大概是将值藏到重加载的区域内--> <script> window.pdata={} pdata.ispage=true; pdata.postTitle="CUE文件格式说明"; pdata.commentPath=""; pdata.commentPlaceholder=""; // header 这里无论是否开启pjax都需要 var l_header=document.getElementById("l_header"); l_header.classList.add("show"); // cover var cover_wrapper=document.querySelector('.cover-wrapper'); cover_wrapper.id="none"; cover_wrapper.style.display="none"; </script> </div> <footer class="footer clearfix"> <br><br> <div class="aplayer-container"> <meting-js theme='#1BCDFC' autoplay='false' volume='0.3' loop='all' order='list' fixed='true' list-max-height='320px' server='netease' type='playlist' id='5244137575' list-folded='false'> </meting-js> </div> <br> <div class="social-wrapper"> </div> <div><p>博客内容遵循 <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议</a></p> </div> <div><p><span id="lc-sv">本站总访问量为 <span id='number'><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span> 次</span> <span id="lc-uv">访客数为 <span id='number'><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span> 人</span></p> </div> 本站使用 <a href="https://github.com/volantis-x/hexo-theme-volantis/tree/4.3.1" target="_blank" class="codename">Volantis</a> 作为主题 <div class='copyright'> <p><a href="/">Copyright © 2015-2021 outdegree.top</a></p> </div> <div><p><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/">蒙ICP备2021001125号-1</a></p> </div> </footer> <a id="s-top" class="fas fa-arrow-up fa-fw" href="javascript:void(0)"></a> </div> </div> <div> <script> /************这个文件存放不需要重载的全局变量和全局函数*********/ window.volantis={}; window.volantis.loadcss=document.getElementById("loadcss"); /******************** Pjax ********************************/ function VPjax(){ this.list=[] // 存放回调函数 this.start=()=>{ for(var i=0;i<this.list.length;i++){ this.list[i].run(); } } this.push=(fn,name)=>{ var f=new PjaxItem(fn,name); this.list.push(f); } // 构造一个可以run的对象 function PjaxItem(fn,name){ // 函数名称 this.name = name || fn.name // run方法 this.run=()=>{ fn() } } } volantis.pjax={} volantis.pjax.method={ complete: new VPjax(), error: new VPjax(), send: new VPjax() } volantis.pjax={ ...volantis.pjax, push: volantis.pjax.method.complete.push, error: volantis.pjax.method.error.push, send: volantis.pjax.method.send.push } /********************脚本懒加载函数********************************/ // 已经加入了setTimeout function loadScript(src, cb) { setTimeout(function() { var HEAD = document.getElementsByTagName('head')[0] || document.documentElement; var script = document.createElement('script'); script.setAttribute('type','text/javascript'); if (cb) script.onload = cb; script.setAttribute('src', src); HEAD.appendChild(script); }); } //https://github.com/filamentgroup/loadCSS var loadCSS = function( href, before, media, attributes ){ var doc = window.document; var ss = doc.createElement( "link" ); var ref; if( before ){ ref = before; } else { var refs = ( doc.body || doc.getElementsByTagName( "head" )[ 0 ] ).childNodes; ref = refs[ refs.length - 1]; } var sheets = doc.styleSheets; if( attributes ){ for( var attributeName in attributes ){ if( attributes.hasOwnProperty( attributeName ) ){ ss.setAttribute( attributeName, attributes[attributeName] ); } } } ss.rel = "stylesheet"; ss.href = href; ss.media = "only x"; function ready( cb ){ if( doc.body ){ return cb(); } setTimeout(function(){ ready( cb ); }); } ready( function(){ ref.parentNode.insertBefore( ss, ( before ? ref : ref.nextSibling ) ); }); var onloadcssdefined = function( cb ){ var resolvedHref = ss.href; var i = sheets.length; while( i-- ){ if( sheets[ i ].href === resolvedHref ){ return cb(); } } setTimeout(function() { onloadcssdefined( cb ); }); }; function loadCB(){ if( ss.addEventListener ){ ss.removeEventListener( "load", loadCB ); } ss.media = media || "all"; } if( ss.addEventListener ){ ss.addEventListener( "load", loadCB); } ss.onloadcssdefined = onloadcssdefined; onloadcssdefined( loadCB ); return ss; }; </script> <script> loadCSS("https://fastly.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.14/css/all.min.css", window.volantis.loadcss); </script> <!-- required --> <script src="https://fastly.jsdelivr.net/npm/jquery@3.5/dist/jquery.min.js"></script> <script> function pjax_fancybox() { $(".md .gallery").find("img").each(function () { //渲染 fancybox var element = document.createElement("a"); // a 标签 $(element).attr("class", "fancybox"); $(element).attr("pjax-fancybox", ""); // 过滤 pjax $(element).attr("href", $(this).attr("src")); if ($(this).attr("data-original")) { $(element).attr("href", $(this).attr("data-original")); } $(element).attr("data-fancybox", "images"); var caption = ""; // 描述信息 if ($(this).attr('alt')) { // 判断当前页面是否存在描述信息 $(element).attr('data-caption', $(this).attr('alt')); caption = $(this).attr('alt'); } var div = document.createElement("div"); $(div).addClass("fancybox"); $(this).wrap(div); // 最外层套 div ,其实主要作用还是 class 样式 var span = document.createElement("span"); $(span).addClass("image-caption"); $(span).text(caption); // 加描述 $(this).after(span); // 再套一层描述 $(this).wrap(element); // 最后套 a 标签 }) $(".md .gallery").find("img").fancybox({ selector: '[data-fancybox="images"]', hash: false, loop: false, closeClick: true, helpers: { overlay: {closeClick: true} }, buttons: [ "zoom", "close" ] }); }; function SCload_fancybox() { if ($(".md .gallery").find("img").length == 0) return; loadCSS("https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css", document.getElementById("loadcss")); loadScript('https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js', pjax_fancybox) }; $(function () { SCload_fancybox(); }); function Pjax_SCload_fancybox(){ if (typeof $.fancybox == "undefined") { SCload_fancybox(); } else { pjax_fancybox(); } } volantis.pjax.push(Pjax_SCload_fancybox) volantis.pjax.send(()=>{ if (typeof $.fancybox != "undefined") { $.fancybox.close(); // 关闭弹窗 } },'fancybox') </script> <!-- internal --> <script src="https://fastly.jsdelivr.net/npm/jquery-backstretch@2.1.18/jquery.backstretch.min.js"></script> <script type="text/javascript"> var imgs=["/images/backstretch01.png", "/images/backstretch02.png", "/images/backstretch03.png"]; if ('true' == 'true') { function shuffle(arr){ /*From countercurrent-time*/ var n = arr.length; while(n--) { var index = Math.floor(Math.random() * n); var temp = arr[index]; arr[index] = arr[n]; arr[n] = temp; } } shuffle(imgs); } function Pjax_backstretch(){ $.backstretch( imgs, { duration: "10000", fade: "1500" }); } loadScript("https://fastly.jsdelivr.net/npm/jquery-backstretch@2.1.18/jquery.backstretch.min.js",Pjax_backstretch) </script> <script> function loadIssuesJS() { if ($(".md").find(".issues-api").length == 0) return; loadScript('/js/issues.js'); }; $(function () { loadIssuesJS(); }); volantis.pjax.push(()=>{ if (typeof IssuesAPI == "undefined") { loadIssuesJS(); } },"IssuesJS") </script> <script defer src="https://fastly.jsdelivr.net/npm/vanilla-lazyload@17.1.0/dist/lazyload.min.js"></script> <script> // https://www.npmjs.com/package/vanilla-lazyload // Set the options globally // to make LazyLoad self-initialize window.lazyLoadOptions = { elements_selector: ".lazyload", threshold: 0 }; // Listen to the initialization event // and get the instance of LazyLoad window.addEventListener( "LazyLoad::Initialized", function (event) { window.lazyLoadInstance = event.detail.instance; }, false ); document.addEventListener('DOMContentLoaded', function () { lazyLoadInstance.update(); }); document.addEventListener('pjax:complete', function () { lazyLoadInstance.update(); }); </script> <script> window.FPConfig = { delay: 0, ignoreKeywords: [], maxRPS: 5, hoverDelay: 25 }; </script> <script defer src="https://fastly.jsdelivr.net/gh/gijo-varghese/flying-pages@2.1.2/flying-pages.min.js"></script> <script src="https://fastly.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script> <script> var clipboard = new ClipboardJS('.btn-copy', { target: function (trigger) { return trigger.nextElementSibling } }); function wait(callback, seconds) { var timelag = null; timelag = window.setTimeout(callback, seconds) } function pjax_initCopyCode() { if($(".highlight .code pre").length+$(".article pre code").length==0)return; var copyHtml = ''; copyHtml += '<button class="btn-copy" data-clipboard-snippet="">'; copyHtml += '<i class="fas fa-copy"></i><span>COPY</span>'; copyHtml += '</button>'; $(".highlight .code pre").before(copyHtml); $(".article pre code").before(copyHtml); clipboard.off('success').on('success', function (e) { let $btn = $(e.trigger); $btn.addClass('copied'); let $icon = $($btn.find('i')); $icon.removeClass('fa-copy'); $icon.addClass('fa-check-circle'); let $span = $($btn.find('span')); $span[0].innerText = 'COPIED'; wait(function () { $icon.removeClass('fa-check-circle'); $icon.addClass('fa-copy'); $span[0].innerText = 'COPY' }, 2000) }); clipboard.off('error').on('error', function (e) { e.clearSelection(); let $btn = $(e.trigger); $btn.addClass('copy-failed'); let $icon = $($btn.find('i')); $icon.removeClass('fa-copy'); $icon.addClass('fa-times-circle'); let $span = $($btn.find('span')); $span[0].innerText = 'COPY FAILED'; wait(function () { $icon.removeClass('fa-times-circle'); $icon.addClass('fa-copy'); $span[0].innerText = 'COPY' }, 2000) }) } $(function () { pjax_initCopyCode() }); volantis.pjax.push(pjax_initCopyCode) </script> <script> let APlayerController = new Object(); APlayerController.id = '5244137575'; // 设定全局音乐播放ID APlayerController.volume = '0.3'; loadCSS("https://cdn.jsdelivr.net/npm/aplayer@1.10/dist/APlayer.min.css", window.volantis.loadcss); // APlayer 需要在 MetingJS 之前加载 loadScript("https://fastly.jsdelivr.net/npm/aplayer@1.10/dist/APlayer.min.js") window.volantis.APlayerLoaded=0 // APlayer加载完成状态 var checkAPlayer = setInterval(function () { if (!window.APlayer) return // APlayer加载完成? if ($("#safearea").css("display")!="block") return // 文章内容加载完成? see: source/css/first.styl clearInterval(checkAPlayer) if (!window.volantis.APlayerLoaded&&!window.MetingJSElement){ // APlayer只能加载一次 window.volantis.APlayerLoaded=1 // APlayer加载完成 loadScript("https://fastly.jsdelivr.net/npm/meting@2.0/dist/Meting.min.js") // 加载 MetingJS } }, 2500) // 按照网速调节差分2.5s // rightmenu see: layout/_partial/rightmenu.ejs </script> <script src="/js/valine.js"></script> <script> function emoji(path, idx, ext) { return path + "/" + path + "-" + idx + "." + ext; } var emojiMaps = {}; for (var i = 1; i <= 54; i++) { emojiMaps['tieba-' + i] = emoji('tieba', i, 'png'); } for (var i = 1; i <= 101; i++) { emojiMaps['qq-' + i] = emoji('qq', i, 'gif'); } for (var i = 1; i <= 116; i++) { emojiMaps['aru-' + i] = emoji('aru', i, 'gif'); } for (var i = 1; i <= 125; i++) { emojiMaps['twemoji-' + i] = emoji('twemoji', i, 'png'); } for (var i = 1; i <= 4; i++) { emojiMaps['weibo-' + i] = emoji('weibo', i, 'png'); } function pjax_valine() { if(!document.querySelectorAll("#valine_container")[0])return; let pagePlaceholder = pdata.commentPlaceholder || "评论我会尽快回复"; let path = pdata.commentPath; if (path.length == 0) { let defaultPath = ''; path = defaultPath || decodeURI(window.location.pathname); } var valine = new Valine(); valine.init(Object.assign({"path":null,"placeholder":"评论我会尽快回复","appId":"9P9NKRVdrVF2VWhCobOoy4iT-gzGzoHsz","appKey":"mRm7uCIs2cmPNsVtWL1b0S7T","meta":["nick","mail","link"],"requiredFields":["nick","mail"],"enableQQ":true,"recordIP":false,"avatar":"retro","pageSize":10,"lang":"zh-cn","highlight":true,"mathJax":false}, { el: '#valine_container', path: path, placeholder: pagePlaceholder, emojiCDN: 'https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/valine/', emojiMaps: emojiMaps, })) } $(function () { pjax_valine(); }); volantis.pjax.push(pjax_valine); </script> <script src="/js/app.js"></script> <!-- optional --> <script> const SearchServiceimagePath="https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@master/img/"; const ROOT = ("/" || "/").endsWith('/') ? ("/" || "/") : ("//" || "/" ); $('.input.u-search-input').one('focus',function(){ loadScript('/js/search/hexo.js',setSearchService); }) function listenSearch(){ customSearch = new HexoSearch({ imagePath: SearchServiceimagePath }); } function setSearchService() { listenSearch(); } </script> <script defer> const LCCounter = { app_id: '9P9NKRVdrVF2VWhCobOoy4iT-gzGzoHsz', app_key: 'mRm7uCIs2cmPNsVtWL1b0S7T', custom_api_server: '', // 查询存储的记录 getRecord(Counter, url, title) { return new Promise(function (resolve, reject) { Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({url}))) .then(resp => resp.json()) .then(({results, code, error}) => { if (code === 401) { throw error; } if (results && results.length > 0) { var record = results[0]; resolve(record); } else { Counter('post', '/classes/Counter', {url, title: title, times: 0}) .then(resp => resp.json()) .then((record, error) => { if (error) { throw error; } resolve(record); }).catch(error => { console.error('Failed to create', error); reject(error); }); } }).catch((error) => { console.error('LeanCloud Counter Error:', error); reject(error); }); }) }, // 发起自增请求 increment(Counter, incrArr) { return new Promise(function (resolve, reject) { Counter('post', '/batch', { "requests": incrArr }).then((res) => { res = res.json(); if (res.error) { throw res.error; } resolve(res); }).catch((error) => { console.error('Failed to save visitor count', error); reject(error); }); }); }, // 构建自增请求体 buildIncrement(objectId) { return { "method": "PUT", "path": `/1.1/classes/Counter/${ objectId }`, "body": { "times": { '__op': 'Increment', 'amount': 1 } } } }, // 校验是否为有效的 UV validUV() { var key = 'LeanCloudUVTimestamp'; var flag = localStorage.getItem(key); if (flag) { // 距离标记小于 24 小时则不计为 UV if (new Date().getTime() - parseInt(flag) <= 86400000) { return false; } } localStorage.setItem(key, new Date().getTime().toString()); return true; }, addCount(Counter) { var enableIncr = '' === 'true' && window.location.hostname !== 'localhost'; enableIncr = true; var getterArr = []; var incrArr = []; // 请求 PV 并自增 var pvCtn = document.querySelector('#lc-sv'); if (pvCtn || enableIncr) { var pvGetter = this.getRecord(Counter, 'https://outdegree.top' + '/#lc-sv', 'Visits').then((record) => { incrArr.push(this.buildIncrement(record.objectId)) var eles = document.querySelectorAll('#lc-sv #number'); if (eles.length > 0) { eles.forEach((el,index,array)=>{ el.innerText = record.times + 1; if (pvCtn) { pvCtn.style.display = 'inline'; } }) } }); getterArr.push(pvGetter); } // 请求 UV 并自增 var uvCtn = document.querySelector('#lc-uv'); if (uvCtn || enableIncr) { var uvGetter = this.getRecord(Counter, 'https://outdegree.top' + '/#lc-uv', 'Visitors').then((record) => { var vuv = this.validUV(); vuv && incrArr.push(this.buildIncrement(record.objectId)) var eles = document.querySelectorAll('#lc-uv #number'); if (eles.length > 0) { eles.forEach((el,index,array)=>{ el.innerText = record.times + (vuv ? 1 : 0); if (uvCtn) { uvCtn.style.display = 'inline'; } }) } }); getterArr.push(uvGetter); } // 请求文章的浏览数,如果是当前页面就自增 var allPV = document.querySelectorAll('#lc-pv'); if (allPV.length > 0 || enableIncr) { for (i = 0; i < allPV.length; i++) { let pv = allPV[i]; let title = pv.getAttribute('data-title'); var url = 'https://outdegree.top' + pv.getAttribute('data-path'); if (url) { var viewGetter = this.getRecord(Counter, url, title).then((record) => { // 是当前页面就自增 let curPath = window.location.pathname; if (curPath.includes('index.html')) { curPath = curPath.substring(0, curPath.lastIndexOf('index.html')); } if (pv.getAttribute('data-path') == curPath) { incrArr.push(this.buildIncrement(record.objectId)); } if (pv) { var ele = pv.querySelector('#lc-pv #number'); if (ele) { if (pv.getAttribute('data-path') == curPath) { ele.innerText = (record.times || 0) + 1; } else { ele.innerText = record.times || 0; } pv.style.display = 'inline'; } } }); getterArr.push(viewGetter); } } } // 如果启动计数自增,批量发起自增请求 if (enableIncr) { Promise.all(getterArr).then(() => { incrArr.length > 0 && this.increment(Counter, incrArr); }) } }, fetchData(api_server) { var Counter = (method, url, data) => { return fetch(`${ api_server }/1.1${ url }`, { method, headers: { 'X-LC-Id': this.app_id, 'X-LC-Key': this.app_key, 'Content-Type': 'application/json', }, body: JSON.stringify(data) }); }; this.addCount(Counter); }, refreshCounter() { var api_server = this.app_id.slice(-9) !== '-MdYXbMMI' ? this.custom_api_server : `https://${ this.app_id.slice(0, 8).toLowerCase() }.api.lncldglobal.com`; if (api_server) { this.fetchData(api_server); } else { fetch('https://app-router.leancloud.cn/2/route?appId=' + this.app_id) .then(resp => resp.json()) .then(({api_server}) => { this.fetchData('https://' + api_server); }); } } }; LCCounter.refreshCounter(); document.addEventListener('pjax:complete', function () { LCCounter.refreshCounter(); }); </script> <!-- Global site tag (gtag.js) - Google Analytics --> <!-- https://github.com/volantis-x/hexo-theme-volantis/issues/63 --> <script> setTimeout(function() { loadScript("https://www.googletagmanager.com/gtag/js?id=G-V9YZTKFM58"); window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-V9YZTKFM58'); }, 5000); // 关于谷歌统计对 SPA 页面的处理: // 当应用以动态方式加载内容并更新地址栏中的网址时,也应该更新通过 gtag.js 存储的网页网址。 // https://developers.google.cn/analytics/devguides/collection/gtagjs/single-page-applications?hl=zh-cn volantis.pjax.push(()=>{ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('config', 'G-V9YZTKFM58', {'page_path': document.location.pathname}); },'google_analytics') </script> <!-- baidu Analytics --> <script> var _hmt = _hmt || []; (function() { setTimeout(function() { loadScript("https://hm.baidu.com/hm.js?07fea0bfbfb7138a7e6b0540556a9a32") }, 5000); })(); // 关于百度统计对 SPA 页面的处理: // 方案一:百度统计>管理>单页应用设置中,打开开启按钮即可对SPA进行统计。 https://tongji.baidu.com/web/help/article?id=324 // 方案二:取消注释下列代码。 https://tongji.baidu.com/web/help/article?id=235 volantis.pjax.push(()=>{_hmt.push(['_trackPageview', document.location.pathname]);},'baidu_analytics') </script> <script> function listennSidebarTOC() { const navItems = document.querySelectorAll(".toc li"); if (!navItems.length) return; const sections = [...navItems].map((element) => { const link = element.querySelector(".toc-link"); const target = document.getElementById( decodeURI(link.getAttribute("href")).replace("#", "") ); link.addEventListener("click", (event) => { event.preventDefault(); window.scrollTo({ top: target.offsetTop + 100, behavior: "smooth" }); }); return target; }); function activateNavByIndex(target) { if (target.classList.contains("active-current")) return; document.querySelectorAll(".toc .active").forEach((element) => { element.classList.remove("active", "active-current"); }); target.classList.add("active", "active-current"); let parent = target.parentNode; while (!parent.matches(".toc")) { if (parent.matches("li")) parent.classList.add("active"); parent = parent.parentNode; } } function findIndex(entries) { let index = 0; let entry = entries[index]; if (entry.boundingClientRect.top > 0) { index = sections.indexOf(entry.target); return index === 0 ? 0 : index - 1; } for (; index < entries.length; index++) { if (entries[index].boundingClientRect.top <= 0) { entry = entries[index]; } else { return sections.indexOf(entry.target); } } return sections.indexOf(entry.target); } function createIntersectionObserver(marginTop) { marginTop = Math.floor(marginTop + 10000); let intersectionObserver = new IntersectionObserver( (entries, observe) => { let scrollHeight = document.documentElement.scrollHeight + 100; if (scrollHeight > marginTop) { observe.disconnect(); createIntersectionObserver(scrollHeight); return; } let index = findIndex(entries); activateNavByIndex(navItems[index]); }, { rootMargin: marginTop + "px 0px -100% 0px", threshold: 0, } ); sections.forEach((element) => { element && intersectionObserver.observe(element); }); } createIntersectionObserver(document.documentElement.scrollHeight); } document.addEventListener("DOMContentLoaded", listennSidebarTOC); document.addEventListener("pjax:success", listennSidebarTOC); </script> <!-- more --> <script src="https://cdn.jsdelivr.net/npm/pjax@0.2.8/pjax.min.js"></script> <script> var pjax; document.addEventListener('DOMContentLoaded', function () { pjax = new Pjax({ elements: 'a[href]:not([href^="#"]):not([href="javascript:void(0)"]):not([pjax-fancybox])', selectors: [ "title", "#pjax-container", "#pjax-header-nav-list" ], cacheBust: false, // url 地址追加时间戳,用以避免浏览器缓存 timeout: 5000 }); }); document.addEventListener('pjax:send', function (e) { //window.stop(); // 相当于点击了浏览器的停止按钮 try { var currentUrl = window.location.pathname; var targetUrl = e.triggerElement.href; var banUrl = [""]; if (banUrl[0] != "") { banUrl.forEach(item => { if(currentUrl.indexOf(item) != -1 || targetUrl.indexOf(item) != -1) { window.location.href = targetUrl; } }); } } catch (error) {} window.subData = null; // 移除标题(用于一二级导航栏切换处) volantis.$switcher.removeClass('active'); // 关闭移动端激活的搜索框 volantis.$header.removeClass('z_search-open'); // 关闭移动端激活的搜索框 volantis.$wrapper.removeClass('sub'); // 跳转页面时关闭二级导航 // 解绑事件 避免重复监听 volantis.$topBtn.unbind('click'); $('.menu a').unbind('click'); $(window).unbind('resize'); $(window).unbind('scroll'); $(document).unbind('scroll'); $(document).unbind('click'); $('body').unbind('click'); // 使用 volantis.pjax.send 方法传入pjax:send回调函数 参见layout/_partial/scripts/global.ejs volantis.pjax.method.send.start(); }); document.addEventListener('pjax:complete', function () { $('.nav-main').find('.list-v').not('.menu-phone').removeAttr("style",""); // 移除小尾巴的移除 $('.menu-phone.list-v').removeAttr("style",""); // 移除小尾巴的移除 $('script[data-pjax], .pjax-reload script').each(function () { $(this).parent().append($(this).remove()); }); try{ // 使用 volantis.pjax.push 方法传入重载函数 参见layout/_partial/scripts/global.ejs volantis.pjax.method.complete.start(); } catch (e) { console.log(e); } }); document.addEventListener('pjax:error', function (e) { // 使用 volantis.pjax.error 方法传入pjax:error回调函数 参见layout/_partial/scripts/global.ejs volantis.pjax.method.error.start(); window.location.href = e.triggerElement.href; }); </script> </div> </body> </html>