淺談動感歌詞-歌詞補充篇

1引言

以前寫了幾篇關於動感歌詞的簡單介紹,相信你們還有印象,這裏就很少說了,這篇要說的是,關於翻譯歌詞和音譯歌詞,以及我在解析和顯示這兩種歌詞的時候,遇到的一些難題、技術和心得。android

2動感歌詞格式

下面我簡單說一下,關於翻譯歌詞和音譯歌詞保存在哪裏的問題。由於我主要研究的是krc歌詞,因此這裏我會以krc解析爲主。固然,我也根據本身的實際需求,自定義了一種歌詞格式,方便本身使用,這裏也會簡單說一下,爲了區分音譯和翻譯歌詞,我把原來的歌詞,稱爲:【原始歌詞】,音譯和翻譯歌詞統稱【額外歌詞】。git

2.1krc歌詞

krc歌詞,分析篇也說了,雖然是加密了,可是也難不到萬能的網友。如下是根據網上提示的算法,獲得解密後的歌詞內容:github

鍩�[id:$0145B5C5]
[ar:�跺お]
[ti:蹇��ㄥ����]
[by:]
[hash:fa8e1508c06761a9b82631f1cf7c3b54]
[al:]
[sign:]
[qq:]
[total:1230449]
[offset:0]
[language:eyJjb250ZW50IjpbeyJsYW5ndWFnZSII6MX0= 。。。。。。。。。。。(此處省略100字)。。。。。]
[28131,4758]<0,1302,0>璧�<1302,951,0>��<2253,401,0>��<2654,250,0>��<2904,1854,0>��
[33690,5705]<0,800,0>��<800,2152,0>浜� <2952,201,0>��<3153,249,0>��<3402,402,0>��<3804,199,0>��<4003,903,0>嫺�<4906,799,0>��

對的,你看到的不是亂碼,這是我爲了找到有翻譯和音譯的krc歌詞,而找的一份歌詞(茶太 - 志在千里~戀姫喚做百花王~.krc),裏面的亂碼實際上是日語來的,好了廢話很少說,其實咱們只要細心看便會看到歌詞裏,有一行:算法

[language:eyJjb250ZW50IjpbeyJsYW5ndWFnZSII6MX0= 。。。。。。。。。。。(此處省略100字)。。。。。]

是的,就是這一行,krc歌詞裏面的翻譯歌詞和音譯歌詞,都在這一行裏面,看到這些abcd是否是好眼熟?對的,這些字符串,就是base64加密後的字符串。咱們解密來看看,是什麼東東,解密內容以下:app

{"content":[{"language":0,"lyricContent":[["a","kaku","ne","nyu","ru"],["a","kanegumo","shi","zu","shi","zu","naga","ru"],。。。。(此處省略100字)。。。。。。。。。。。],"type":0},{"language":0,"lyricContent":[["\u71C3\u7684\u706B\u7EA2"],["\u7EC6\u7EC6\u6447\u66F3\u7684\u6697\u7EA2\u8272\u7684\u4E91\u6735\u9759\u9759\u6D41\u52A8"],["\u8EAB\u540E\u9668\u843D"]。。。。(此處省略100字)。。。。。。],"type":1}],"version":1}

從解密後的內容能夠看到,type=0是音譯歌詞,type=1是翻譯歌詞,其中歌詞中看不到與時間相關的標籤,這是由於【原始歌詞】中已經含有了時間的標籤和精準到【字】的時間標籤。翻譯歌詞相對簡單,只須要與原始歌詞的【行】對應便可。音譯歌詞,除了與原始歌詞的【行】對應外,還與【行】歌詞裏的每一個【字】相對應。優化

2.2hrcs歌詞

該歌詞格式是以前hrcx歌詞的升級版。咱們先回顧一下hrcx歌詞的格式:動畫

[ti:右手戒指];
[total:272706];
[ar:金海心];
[offset:0];
[by:HappyPlayer-PC];
haplayer.lrc('<1270,9630>','金海[心 ][- ]右手戒指','<1010,780,830,1410,800,1210,1410,910>');
haplayer.lrc('<18710,19810>','[la ][la ][la ]','<300,400,400>');
haplayer.lrc('<20020,22840><77150,79970><163120,165840><191920,194740>','是你夢中的女郎','<200,300,400,300,510,500,610><310,400,300,510,400,400,500><200,510,400,400,410,500,300><210,400,300,400,400,510,600>');

從歌詞格式內容,咱們能夠看到,在解析歌詞的時候,咱們還要費時去解析歌詞行的每一個【字】(最可憐的仍是要判斷該【字】是中文、英文、韓文仍是日文,最變態的仍是泰文),而後對歌詞進行分割,獲得【字】而後,最後解析後面的時間標籤再獲得【字】對應的時間。是的,解析歌詞行的每一個【字】,這是在製做歌詞的時候,才須要去作的事情啊,因此這裏也是須要優化的地方,加上各類歌詞間相互轉換時,該格式存在出錯的機率比較多,每每會由於獲得的【字】個數與後面的【字】時間個數不對應,而報錯。因此基於以上的種種緣由,我從新改良了該歌詞的格式:加密

haplayer.tag[qq:];
[ti:志在千里];
haplayer.tag[total:1230449];
haplayer.tag[by:];
haplayer.tag[sign:];
haplayer.tag[al:];
[ar:茶太];
[offset:0];
haplayer.tag[hash:fa8e1508c06761a9b82631f1cf7c3b54];
haplayer.extra.lrc('eyJjb250ZW50IjpbeyJseXYSI。。。。(此處省略100字)。。。。。。。。。。。sImkiLCJ0ZSJdXX1dfQ==');
haplayer.lrc('<28131,32889>','<赤><く><燃><ゆ><る>','<1302,951,401,250,1854>');

從上面的內容能夠看出,該歌詞格式也是支持音譯歌詞和翻譯歌詞的(參考krc原理)。主要優化在歌詞行:翻譯

haplayer.lrc('<28131,32889>','<赤><く><燃><ゆ><る>','<1302,951,401,250,1854>');

在這裏,我將每一個【字】用<>來包住,這樣子在解析時,除了簡單,相對準確性會比較高。code

3歌詞實體類結構變化

  1. 歌詞實體,添加音譯歌詞和翻譯歌詞
  2. 原始歌詞行實現,添加分割後的歌詞行集合
  3. 翻譯歌詞實體
  4. 翻譯歌詞行實體,添加分割後的歌詞行集合
  5. 音譯歌詞實體
  6. 音譯歌詞行實體,和原始歌詞行的實體同樣

4歌詞過長換行顯示思路

在上面的歌詞實體,新添加分割後的歌詞行集合。當歌詞內容過長,超出了顯示的view時,歌詞超出的部分會換行顯示。在這裏,我不是在顯示的時候,纔對歌詞進行換行處理的,個人思路以下:

  1. 解析歌詞文件,獲得原始的歌詞集合
  2. 根據view的大小,對歌詞集合中的原始行歌詞,進行分割,獲得換行後的歌詞集合

5多行原始歌詞(包含歌詞過長換行)顯示思路

關於多行歌詞的顯示方式,我在顯示篇的時候,已經講解過,原理也是差很少的。這裏以android爲例子,在文章最後我會貼上個人源碼,以前關於view的平滑移動是使用ValueAnimator的動畫來實現的,我發覺它在實現fling的效果時,並非好理想。因此我就轉用了scroller來實現view的平滑移動,這裏須要注意的是,scroller只作動畫,不要使用它來移動view。我實現的思路以下:

  1. 主要是以分割後歌詞集合做爲繪畫當前歌詞的數據。
  2. 行的高度= (歌詞高度 + 空行高度)* 分割後歌詞的行數
  3. 每行歌詞與所在view的位置綁定,公式:Y=行號*(歌詞高度 + 空行高度)
  4. 動感歌詞行居中顯示,公式:(view的中間值+(歌詞高度 + 空行高度))*0.5 + 移動到當前行號所需的Y值- offsetY
  5. offsetY是從當前歌詞行切換到下一行時,須要的偏移值,公式:offsetY= 移動到【新】行號所需的Y值 - 移動到當前行號所需的Y值
  6. 移動到行號所需的Y值 = 第0個到行號的每行高度累加值。
  7. 歌詞滑動快進時,在計算滑動所在的行號(須要注意行的高度),可經過offsetY值和每行歌詞與view所綁定的位置關係,來計算當前對應的是第幾行歌詞。
  8. 在繪畫歌詞的過程當中,順序須要變一下,存在歌詞過長換行的狀況,因此每行歌詞的Y值會有變化。先繪畫當前歌詞行,計算繪畫分割後的當前行所需的Y值後,再使用該Y值來繪畫當前歌詞行下面的歌詞。

實現效果預覽:

6多行額外歌詞顯示思路

原理和多行原始歌詞顯示差很少,須要注意以下問題:

  1. 音譯歌詞:音譯歌詞由於須要知道每一個【字】的時間,因此須要在原始歌詞的基礎上構造音譯歌詞。
  2. 翻譯歌詞:若是須要像音譯歌詞那樣顯示動感效果,則須要獲取歌詞的持續時間,計算每一個【字】的平均時間,因此也是須要在原始歌詞的基礎上獲取開始時間和結束時間,計算每一個【字】的平均時間。
  3. 移動到行號所需的Y值,須要加上額外歌詞行的高度
  4. 繪畫歌詞時,畫完當前行分割的歌詞後,須要向下畫行對應的分割額外歌詞。最後再向下畫下一行歌詞。在畫當前行歌詞上面的歌詞時,先畫額外歌詞。

實現效果預覽:

7源碼

因爲個人語文水平有限,表達得不清楚,因此,你們若是看不懂或者想更深刻了解,可到個人github上面看源碼。

7.1樂樂音樂Android版本

該版本已經支持和顯示翻譯歌詞和音譯歌詞:https://github.com/zhangliangming/HappyPlayer5.git

7.2樂樂音樂Java Swing PC版

該版本支持顯示多種語言歌詞,而且提供了製做歌詞(包含音譯和翻譯)功能: https://github.com/zhangliangming/HappyPlayer-PC.git

8最後

但願動感歌詞的分析篇、生成篇、解析篇、顯示篇和補充篇對一些想了解或者想實現動感歌詞的讀者有幫助。若有侵權,麻煩告知。

9聯繫方式

316257874@qq.com

相關文章
相關標籤/搜索