[原创]XSLT实现SRT电影字幕修正(加强版) 

2008/9/4 9:23:17


阅读全文(3030) | 回复(0) | 编辑 | 精华

[原创]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="'&#x0A;'"/> <xsl:template match="/">        <!--SRT末尾要保证有3个换行,否则取不到最末字幕。解决:在将文件内容读入DOM前通过程序语言添加3个换行符。或再加一个递归,条件是:string-length($msg) &gt; 1 and not(contains($msg,'&#x0A;&#x0A;'))-->        <!--字幕间隔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,'&#x0A;&#x0A;')"/>         <!--以下两个xsl:if不能解决字幕间隔2n+1个换行符的问题-->        <!--xsl:if test="string-length($sb) &gt; 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,'&#x0A;&#x0A;')">                <xsl:call-template name="msg">                        <xsl:with-param name="msg" select="substring-after($msg,'&#x0A;&#x0A;')" />                </xsl:call-template>        </xsl:if-->         <!--通过xsl:choose来能解决字幕间隔2n+1个换行符的问题-->        <xsl:choose>        <xsl:when test="starts-with($sb,'&#x0A;')"><!--递归,跳过2n+1个换行符-->                <xsl:call-template name="msg">                        <xsl:with-param name="msg" select="substring-after($msg,'&#x0A;')" />                        <xsl:with-param name="pos" select="$pos" />                </xsl:call-template>        </xsl:when>         <xsl:when test="string-length($sb) &gt; 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,'&#x0A;&#x0A;')">                        <xsl:call-template name="msg">                                <xsl:with-param name="msg" select="substring-after($msg,'&#x0A;&#x0A;')" />                                <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 &lt; 3">                                <xsl:value-of select="substring-before($msg1,'&#x0A;')" />                        </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\-103,数值为调整序号用--><!--序号--><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="' --&gt; '"/><!--箭头-->                        <!--xsl:value-of select="substring-after($sb1,'&gt; ')"/-->                        <xsl:call-template name="timefix">                                <xsl:with-param name="time" select="substring-after($sb1,'&gt; ')" />                                <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 &lt; 3">                <xsl:call-template name="msg1">                        <xsl:with-param name="msg1" select="substring-after($msg1,'&#x0A;')" />                        <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

Qr

Posted by Qr on 2008/9/4 9:23:17


发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)
站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.031 second(s), page refreshed 144783201 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号