반응형
사실 자막을 입힌다기보다 레이어를 얹고 레이어의 투명도를 조정한뒤 그 레이어에 문자를 적어넣는 방식입니다. 물론 자바스크립트를 이용한 기술이긴하지만 기존에 setInterval등의 외부에서 작동되는식의 시스템콜을 방법을 활용한것입니다.
일단 자바스크립트만으로 파일을 읽는것 자체가 매우 위험한 요소이기때문에(엑티브x를 이용하지 않기위함) php를 활용하여 자막을 읽습니다. php를 활용한다는것자체가 서버쪽에 부담이 되긴하지만 자막이 그렇게 긴것도 아니고 루프를 한번만 돌면 끝나기때문에 그리 큰 문제는 아닙니다.
먼저 php 코드부분입니다.
<?
header('Content-Type: text/html; charset= UTF-8');
$id = $_POST["id"];
$smi_name = $_POST["smi_name"];
$filepath = "../User/".$id."/".$smi_name;
echo $filepath;
$fp = fopen($filepath , "r");
if(!$fp){
echo "못읽음";
die;
}
$index = -1; //행의 개수
$col_time = 0; //시간을 담는 행
$col_text = 1; //문자를 담는 행
$text = "";
echo "<textarea id='smi_box'>";
while(!feof($fp)){
$line = fgets($fp , 1024);
$encoding = iconv('EUC-KR','UTF-8',$line)==$line ? 'UTF-8' : 'EUC-KR'; //인코딩 정보 확인
if($encoding == "EUC-KR"){
$line = iconv('EUC-KR' , 'UTF-8' , $line);
}
//대소문자를 가리지않고 <sync를 찾음
if(stristr($line , "<sync")){
$index++;
$text = "";
$start = strpos($line , "=")+1;
$end = strpos($line , ">");
$time = substr($line , $start , $end-$start);
if(strchr($time , " ")){
$time = substr($time ,0, strpos($time , " "));
}
$smi[$index][$col_time] = $time;
$text = strstr($line , ">");
$smi[$index][$col_text] = substr($text , 1 , strlen($text));
}else{
$smi[$index][$col_text] = $smi[$index][$col_text].$line;
}
}
for($i=0; $i<$index; $i++){
echo "$!".$smi[$i][$col_time]."$/".$smi[$i][$col_text]."\n";
}
echo "</textarea>";
?>
자막을 가져오는 첫번째 단계는 textarea내부에 자막을 서술합니다. 이렇게한후 자바스크립트로 해당 값을 참조해서 자막을 읽을수 있기때문입니다. 코드는 별로 어려운것이 아니나 인코딩설정부분은 유의깊게 봐주시길 바랍니다. 문서들이 여러개의 인코딩으로 되어있기때문에 인코딩만 잘못하면 한글이 깨지기 쉽상입니다.
textarea에 적히는 자막은 $!시간$/자막\n 으로 적혀지며 이렇게 $! , $/를 주는 이유는 자바스크립트로 이것들을 스플릿하기 위해서입니다.
이제 자바스크립트 코드부분입니다.
function get_smi(){
var text = document.getElementById("smi_box").value;
smi_ary = text.split("$!");
var smi = new Array(smi_ary.length);
for(var i=1; i<smi_ary.length; i++){
time_text = smi_ary[i].split("$/");
smi[i-1] = new Array(2);
smi[i-1][0] = time_text[0];
smi[i-1][1] = time_text[1];
}
localStorage.setObject("smi" , smi);
}
[로컬스토리지는 기본적으로 key-value이므로 객체를 담기위해서는 프로퍼티 확장해야합니다]
<스토리지에 객체를 담을 수 있도록 확장>
Storage.prototype.setObject = function(key , value){
this.setItem(key , JSON.stringify(value));
};
Storage.prototype.getObject = function(key){
return this.getItem(key) && JSON.parse(this.getItem(key));
};
이제 자막을 영상의 시간에 맞추어 재생시키는 일만 남았습니다. 다생스럽게도 video태그에 timeupdate라는 이벤트때문에 아주 쉽게 구현이 가능합니다.... 만, 매번 이벤트가 실행될때마다 자막의 개수만큼 반복문을 돌려야하는 절차가 있기때문에 그닥 좋지 않은 알고리즘임을 먼저 말씀드립니다^^;;
function stat_smi(){
var subtitle = document.getElementById("subtitle");
subtitle.innerHTML = "";
var video = document.getElementById("player");
video.addEventListener("timeupdate" , function(){
//시간을 밀리세컨드단위까지만 표현해야함.
var time = Math.floor(video.currentTime)*1000;
var smi = localStorage.getObject("smi");
if(!smi) return;
for(var i=0; i<smi.length; i++){
var smi_sec = Math.floor(smi[i][0]/1000)*1000;
if(time == smi_sec){
subtitle.innerHTML = smi[i][1];
}
}
});
}
이것으로 자막입히기 끝입니다. ㅋ
자막입힌 영상 모습입니다.
'Lecture > Javascript-기초' 카테고리의 다른 글
문자열 관련 함수 (0) | 2012.07.02 |
---|---|
모바일 브라우저 체크 (0) | 2012.06.29 |
자바스크립트를 이용한 CSS 제어 (2) | 2012.06.25 |
javascript를 이용한 HTML객체 생성 (0) | 2012.06.17 |
[본격 게시판짜기 Part1.3 - Dom 맛보기 ] 글입력폼 검사 (39) | 2012.06.13 |