1

我正在开发一个 Web 应用程序,它可以接收时间文本标记(TTML)或WebVTT格式的字幕文件。如果文件是定时文本,我想把它翻译成 WebVTT。这基本上不是问题,我遇到的一个问题是,如果 TTML 将 HTML 作为文本内容的一部分,那么 HTML 标记就会被删除。

例如:

<p begin="00:00:08.18" dur="00:00:03.86">(Music<br />playing)</p>

结果是:

(Musicplaying)

我使用的代码是:

private const string TIME_FORMAT = "hh\\:mm\\:ss\\.fff";
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(fileLocation);
XDocument xdoc = xmldoc.ToXDocument();
var ns = (from x in xdoc.Root.DescendantsAndSelf()
          select x.Name.Namespace).First();

List<TTMLElement> elements =
(
     from item in xdoc.Descendants(ns + "body").Descendants(ns + "div").Descendants(ns + "p")
     select new TTMLElement
     {
          text = item.Value,
          startTime = TimeSpan.Parse(item.Attribute("begin").Value),
          duration = TimeSpan.Parse(item.Attribute("dur").Value),
     }
).ToList<TTMLElement>();

StringBuilder sb = new StringBuilder();
sb.AppendLine("WEBVTT");
sb.AppendLine();

for (int i = 0; i < elements.Count; i++)
{
     sb.AppendLine(i.ToString());
     sb.AppendLine(elements[i].startTime.ToString(TIME_FORMAT) + " --> " + elements[i].startTime.Add(elements[i].duration).ToString(TIME_FORMAT));
     sb.AppendLine(elements[i].text);
     sb.AppendLine();
}

任何关于我遗漏的想法,或者是否有更好的方法,或者即使已经有将时间文本转换为 WebVTT 的解决方案,我们都将不胜感激。谢谢。

4

2 回答 2

2

我终于回到了这个项目,我也找到了解决我的问题的方法。

本节首先介绍:

from item in xdoc.Descendants(ns + "body").Descendants(ns + "div").Descendants(ns + "p")
    select new TTMLElement
    {
        text = item,
        startTime = TimeSpan.Parse(item.Attribute("begin").Value),
        endTime = item.Attribute("dur") != null ?
          TimeSpan.Parse(item.Attribute("begin").Value).Add(TimeSpan.Parse(item.Attribute("dur").Value)) :
          TimeSpan.Parse(item.Attribute("end").Value)
   }

item 是 XElement 类型,因此可以从中创建 XmlReader 对象,从而产生以下函数:

private static string ReadInnerXML(XElement parent)
{
    var reader = parent.CreateReader();
    reader.MoveToContent();
    var innerText = reader.ReadInnerXml();
    return innerText;
}

为了删除节点内的 html,我将函数修改为如下所示:

private static string ReadInnerXML(XElement parent)
{
    var reader = parent.CreateReader();
    reader.MoveToContent();
    var innerText = reader.ReadInnerXml();
    innerText = Regex.Replace(innerText, "<.+?>", " ");
    return innerText;
}

最后导致上面的 lambda 看起来像这样:

from item in xdoc.Descendants(ns + "body").Descendants(ns + "div").Descendants(ns + "p")
    select new TTMLElement
    {
        text = ReadInnerXML(item),
        startTime = TimeSpan.Parse(item.Attribute("begin").Value),
        endTime = item.Attribute("dur") != null ?
          TimeSpan.Parse(item.Attribute("begin").Value).Add(TimeSpan.Parse(item.Attribute("dur").Value)) :
          TimeSpan.Parse(item.Attribute("end").Value)
   }
于 2013-08-08T15:05:07.290 回答
1

Microsoft 有一个工具可以生成两种格式:

此演示允许您创建简单的视频字幕文件。首先以浏览器可以播放的格式加载视频。然后交替播放和暂停视频,为每个片段输入标题。

如果您为视频保存了 WebVTT 或 TTML 字幕文件,您可以加载它、编辑现有片段的文本或附加新片段。

如果您想以编程方式执行此操作,其他 问题的答案可能会有所帮助。

于 2013-06-14T02:33:06.977 回答