티스토리 뷰

smi 확장자는 xml에서 파생되었지만, xml 규격으로 읽을수 없게 되어있다.
smi를 읽을수 있는 라이브러리로 쓸만한 것도 없다.
정규식을 사용하면 기존 자막파일들에서 비교적 자주 반복되는 규칙을 이용해 파싱할 수 있다.

자바와 as3 는 정규식 함수 RegExr 를 지원한다.

컨셉:
통합자막을 타임틱 기준으로 영어 한줄, 한글 한줄씩 반복되어 나오는 text 파일로 만든다.
  부분 제거 

사용할 정규식 정리
<SYNC> 에서 시작해서 <SYNC> 가 다시 나오기 전까지를 한 블럭으로 설정
/<SYNC[^>]+?>.+?(?=^|<SYNC)/gis

타임 틱 뽑아내기
/(?<=^|<SYNC Start=)\w+?(?=>|$)/is
SYNC 테그 제거
/<SYNC[^<]+?>/is

언어 정보 뽑아내기
/(?<=^|<P Class=)\w+?(?=>|$)/is
언어 테그 제거
/<P[^<]+?>/is


파일 구조
fileManager.as - 파일 입출력 용
TF_SMIConverter.as - 자막 변환 처리와 환경세팅
TF_SMIConverter.fla - 버튼, 텍스트박스 등 그래픽이 들어있는 파일
 

fileManager.as
package {

import flash.events.*;

import flash.net.*;

public class fileManager extends EventDispatcher{

public var textValue:String;

private var MyFile:FileReference = new FileReference();

private var fileName:String = "filename.txt";

public function fileManager() {

}

private function openFileHandler(e) {

MyFile.addEventListener(Event.COMPLETE, fileLoadHandler);

MyFile.load();

MyFile.removeEventListener(Event.SELECT, openFileHandler);

}

private function fileLoadHandler(e:Event) {

textValue = new String(e.currentTarget.data);

//MyTextField.text = textValue.toString();

dispatchEvent(new Event("TFcomplite"));

MyFile.removeEventListener(Event.COMPLETE, fileLoadHandler);

}

//---------------------------------------------------------------------

public function newFile() {

var tempXml:String = "";

textValue = tempXml;

dispatchEvent(new Event("TFcomplite"));

}

public function fileLoad() {

var docFilter:FileFilter = new FileFilter("Àڸ· ÆÄÀÏ(*.smi;*.html;*.txt)", "*.smi;*.html;*.txt");

MyFile.addEventListener(Event.SELECT, openFileHandler);

MyFile.browse([docFilter]);

}

public function fileSave() {

if(textValue == null){

trace("can't save.");

return;

}

MyFile.save(textValue, fileName);

}

}

}


TF_SMIConverter.as
package {

import fl.controls.Button;

import fl.controls.ComboBox;

import fl.controls.TextArea;

import fl.controls.TextInput;

import fl.controls.List;


import flash.display.DisplayObject;

import flash.display.Sprite;

import flash.events.Event;

import flash.events.MouseEvent;

import flash.events.ProgressEvent;

import flash.text.Font;

import flash.text.TextFormat;

import fl.data.DataProvider;

import flash.system.System;

import flashx.textLayout.formats.FormatValue;


import flash.events.TimerEvent;

import flash.external.ExternalInterface;


public class TF_SMIConverter extends Sprite {

System.useCodePage = true;

private var _filemanager:fileManager = new fileManager();

public var btn_new:Button = new Button();

public var btn_open:Button = new Button();

public var btn_save:Button = new Button();


public var outPutText:TextArea = new TextArea();


public function TF_SMIConverter() {

btn_new.addEventListener(MouseEvent.CLICK, newfileHandler);

btn_open.addEventListener(MouseEvent.CLICK, openHandler);

btn_save.addEventListener(MouseEvent.CLICK, saveHandler);

outPutText.text = "TF SMI Converter ver1.0\n" +

"SMI 파일을 대본 형태의 텍스트 파일로 바꾸기\n"+

"타임 틱을 기준으로 영문과 한글 자막을 순차적으로 출력";

}

private function xmlLoadHandler(e) {

//sysMassage.text = "successfully opened";

setChilds();

}

private function newfileHandler(e) {

_filemanager.addEventListener("TFcomplite",xmlLoadHandler);

_filemanager.newFile();

}

private function openHandler(e) {

outPutText.text = "자막을 불러오는 중...";

_filemanager.addEventListener("TFcomplite",xmlLoadHandler);

_filemanager.fileLoad();

}

private function saveHandler(e) {

var savetext:String = outPutText.text;

savetext = savetext.replace( /\n|\r/g, "\r\n" );

_filemanager.textValue = savetext;

_filemanager.fileSave();

}

private function setChilds() {

//처리

var txtcontainer:Array = new Array();

var smitext:String = _filemanager.textValue;

//<SYNC> 에서 시작해서 <SYNC> 가 다시 나오기 전까지를 한 블럭으로 설정

var emailRegExp:RegExp = /<SYNC[^>]+?>.+?(?=^|<SYNC)/gis;

var catches:Array = smitext.match(emailRegExp);

for( var j:String in catches ) {

var str: String = catches[j];

//타임 틱 뽑아내기

var pattern1:RegExp = /(?<=^|<SYNC Start=)\w+?(?=>|$)/is;

var timetic:Number = Number(str.match(pattern1));

//언어 정보 뽑아내기

var pattern2:RegExp = /(?<=^|<P Class=)\w+?(?=>|$)/is;

var langinfo:String = String(str.match(pattern2));

//SYNC 테그 제거

     str = str.replace( /<SYNC[^<]+?>/is, "" );

//언어 테그 제거

   str = str.replace( /<P[^<]+?>/is, "" );

     str = str.replace( /\r|\n/g, "" );

//해당 라인이 내용없는 라인일때 넘어간다.

if(str.replace(/\s+/g,"") == "&nbsp;" || str == "") continue;

txtcontainer.push( [timetic,langinfo,str] );

}

//틱을 기준으로 정렬

txtcontainer.sort(orderTimeTic);

//출력

var htmlText:String = new String();

for( var smiLine:String in txtcontainer ) {

htmlText += txtcontainer[smiLine][2] + "\n";

if(txtcontainer[smiLine][1] == "ENCC") htmlText += "\n";

}

//ExternalInterface.call("outPutSmiText()",htmlText);

outPutText.htmlText = htmlText;

//outPutText.htmlText = txtcontainer.join("\n");

}

private function orderTimeTic(a:*,b:*):int {

if (a[0] < b[0]) { 

return -1; 

} else if (a[0] > b[0]) { 

return 1; 

} else { 

return 0; 

}

}

}


Flash cs5 로 만들었습니다.

swf 직접 실행해서 사용하실때는 로컬보안설정이 필요할 수 있습니다.
(구글링해보세요. flash 로컬 보안 설정)

자막 파일에 따라서 영어가 먼저 나오거나, 한글이 먼저나오거나 순서가 변할 수 있습니다.(자막 파일안의 타임 틱을 기준으로 하기 때문에 그렇습니다.)

혹시나 퍼가신다면 http://mhugt.tistory.com 출처 달아주시면 감사하겠습니다.


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함