확장자 *.smi를 가지는 자막파일(이른바, SAMI) 를 읽어들이고, 그리고 또한 그 자막파일을 자동으로 작성하는 예제.
NOTE: 글의 끝부분이 깨졌을 경우는, 첨부파일을 다운받아서 보세요.
/////////////////////////////////////////////////////////
Created by Jisang Yoo for the use in 'LanguageMaster'
/////////////////////////////////////////////////////////
class TSubtitle
{
private:
String text[MaxLine]; // 각각 켑션.
int start[MaxLine]; // 각 켑션의 시작시간. milisecond단위.
int FLineCount; //전체 켑션개수.
String __fastcall GetText(int Index);
int __fastcall GetStart(int Index);
int __fastcall GetEnd(int Index);
public:
void LoadFromSamiFile(String filename, String BR = "\n");
void LoadFromSubripFile(String filename);
void LoadFromSubviewer2File(String filename);
void LoadFromMicrodvdFile(String filename, float FPS=25);
void SaveToSamiFile(String filename) const;
TSubtitle();
void Compress();
__property int LineCount = { read=FLineCount };
__property String Text[int Index] = { read=GetText };
__property int Start[int Index] = { read=GetStart };
};
TSubtitle::TSubtitle()
:FLineCount(0)
{}
String __fastcall TSubtitle::GetText(int Index)
{
if (0<=Index && Index<FLineCount)
return text[Index];
else
return String("");
}
int __fastcall TSubtitle::GetStart(int Index)
{
if (0<=Index && Index<FLineCount)
return start[Index];
else
return 0;
}
void TSubtitle::SaveToSamiFile(String filename) const
{
FILE* fp = fopen(filename.c_str(),"w");
if(fp == NULL)
return;
fputs("<SAMI>\n\n
\nAlbert Einstein\n\n\n\n\n",fp);
String Temp, Temp2; int x,sp;
for(int i=0 ; i
\n";
fputs( Temp.c_str() , fp);
Temp = text[i].Trim();
x = 0; // for error check.
while(sp = Temp.Pos("\n") , sp) //
{
if (x++>5)
break; //예외처리 무한루푸 방지
Temp2 = Temp.SubString(1,sp-1);
Temp = Temp2 + "
" + Temp.Delete(1,sp);
}
Temp += "\n";
fputs( Temp.c_str() , fp);
}
fputs("\n</SAMI>\n",fp);
fclose(fp);
}
void TSubtitle::LoadFromSamiFile(String filename, String BR /*= "\n"*/)
{ /* SAMI (*.smi , *.smil)
ex)
<SAMI>
"A Few Good Man"
Captain, I'd like to request that
it be me who's the attorney ...
</SAMI> */
/* SMPlay의 소스코드를 참조하고 변형*/
int i ; char buf[201]; String CurLine, Upper ,Temp; int sp,sp2;
FILE* fp = fopen(filename.c_str(),"r");
if(fp==NULL)
return;
//skip until '
' appears
while (fgets(buf,200,fp))
if (String(buf).UpperCase().AnsiPos("") )
break;
i = 0; start[0] = 0;
while (fgets(buf,200,fp) && i' and reading the 'start[i]'.
if(CurLine.UpperCase().Pos("");
start[i] = CurLine.SubString(sp+1,sp2-sp-1).ToInt();
text[i] = "";
CurLine.Delete(1,sp2);
}
int x = 0; // for error check.
while(Upper = CurLine.UpperCase(), sp = Upper.Pos("&NBSP") , sp) //replacing '&NBSP' or '&NBSP;' with ' '
{
if (x++>5)
break; //예외처리 무한루푸 방지
int len = 5;
if(Upper.SubString(sp,6) == "&NBSP;")
len = 6;
Temp = CurLine.SubString(1,sp-1);
CurLine = Temp + ' ' + CurLine.Delete(1,sp+len-1);;
}
while(sp = CurLine.Pos("<") ,sp) //replacing '
' and deleting '< ????? >'
{
if (x++>5)
break; //예외처리 무한루푸 방지
if(CurLine.SubString(sp,4) == "
" || CurLine.SubString(sp,4) == "
" )
{
//TODO:
Temp = CurLine.SubString(1,sp-1);
CurLine = Temp + BR + CurLine.Delete(1,sp+3);
}
else
{
sp2=Upper.Pos(">");
Temp = CurLine.SubString(1,sp-1);
CurLine= Temp + CurLine.Delete(1,sp2);
}
}
text[i] += CurLine;
}
FLineCount = i+1;
fclose(fp);
}
void TSubtitle::Compress()
{
int k =0;
for(int i=0; i