-- 作者:Qr
-- 发布时间:9/4/2008 9:40:00 AM
-- [原创]XSLT实现SRT电影字幕修正(加强版)
[原创]XSLT实现SRT电影字幕修正(加强版) Qr原创:http://blogger.org.cn/blog/more.asp?name=Qr&id=39540 昨天晚上在看一部老电影的过程中发现,第一段的后5分钟字幕被错误的分割到第二段中,导致第一段视频后5分钟无字幕,而第二段声音和字幕完全不同步。在没有上网条件和调整工具的情况下,只能依靠存在我U盘上的XSLT来实现,原文链接:《XSLT实现SRT电影字幕修正》。 Qr原创:http://blogger.org.cn/blog/more.asp?name=Qr&id=39540 然而,在实现调整过程中发现,前文《XSLT实现SRT电影字幕修正》只适用于毫秒级的调整,但是,在这部影片中,需要调整的偏移量达1个小时之多,怎么办?总不能在关键时刻丢面子吧,呵呵!花几分钟改一下代码咯! Qr原创:http://blogger.org.cn/blog/more.asp?name=Qr&id=39540 代码的大部分还是原来的,只是重写了模板timefix的代码,完全解决了时间偏移量的问题,无论时间偏移量的大小。 Qr原创:http://blogger.org.cn/blog/more.asp?name=Qr&id=39540 <?xml version="1.0" encoding="gb2312"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" version="1.0" encoding="gb2312" indent="yes"/> <!--srt实际上是文本文件,故取method="text"--> <xsl:variable name="ms" select="3530553"/><!--1\3530553;2\-333000--> <!--ms以毫秒为单位,1s=1000ms--> <xsl:variable name="br" select="'
'"/> <xsl:template match="/"> <!--SRT末尾要保证有3个换行,否则取不到最末字幕。解决:在将文件内容读入DOM前通过程序语言添加3个换行符。或再加一个递归,条件是:string-length($msg) > 1 and not(contains($msg,'
'))--> <!--字幕间隔2n+1(n>0)个以上的换行符出错。已解决!--> <xsl:call-template name="msg"> <xsl:with-param name="msg" select="." /> <xsl:with-param name="pos" select="1" /> </xsl:call-template> </xsl:template> <xsl:template name="msg"> <xsl:param name="msg"/> <xsl:param name="pos"/> <xsl:variable name="sb" select="substring-before($msg,'
')"/> <!--以下两个xsl:if不能解决字幕间隔2n+1个换行符的问题--> <!--xsl:if test="string-length($sb) > 1"> <xsl:call-template name="msg1"> <xsl:with-param name="msg1" select="$sb" /> <xsl:with-param name="pos1" select="1" /> </xsl:call-template> </xsl:if> <xsl:if test="contains($msg,'
')"> <xsl:call-template name="msg"> <xsl:with-param name="msg" select="substring-after($msg,'
')" /> </xsl:call-template> </xsl:if--> <!--通过xsl:choose来能解决字幕间隔2n+1个换行符的问题--> <xsl:choose> <xsl:when test="starts-with($sb,'
')"><!--递归,跳过2n+1个换行符--> <xsl:call-template name="msg"> <xsl:with-param name="msg" select="substring-after($msg,'
')" /> <xsl:with-param name="pos" select="$pos" /> </xsl:call-template> </xsl:when> <xsl:when test="string-length($sb) > 1"> <xsl:call-template name="msg1"> <xsl:with-param name="msg1" select="$sb" /> <xsl:with-param name="pos1" select="1" /> <xsl:with-param name="pos" select="$pos" /> </xsl:call-template> <xsl:if test="contains($msg,'
')"> <xsl:call-template name="msg"> <xsl:with-param name="msg" select="substring-after($msg,'
')" /> <xsl:with-param name="pos" select="$pos+1" /> </xsl:call-template> </xsl:if> </xsl:when> </xsl:choose> </xsl:template> <xsl:template name="msg1"> <xsl:param name="msg1"/> <xsl:param name="pos1"/> <xsl:param name="pos"/> <xsl:variable name="sb1"> <xsl:choose> <xsl:when test="$pos1 < 3"> <xsl:value-of select="substring-before($msg1,'
')" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$msg1" /> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:choose> <xsl:when test="$pos1=1"> <xsl:value-of select="690 + $sb1"/><!--1\690;2\-10,数值为调整序号用--><!--序号--><xsl:value-of select="$br"/> <xsl:if test="$sb1 != $pos"> <xsl:message terminate="yes"> <xsl:value-of select="'message:ERROR'"/> </xsl:message> </xsl:if> </xsl:when> <xsl:when test="$pos1=2"> <xsl:call-template name="timefix"> <xsl:with-param name="time" select="substring-before($sb1,' ')" /> <xsl:with-param name="pos" select="$pos" /> </xsl:call-template> <xsl:value-of select="' --> '"/><!--箭头--> <!--xsl:value-of select="substring-after($sb1,'> ')"/--> <xsl:call-template name="timefix"> <xsl:with-param name="time" select="substring-after($sb1,'> ')" /> <xsl:with-param name="pos" select="$pos" /> </xsl:call-template> <xsl:value-of select="$br"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$sb1"/><xsl:value-of select="concat($br,$br)"/> </xsl:otherwise> </xsl:choose> <xsl:if test="$pos1 < 3"> <xsl:call-template name="msg1"> <xsl:with-param name="msg1" select="substring-after($msg1,'
')" /> <xsl:with-param name="pos1" select="$pos1+1" /> <xsl:with-param name="pos" select="$pos" /> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="timefix"> <xsl:param name="time"/> <xsl:param name="pos"/> <xsl:variable name="h" select="substring($time,1,2)"/> <xsl:variable name="m" select="substring($time,4,2)"/> <xsl:variable name="s" select="substring($time,7,2)"/> <xsl:variable name="u" select="substring($time,10)"/> <xsl:variable name="msbac" select="($h * 3600 + $m * 60 + $s) * 1000"/> <xsl:variable name="msfix" select="$msbac + $ms"/> <xsl:variable name="h1" select="format-number(floor($msfix div 3600000),'00')"/> <xsl:variable name="m1" select="format-number(floor(($msfix mod 3600000) div 60000),'00')"/> <xsl:variable name="s1" select="format-number(floor((($msfix mod 3600000) mod 60000) div 1000),'00')"/> <xsl:variable name="u1" select="format-number(($msfix mod 3600000) mod 1000,'000')"/> <xsl:value-of select="concat($h1,':',$m1,':',$s1,',',$u1)"/> </xsl:template> </xsl:stylesheet> Qr原创:http://blogger.org.cn/blog/more.asp?name=Qr&id=39540
|