2005年3月6日 星期日

Flash mp3撥放歌詞與聲音同步實作

一.聲音與歌詞同步原理:
只要能先對準備好的每句歌詞設定TimeCode,利用setInterval不斷偵測歌曲目前撥放狀況(Sound.position)
當播放時間與歌詞的timecode相同時,即將歌詞show出
二.歌詞檔製作
利用Google可以找到Free的lyricShow或lyricMake等軟體,這是目前用來製作mp3 player歌詞檔用的軟體
產生lrc檔其內容會像以下格式存在
[00:28.05]縱然是往事如雲煙
[00:34.41]偶然你也會想起
[00:40.91]那一段卿卿我我日子裡
[00:47.42]總有一些值得你回憶
[00:57.38]縱然是註定要分離
[01:03.87]偏偏想見你一面
[01:10.45]明知道海誓山盟已過去
[01:16.98]只有默默懷念著你
[01:23.46]雖然萬山相隔離
[01:29.95]千水望無際
[01:36.62]我也會寄語白雲
[01:43.19]祝福你永遠幸福
為了要在flash內以loadVar讀入,把以上修改為
lyric=
[00:28.05]縱然是往事如雲煙
[00:34.41]偶然你也會想起
[00:40.91]那一段卿卿我我日子裡
[00:47.42]總有一些值得你回憶
[00:57.38]縱然是註定要分離
[01:03.87]偏偏想見你一面
[01:10.45]明知道海誓山盟已過去
[01:16.98]只有默默懷念著你
[01:23.46]雖然萬山相隔離
[01:29.95]千水望無際
[01:36.62]我也會寄語白雲
[01:43.19]祝福你永遠幸福
在flash讀入時,即是把整個含timecode的歌詞放在lyric這變數中
三.程式碼分析
包含5個function
1.function loadSong():用來載入外部歌曲聲音檔
2.function loadLyric(lyricName):用來載入外部歌詞檔
並加以剖析,剖析完將得到的歌詞與timecode分別存在
word_array與time_array兩個陣列內
3.function checkPlaytime():利用這個函式判斷目前歌曲播到的時間點
是否有與time_array內時間有相同的,若有相同則執行
歌詞顯示(showLyric())
4.function showLyric():歌詞顯示,這裡只是簡單的把歌詞帶到stage上的
show_word變數,若要做其他變化,在此function內變化即可
5.function init():各種條件初始化


四.完整程式碼
function loadSong(songName){
song=new Sound();
time_index=0;
song.onLoad=function(){
this.start(0,false);
};
song.loadSound(songName,false);
}
function loadLyric(lyricName){
myload=new LoadVars();
myload.load(lyricName);
myload.onLoad=function(){
var buffer_array=myload.lyric.split("[");
time_array=new Array();
word_array=new Array();
for(var i=0;i<buffer_array.length;i++){<br />
var tmp=buffer_array[i].split("]");
if(tmp[0]!=null&&tmp[1]!=null){
var time_buffer=tmp[0].split(":");
time_buffer=Number(time_buffer[1])*1000+Number(time_buffer[0])*60000;
time_array.push(time_buffer);
word_array.push(tmp[1]);
}
};
}
}
function checkPlaytime(){
if(song.position>(time_array[time_index])){
showLyric();
if(time_index<time_array.length-1){<br />
time_index++;
}else{
clearInterval(play_id);
}
}
}
function showLyric(){
show_word=word_array[time_index];
}

function init(){
System.useCodepage=true;
loadSong("song.mp3");
loadLyric("lyric.lrc");
play_id=setInterval(checkPlaytime,100);
}
init();

沒有留言: