Created
February 20, 2012 13:55
-
-
Save notyy/1869326 to your computer and use it in GitHub Desktop.
2D字幕文件转3D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
本程序逻辑如下: | |
1、列出当前目录下所有后缀名为srt的文件,过滤掉其中文件名以-3D结尾的文件 | |
2、对每个符合条件1的文件,读取其内容,通过在字幕内容中加入坐标偏移量,使之能在左右屏的3D电视上正常播放 | |
3、srt文件格式 | |
1、文件由多个段落组成,段落之间以空行分隔 | |
2、每段落中的内容由3部分组成 | |
1、序号 | |
2、时间量 | |
3、字幕内容 | |
4、转换逻辑是将原字幕内容分别在前面加上偏移量{\pos(96,255)\fscx50}和{\pos(288,255)\fscx50},变成两段内容,一个序号保持不变,位置也不变,而另一段必须加到原内容最后,序号递增 | |
举例如下: | |
1 | |
00:00:46,171 --> 00:00:48,340 | |
《每日快讯》 | |
2 | |
00:00:56,181 --> 00:00:57,015 | |
请稍等 | |
经过转换后应为 | |
1 | |
00:00:46,171 --> 00:00:48,340 | |
{\pos(96,255)\fscx50}《每日快讯》 | |
2 | |
00:00:56,181 --> 00:00:57,015 | |
{\pos(96,255)\fscx50}请稍等 | |
3 | |
00:00:46,171 --> 00:00:48,340 | |
{\pos(288,255)\fscx50}《每日快讯》 | |
4 | |
00:00:56,181 --> 00:00:57,015 | |
{\pos(288,255)\fscx50}请稍等 | |
-------------代码------------------------------------ | |
import java.io._ | |
import scala.io._ | |
import scala.collection.JavaConverters._ | |
object MainApp extends App { | |
def files23D() { | |
val files = new File(".").listFiles() filter isValidFile | |
files map to3D | |
} | |
def isValidFile(f: File) = { | |
f.isFile() && !(f.getName.endsWith("-3D.srt")) && f.getName.endsWith(".srt") | |
} | |
def to3D(f: File) { | |
val srcFileName = f.getName.take(f.getName.length - ".srt".length) | |
val toFile = new File("./" ++ srcFileName ++ "-3D" ++ ".srt") | |
toFile.createNewFile() | |
val writer = new BufferedWriter(new FileWriter(toFile)) | |
writer.write(convert(Source.fromFile(f).getLines)) | |
writer.flush() | |
writer.close() | |
} | |
case class Section(id: Option[String], timeline: Option[String], contents: Option[String]) | |
def convert(lines: Iterator[String]): String = { | |
val sections = extractSections(lines).tail.reverse | |
val maxId = sections.length | |
val offseted = sections map (offset(maxId, _)) | |
val resultSections = fst(offseted) ++ snd(offseted) | |
(resultSections map (sectionToString)).mkString | |
} | |
def extractSections(strIter: Iterator[String]): List[Section] = { | |
strIter.foldLeft(List[Section]()) { (rsSections, line) => | |
(rsSections, line) match { | |
case (List(), l) => Section(Some(l), None, None) :: List() | |
case (Section(Some(id), None, None) :: ss, l) => Section(Some(id), Some(l), None) :: ss | |
case (Section(Some(id), Some(timel), None) :: ss, l) => Section(Some(id), Some(timel), Some(l)) :: ss | |
case (Section(Some(id), Some(timel), Some(content)) :: ss, l) if (!l.isEmpty()) => Section(Some(id), Some(timel), Some(content ++ "\n" ++ l)) :: ss | |
case (ss, l) if (l.isEmpty()) => Section(None, None, None) :: ss // if a blank line | |
case (Section(None, None, None) :: ss, l) => Section(Some(l), None, None) :: ss | |
} | |
} | |
} | |
def offset(mid: Int, sec: Section): (Section, Section) = (mid, sec) match { | |
case (mid, Section(Some(id), Some(timel), Some(contents))) => { | |
val left = Section(Some(id), Some(timel), Some("{\\pos(96,255)\\fscx50}" ++ contents)) | |
val newId: Int = id.toInt + mid | |
val right = Section(Some(newId.toString()), Some(timel), Some("{\\pos(288,255)\\fscx50}" ++ contents)) | |
(left, right) | |
} | |
case (_, Section(None, None, None)) => throw new IllegalArgumentException("error offset") | |
} | |
def sectionToString(sec: Section): String = sec match { | |
case (Section(Some(id), Some(timel), Some(contents))) => id ++ "\n" ++ timel ++ "\n" ++ contents ++ "\n\n" | |
case _ => throw new IllegalArgumentException("error sectionToString") | |
} | |
def fst[A, B](l: List[(A, B)]): List[A] = l map (_._1) | |
def snd[A, B](l: List[(A, B)]): List[B] = l map (_._2) | |
override def main(args: Array[String]) { | |
files23D() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment