Support importing lyrics

- Use inline "#LYRIC" lines in tja files
- "LYRICS:" in tja metadata can point to a vtt file, this overrides "#LYRIC"
This commit is contained in:
LoveEevee 2020-03-31 15:50:27 +03:00
parent b4dcd76f90
commit 51bd6cec63
6 changed files with 58 additions and 11 deletions

View File

@ -99,8 +99,9 @@
font-weight: bold; font-weight: bold;
font-size: calc(45px * var(--scale)); font-size: calc(45px * var(--scale));
line-height: 1.2; line-height: 1.2;
white-space: pre-wrap;
} }
#game.portrait{ #game.portrait #song-lyrics{
right: calc(20px * var(--scale)); right: calc(20px * var(--scale));
left: calc(20px * var(--scale)); left: calc(20px * var(--scale));
} }

View File

@ -57,9 +57,14 @@ class Controller{
if(song.id == this.selectedSong.folder){ if(song.id == this.selectedSong.folder){
this.mainAsset = song.sound this.mainAsset = song.sound
this.volume = song.volume || 1 this.volume = song.volume || 1
if(song.lyricsData && !multiplayer && (!this.touchEnabled || this.autoPlayEnabled)){ if(!multiplayer && (!this.touchEnabled || this.autoPlayEnabled)){
var lyricsDiv = document.getElementById("song-lyrics") if(song.lyricsData){
this.lyrics = new Lyrics(song.lyricsData, selectedSong.offset, lyricsDiv) var lyricsDiv = document.getElementById("song-lyrics")
this.lyrics = new Lyrics(song.lyricsData, selectedSong.offset, lyricsDiv)
}else if(this.parsedSongData.lyrics){
var lyricsDiv = document.getElementById("song-lyrics")
this.lyrics = new Lyrics(this.parsedSongData.lyrics, selectedSong.offset, lyricsDiv, true)
}
} }
} }
}) })
@ -231,20 +236,27 @@ class Controller{
resolve() resolve()
}else{ }else{
var songObj = assets.songs.find(song => song.id === this.selectedSong.folder) var songObj = assets.songs.find(song => song.id === this.selectedSong.folder)
var promises = []
if(songObj.chart && songObj.chart !== "blank"){ if(songObj.chart && songObj.chart !== "blank"){
var reader = new FileReader() var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => { promises.push(pageEvents.load(reader).then(event => {
this.songData = event.target.result.replace(/\0/g, "").split("\n") this.songData = event.target.result.replace(/\0/g, "").split("\n")
resolve() return Promise.resolve()
}) }))
if(this.selectedSong.type === "tja"){ if(this.selectedSong.type === "tja"){
reader.readAsText(songObj.chart, "sjis") reader.readAsText(songObj.chart, "sjis")
}else{ }else{
reader.readAsText(songObj.chart) reader.readAsText(songObj.chart)
} }
}else{
resolve()
} }
if(songObj.lyricsFile){
var reader = new FileReader()
promises.push(pageEvents.load(reader).then(event => {
songObj.lyricsData = event.target.result
}), songObj.lyricsFile.webkitRelativePath)
reader.readAsText(songObj.lyricsFile)
}
Promise.all(promises).then(resolve)
} }
}).then(() => { }).then(() => {
var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled) var taikoGame = new Controller(this.selectedSong, this.songData, this.autoPlayEnabled, false, this.touchEnabled)

View File

@ -260,6 +260,15 @@
id: 1 id: 1
} }
} }
if(meta.lyrics){
var lyricsFile = this.normPath(this.joinPath(dir, meta.lyrics))
if(lyricsFile in this.otherFiles){
songObj.lyrics = true
songObj.lyricsFile = this.otherFiles[lyricsFile]
}
}else if(meta.inlineLyrics){
songObj.lyrics = true
}
for(var id in allStrings){ for(var id in allStrings){
var songTitle = songObj.title var songTitle = songObj.title
var ura = "" var ura = ""

View File

@ -137,6 +137,13 @@ class LoadSong{
reader.readAsText(songObj.chart) reader.readAsText(songObj.chart)
} }
} }
if(songObj.lyricsFile){
var reader = new FileReader()
this.addPromise(pageEvents.load(reader).then(event => {
songObj.lyricsData = event.target.result
}), songObj.lyricsFile.webkitRelativePath)
reader.readAsText(songObj.lyricsFile)
}
}else{ }else{
var url = this.getSongPath(song) var url = this.getSongPath(song)
this.addPromise(loader.ajax(url).then(data => { this.addPromise(loader.ajax(url).then(data => {

View File

@ -1,5 +1,5 @@
class Lyrics{ class Lyrics{
constructor(file, songOffset, div){ constructor(file, songOffset, div, parsed){
this.div = div this.div = div
this.stroke = document.createElement("div") this.stroke = document.createElement("div")
this.stroke.classList.add("stroke") this.stroke.classList.add("stroke")
@ -12,7 +12,7 @@ class Lyrics{
this.songOffset = songOffset || 0 this.songOffset = songOffset || 0
this.vttOffset = 0 this.vttOffset = 0
this.rLinebreak = /\n|\r\n/ this.rLinebreak = /\n|\r\n/
this.lines = this.parseFile(file) this.lines = parsed ? file : this.parseFile(file)
this.length = this.lines.length this.length = this.lines.length
} }
parseFile(file){ parseFile(file){

View File

@ -84,6 +84,8 @@
} }
}else if(name.startsWith("branchstart") && inSong){ }else if(name.startsWith("branchstart") && inSong){
courses[courseName].branch = true courses[courseName].branch = true
}else if(name.startsWith("lyric") && inSong){
courses[courseName].inlineLyrics = true
} }
}else if(!inSong){ }else if(!inSong){
@ -411,6 +413,18 @@
} }
branchObj[branchName] = currentBranch branchObj[branchName] = currentBranch
break break
case "lyric":
if(!this.lyrics){
this.lyrics = []
}
if(this.lyrics.length !== 0){
this.lyrics[this.lyrics.length - 1].end = ms
}
this.lyrics.push({
start: ms,
text: value.trim()
})
break
} }
}else{ }else{
@ -545,6 +559,10 @@
this.scoreinit = autoscore.ScoreInit; this.scoreinit = autoscore.ScoreInit;
this.scorediff = autoscore.ScoreDiff; this.scorediff = autoscore.ScoreDiff;
} }
if(this.lyrics){
var line = this.lyrics[this.lyrics.length - 1]
line.end = Math.max(ms, line.start) + 5000
}
return circles return circles
} }
} }