-
speech-text-synchronize기타 2022. 12. 22. 23:25
speech-text-synchronize
WHAT : 재생되는 영상의 Speech와 Text의 sync를 맞추는 것
WHY : 영상의 사운드에 해당하는 대사를 사용자가 인식하기 쉽도록 하기 위해 사용하고자 한다.
HOW : 기술적으로 어떻게 구현할 수 있나?- Sync Audio With Text Using Javascript : https://growth-msleeffice.tistory.com/80
하단의 내용은 "영상"이 아니라 "오디오"에 적용하기 좋은 방법이다.
영상과 dialog의 sync에 vtt를 활용할 수 있는 방법이 있어 상기 내용으로 대체함.
1. LRC 파일 + lrc-parser(npm module) + Audio Sync With text (npm module)
1.0 Logic
- 영상 관련 대본을 LRC 파일 포맷으로 저장
- lrc-parser로 해당 데이터를 JSON 형태로 바꾸어 front로 전송
- front에서 영상 재생 시 audioSync 모듈을 활용, 로직 구현
1.1 LRC (출처 : https://ko.wikipedia.org/wiki/LRC_(파일_포맷))
- 정의 LRC는 MP3나 OGG, MIDI와 같은 음악 파일과 동시에 동작되는 노랫말을 담은 파일 확장자이다. .lrc로 된 확장자를 사용하며 일반적으로 그 음악 파일과 동일한 이름으로 존재한다. 예를 들면 노래.mp3와 노래.lrc 식으로 존재한다. LRC 포맷은 텍스트를 기반으로 하고 있으며 자막 파일과 비슷하다.
- 파일포맷
- 심플 포맷
- 강화 포맷
- ``` **- 강화된 LRC 포맷의 예시** [mm:ss.xx] <mm:ss.xx> 첫 번째 줄 첫 번째 가사 <mm:ss.xx> 첫 번째 줄 두 번째 가사 <mm:ss.xx> ... 첫 번째 줄 마지막 가사 <mm:ss.xx> [mm:ss.xx] <mm:ss.xx> 두 번째 줄 첫 번째 가사 <mm:ss.xx> 두 번째 줄 두 번째 가사 <mm:ss.xx> ... 두 번째 줄 마지막 가사 <mm:ss.xx> ... [mm:ss.xx] <mm:ss.xx> 마지막 줄 첫 번째 가사 <mm:ss.xx> 마지막 줄 두 번째 가사 <mm:ss.xx> ... 마지막 줄 마지막 가사 <mm:ss.xx> ```
- ``` **- 일반적인 예시** [00:12.00]첫 번째 가사 행 [00:17.20]두 번째 가사 행 [00:21.10]세 번째 가사 행 ... [mm:ss.xx]마지막 가사 행 ``` ID태그 일부 플레이어가 무시하거나 가사전에 표시할 수 있음 ``` [ar:가사 아티스트] [al:노래의 앨범] [ti:가사(노래) 제목] [au:가사 작성자] [length:음악의 길이] [by:LRC파일의 작성자] [offset:+/- ms단위로 전체 오브셋조정] [re:LRC를 작성한 플레이어나 편집기] [ve:프로그램 버전] ```
1.2 lrc-parser(npm module)
- 출처 : https://www.npmjs.com/package/lrc-parser-ts) / https://github.com/AdoneZ/lrc-parser#readme
- Parse LRC file into json format, works on both node and browser → LRC 파일을 json 형식으로 구문 분석하고, 노드와 브라우저 모두에서 작동한다.
- Usage
- node.js
- const lrcParser = require('lrc-parser') const fs = require('fs') fs.readFile('havana.lrc', (err, data) => { const data = lrcParser(data.toString('utf8')) })
- Browser
- const file = ... const fileReader = new FileReader() fileReader.addEventListener('load', e => { const data = lrcParser(e.target.result) }) fileReader.readAsText(file)
1.3 Sync Audio With Text Using JavaScript
- 출처 : https://www.npmjs.com/package/audio-sync-with-text / https://github.com/the-codepunker/audio-sync-with-text / https://www.codepunker.com/blog/sync-audio-with-text-using-javascript
- 설명 A client of mine wanted a way to highlight text on a page as audio was playing, thus helping children that had difficulties reading along. In this tutorial I will show you the solution I implemented. My client has some complex XML files that contain data about the media files and text, but for the sake of clarity, in this tutorial I will use a much simpler JSON file which basically contains the text from the audio file and markers that define the start and end time of a word or group of words in the audio track. The code makes use of the timeupdate event and it uses the data from the JSON to sync audio with the text. I am pasting the code below in case you want to use it in your own projects.
- usage
var audioSync = function (options) { var audioPlayer = document.getElementById(options.audioPlayer); var subtitles = document.getElementById(options.subtitlesContainer); var syncData = []; var rawSubTitle = ""; var convertVttToJson = require('vtt-json'); var init = function() { return fetch(new Request(options.subtitlesFile)) .then(response => response.text()) .then(createSubtitle) }(); function createSubtitle(text) { var rawSubTitle = text; convertVttToJson(text) .then((result) => { var x = 0; for (var i = 0; i < result.length; i++) { //cover for bug in vtt to json here if (result[i].part && result[i].part.trim() != '') { syncData[x] = result[i]; x++; } } }); } audioPlayer.addEventListener("timeupdate", function(e){ syncData.forEach(function(element, index, array){ var el; if( (audioPlayer.currentTime*1000) >= element.start && (audioPlayer.currentTime*1000) <= element.end ) { while(subtitles.hasChildNodes()) subtitles.removeChild(subtitles.firstChild) el = document.createElement('span'); el.setAttribute("id", "c_" + index); el.innerText = syncData[index].part + "\\n"; el.style.background = 'yellow'; subtitles.appendChild(el); } }); }); } module.exports = audioSync;
- 기타 조사내용 : ID3(MP3 파일에서 사용하는 메타데이터 포맷에서 SYLT tag활용?)와 JS MediaTags(npm module) 조합으로도 LRC + lrc parser 조합을 대체 할 수 있을 것으로 보았으나, Synchronized lyrictext(SYLT)를 포함한 ID3를 만드는 것은 구현 불가능할 것으로 보임
- JS MediaTags : https://www.npmjs.com/package/jsmediatags / https://github.com/aadsm/jsmediatags
- ID3 Tag 설명 : https://exiftool.org/TagNames/ID3.html#SynLyrics
- ID3 lyric writer : https://github.com/ToPeter/ID3-lyrics-writer → 음성을 text로 transcription
- etc
- Lyricer : 웹페이지에서 LRC 가사를 구문분석하여 보여주는 간단한 라이브러리https://github.com/lusaisai/Lyricer → 오디오의 시간 업데이트 이벤트에 text 이동을 바인딩 할 수 있다. → 반대로, 특정 text 클릭 시 해당 오디오 시간으로 바인딩 할 수 있다.
'기타' 카테고리의 다른 글
컴퓨터가 데이터를 표현하고 이해하는 방식 (0) 2023.04.07 컴퓨터 구조의 큰 그림 (0) 2023.04.06 TTS (0) 2022.12.22 [MAC] 캡스락 대문자 기능 끄기 by. Karabiner-Elements, BTT (0) 2022.10.05