以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XSL/XSLT/XSL-FO/CSS 』  (http://bbs.xml.org.cn/list.asp?boardid=8)
----  [原创]XSLT实现SRT电影字幕修正(加强版)  (http://bbs.xml.org.cn/dispbbs.asp?boardid=8&rootid=&id=66782)


--  作者: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) &gt; 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) &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,' ')">
                <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) &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,' ')">
                        <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 &lt; 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="' --&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,' ')" />
                        <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



W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
93.994ms