如何将WebVTT格式转换为纯文本?

11

这是WebVTT的示例

WEBVTT
Kind: captions
Language: en
Style:
::cue(c.colorCCCCCC) { color: rgb(204,204,204);
 }
::cue(c.colorE5E5E5) { color: rgb(229,229,229);
 }
##

00:00:00.060 --> 00:00:03.080 align:start position:0%
 
<c.colorE5E5E5>okay<00:00:00.690><c> so</c><00:00:00.750><c> this</c><00:00:01.319><c> is</c><00:00:01.469><c> a</c></c><c.colorCCCCCC><00:00:01.500><c> newsflash</c><00:00:02.040><c> page</c><00:00:02.460><c> for</c></c>

00:00:03.080 --> 00:00:03.090 align:start position:0%
<c.colorE5E5E5>okay so this is a</c><c.colorCCCCCC> newsflash page for
 </c>

00:00:03.090 --> 00:00:08.360 align:start position:0%
<c.colorE5E5E5>okay so this is a</c><c.colorCCCCCC> newsflash page for</c>
<c.colorE5E5E5>Meraki<00:00:03.659><c> printing</c><00:00:05.120><c> so</c><00:00:06.529><c> all</c><00:00:07.529><c> we</c><00:00:08.040><c> need</c><00:00:08.130><c> to</c><00:00:08.189><c> do</c></c>

00:00:08.360 --> 00:00:08.370 align:start position:0%
<c.colorE5E5E5>Meraki printing so all we need to do
 </c>

00:00:08.370 --> 00:00:11.749 align:start position:0%
<c.colorE5E5E5>Meraki printing so all we need to do
here<00:00:08.700><c> is</c><00:00:08.820><c> to</c><00:00:09.000><c> swap</c><00:00:09.330><c> out</c><00:00:09.480><c> the</c><00:00:09.660><c> logo</c><00:00:09.929><c> here</c><00:00:10.650><c> and</c><00:00:10.830><c> I</c></c>

00:00:11.749 --> 00:00:11.759 align:start position:0%
here is to swap out the logo here<c.colorE5E5E5> and I
 </c>

00:00:11.759 --> 00:00:16.400 align:start position:0%
here is to swap out the logo here<c.colorE5E5E5> and I
should<00:00:11.969><c> also</c><00:00:12.120><c> work</c><00:00:12.420><c> on</c><00:00:12.630><c> move</c><00:00:12.840><c> out</c><00:00:13.049><c> as</c><00:00:13.230><c> well</c><00:00:15.410><c> and</c></c>

00:00:16.400 --> 00:00:16.410 align:start position:0%
<c.colorE5E5E5>should also work on move out as well and
 </c>

我使用youtube-dl从YouTube上下载它。

我想将其转换为纯文本。我不能仅仅剥离时间和颜色标签,因为文本会重复出现。

所以我想知道是否存在某种方法将其转换为纯文本,或者是否有人能提供一些伪代码,以便我可以编写代码?

我还向youtube-dl发布了此问题。

3个回答

15
我已经使用WebVTT-py来提取纯文本转录。
import webvtt
vtt = webvtt.read('subtitles.vtt')
transcript = ""

lines = []
for line in vtt:
    # Strip the newlines from the end of the text.
    # Split the string if it has a newline in the middle
    # Add the lines to an array
    lines.extend(line.text.strip().splitlines())

# Remove repeated lines
previous = None
for line in lines:
    if line == previous:
       continue
    transcript += " " + line
    previous = line

print(transcript)

8
命令行在Bash Shell中对我来说效果最好,速度更快、体积更小、简单易用,操作十分高效:
cat myfile.vtt | grep : -v | awk '!seen[$0]++'

使用 -v 反转(即不包含)符号 : (冒号),此 grep 命令移除包含 : 的行。

此 awk 命令移除重复的行。


3

与Terence Eden的答案相同的概念,但是泛化为单个函数。

生成器的魔力提高了这个任务的可读性,并节省了大量内存。通常没有必要将文件中的数据保存在列表或大字符串中进行处理。

因此,至少在这里,webvtt是唯一将整个源文件保存在内存中的部分。

我发现我的文件中也有空格的HTML实体,因此添加了一个简单的替换。并且默认情况下保留换行符。

这是我的版本,包含pathlib、Typing和Generators:

from pathlib import Path
from typing import Generator
import webvtt


def vtt_lines(src) -> Generator[str, None, None]:
    """
    Extracts all text lines from a vtt file which may contain duplicates

    :param src: File path or file like object
    :return: Generator for lines as strings
    """
    vtt = webvtt.read(src)

    for caption in vtt:  # type: webvtt.structures.Caption
        # A caption which may contain multiple lines
        for line in caption.text.strip().splitlines():  # type: str
            # Process each one of them
            yield line


def deduplicated_lines(lines) -> Generator[str, None, None]:
    """
    Filters all duplicated lines from list or generator

    :param lines: iterable or generator of stringsa
    :return: Generator for lines as strings without duplicates
    """
    last_line = ""
    for line in lines:
        if line == last_line:
            continue

        last_line = line
        yield line


def vtt_to_linear_text(src, savefile: Path, line_end="\n"):
    """
    Converts an vtt caption file to linear text.

    :param src: Path or path like object to an existing vtt file
    :param savefile: Path object to save content in
    :param line_end: Default to line break. May be set to a space for a single line output.
    """
    with savefile.open("w") as writer:
        for line in deduplicated_lines(vtt_lines(src)):
            writer.write(line.replace("&nbsp;", " ").strip() + line_end)

# Demo call
vtt_to_linear_text("file.vtt", Path("file.txt"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接