

# 如何在长篇 YouTube 讲座中找到某个概念的讲解

根据字幕时间制作一份小型概念索引。然后观看视频中的每个候选时段。词语匹配可以表明某处提到了概念，但不能证明那里对概念作了解释。

这份索引是你自己制作的导航工具。它不是视频作者编写的章节列表，不是剪辑出来的视频片段，不是整段视频的摘要，也不是搜索分块方案。

## 1. 先写下学习问题

浏览字幕全文前，先写一句话。明确要找的概念，补充教师可能使用的其他词语，并说明你需要哪种类型的答案。

可以使用以下答案类型：

- 定义：说明概念的含义或具体做法。
- 例题详解：逐步解答一个具体案例。
- 操作步骤：按顺序展示各项操作。
- 比较：将两个概念并列对照。
- 适用限制：说明概念的适用边界。

要明确区分：“提到测量”不等于“解释如何测量”。你写的句子应说明自己需要哪一种。

## 2. 获取一条字幕轨道

字幕是视频已有的、带有时间信息的文本。字幕全文是一个视频全部字幕的汇总。字幕片段是其中一行带有时间信息的字幕。每个字幕片段都有文本、开始时间和持续时长。持续时长是指这行字幕持续显示的时间。

时段是你为某个概念选定的起止时间范围。阅读字幕片段后，再选择时段。

Actor 是一个托管运行的程序，用于采集来源数据行。每个来源数据行对应一个视频结果。Task 是保存好的输入预设。Actor 只负责采集数据行。概念相关的分析由你根据这些数据行完成。

使用 YouTube Transcript 0.1.43 版本。对应的 Actor 是 [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)。公开的 Task 是 [YouTube Transcript Data for Video Chapter Generation](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-chapters)。

这个 Task 提供一份初始输入。它不会替你标注概念。其中保存的是示例视频列表，不是你的课程。请将整个列表替换为一个你已知的公开课程视频。不要研究示例列表，也不要从中复制词语。

Actor 接受公开视频 URL，也接受由 11 个字符组成的视频 ID。ID 是视频的简短识别码。你最多可以提交 1,000 个输入。本次任务只提交一个视频。重复的视频 ID 只处理一次。

起始 URL 可以是普通观看链接、youtu.be 链接、Shorts 链接、直播链接或嵌入链接。嵌入链接用于将播放器放到其他页面上。Actor 不会从频道、播放列表或搜索页面中查找视频。

它只读取[已有的公开字幕](/zh-Hans/articles/youtube-%E6%96%87%E5%AD%97%E7%A8%BF%E6%8F%90%E5%8F%96%E4%B8%8E%E7%BC%BA%E5%A4%B1%E5%AD%97%E5%B9%95%E6%A3%80%E6%9F%A5/)。它不会将语音转换成新文本，不会翻译，也不会编写章节、标签或摘要。

需要英语字幕轨道时，使用以下输入：

```json
{
  "startUrls": ["https://www.youtube.com/watch?v=YOUR_PUBLIC_VIDEO"],
  "preferredLanguages": ["en"],
  "outputFormats": ["json"],
  "includeFailedInputDetails": true
}
```

2. 获取一条字幕轨道

将 YOUR_PUBLIC_VIDEO 替换为你已知的公开视频。`outputFormats` 必须设为 `["json"]`，这样每个字幕片段才能保留时间信息。将 `preferredLanguages` 设为 `["en"]` 表示请求英语字幕。如果没有英语字幕，结果会说明该语言不可用，不会在未作说明的情况下返回其他语言。

如果你希望获取现有字幕中最合适的轨道，请使用空的语言列表：

```json
{
  "startUrls": ["https://www.youtube.com/watch?v=YOUR_PUBLIC_VIDEO"],
  "preferredLanguages": [],
  "outputFormats": ["json"],
  "includeFailedInputDetails": true
}
```

2. 获取一条字幕轨道

空列表不保证返回英语字幕。运行结束后，你必须查看 `transcriptLanguageCode`。将 `includeFailedInputDetails` 保持为 true，以便仍能看到失败的输入。

## 3. 搜索前先检查结果

查看来源数据行中的以下字段。字段是一个有名称的值。

- `videoId`
- `videoUrl`
- `transcriptLanguageCode`
- `isAutoGenerated`
- `segments`，其中每个字幕片段都包含 `text`、`startSeconds`、`endSeconds` 和 `durationSeconds`
- `segmentCount`
- `status`
- `statusReason`
- `scrapedAt`

`videoDurationSeconds` 可能缺失。缺失表示未知。不要将未知值写成 0。

`isAutoGenerated` 表示字幕轨道的制作方式。True 表示字幕由系统自动生成。False 表示字幕轨道由人工提供。人工字幕也可能有错字。你仍需观看视频。

`status` 表示本次字幕读取是否成功。`statusReason` 说明原因。`scrapedAt` 是观测时间。请在笔记中保留视频 ID、URL、语言、自动或人工字幕标记，以及 `scrapedAt`。

然后查看名为 OUTPUT 的运行摘要：

- `successfulTranscriptRows`
- `rowsWritten`
- `failedInputs`
- `statusCounts`
- `errorCodeCounts`
- `failedInputDetails`

失败的输入不会生成字幕数据行。如果 `status` 未显示成功，请停止。如果请求的语言不可用，就将搜索结果保留为未确定。没有匹配到文本，不能证明视频中没有这个概念。相关词语可能只出现在画面上，也可能缺少所需语言的字幕轨道，或字幕读取失败。这一限制只适用于已检查的字幕轨道，不适用于整个视频。

对 0.1.43 版本的一次测试使用了一个指定的公开视频 ID。测试返回了 1 份字幕全文。字幕轨道为英语人工字幕，包含 4,530 个带有时间信息的字幕片段。OUTPUT 显示成功，且没有失败的输入。这只能证明该来源提供了带有时间信息的字幕片段，不能证明概念标签有效，不能证明字幕用词完全正确，也不能证明每个视频都能得到同样的结果。请对照视频核查每个时段。

`transcriptSpanSeconds` 以及首尾时间值只描述字幕轨道，不能证明某个概念已得到完整讲解。

## 4. 保留每个原始字幕片段

保留每个原始字幕片段。不要将字幕中的每个词都单独作为一个概念。查找你的概念及所列出的其他词语，然后阅读匹配位置前后的字幕片段。

关键词搜索可以帮助找出候选时段。候选时段是可能相关但尚未确认的时段。搜索不会生成经过核实的标签。只有观看视频后，你才能写下标签。

## 5. 标出候选时段

将开始讲解的第一个字幕片段作为时段起点，将仍在回答你所提问题的最后一个字幕片段作为时段终点。

优先使用最后一个字幕片段返回的 `endSeconds`。如果 `durationSeconds` 已知，请交叉核对 `endSeconds` 是否等于 `startSeconds` 加 `durationSeconds`。即使 `endSeconds` 已知，`durationSeconds` 也可能为 null。请保留 null，绝不要猜成 0。不要将下一个字幕片段的开始时间用作结束时间。字幕片段可能重叠，也可能存在间隔。最后一行字幕的结束时间不等于视频的结束时间。

如果较早的字幕片段定义了你需要理解的词语，也应将它们纳入时段。所定义的词语可能是某个数值的名称。教师重新讲到先前的概念时，时段可以重叠。你不必将整个视频划分成一组连续时段。

## 6. 观看视频并标注答案类型

打开原视频中的候选时段。听清讲述内容，同时查看图示、屏幕上的代码和引用资料。字幕可能遗漏这些内容。

从以下简单分类中选择一个标签：

- `mention_only` 表示提到了概念，但没有解释。
- `explains_definition` 表示该时段解释了含义或方法。
- `worked_example` 表示该时段逐步解答了一个具体案例。
- `comparison` 表示该时段对事物进行了比较。
- `unresolved` 表示你无法通过本次观看确认答案。

这些标签是你自己作出的内容标记，不是 Actor 的输出。请写明该时段为什么能回答学习问题，或为什么不能。

## 7. 保存一条索引记录

索引记录是你为一个已核查时段编写的一行记录。请包括：

- 概念标签
- 学习问题
- 视频 ID 和 URL
- 字幕语言
- 以秒为单位的开始时间和结束时间
- 以分秒表示的开始时间
- 讲解类型
- `checked_at`
- 证据备注
- 置信程度

还要保留结束时间。置信程度是你给出的核查评级，不是模型评分。如果某个边界未知，就保留为未知。

## 8. 打开起始时间链接，学习该时段

在电脑上打开“分享”，然后选择“开始时间”。输入开始时间并复制链接。打开复制的链接，确认播放是否从所需内容附近开始。YouTube 在[分享视频和频道](https://support.google.com/youtube/answer/57741?hl=en&ref_topic=9257102)中说明了这项功能。

起始时间链接不会强制播放在指定时间停止。请在索引中保留结束时间。不要将编造的示例 URL 当作经过核查、可以播放的视频。

使用已核查的时段进行学习。如果无法确认其中的讲解，请标记为 `no_confirmed_explanation_in_checked_track`。添加一条范围备注，注明检查的是哪条字幕轨道，然后查阅其他来源。不要因为一次不确定的字幕搜索未找到结果，就认定整个视频无法回答问题。

## 虚构课程：测量花坛

以下示例是原创虚构内容，用于讲解时段计算。它不是 Actor 的结果，也没有真实的视频 URL。不要将它的任何链接视为可播放链接。

这节虚构课程名为“测量花坛”，时长为 12 分钟。教学时段如下：

- 0 至 120 秒：准备
- 120 至 330 秒：测量方法讲解
- 330 至 570 秒：计算例题
- 570 至 720 秒：适用限制

在宽度概念附近，有 3 个虚构的字幕片段：

| 开始时间（秒） | 持续时长（秒） | 结束时间（秒） | 文本 |
| --- | --- | --- | --- |
| 120 | 30 | 150 | 从一侧内边缘量到另一侧内边缘，测出内部宽度 |
| 150 | 45 | 195 | 长度和宽度使用相同的单位 |
| 300 | 30 | 330 | 记录前先核对读数。 |

学习问题是：如何使用统一的单位测量宽度？

120 秒处的字幕给出操作方法。150 秒处的字幕补充了统一单位的要求。300 秒处的字幕完成了方法讲解。因此，定义讲解时段包括这 3 行字幕，范围为 120 秒至 330 秒。

最后一个字幕片段的结束时间：300 + 30 = 330 秒。时段长度：330 - 120 = 210 秒。210 秒等于 3 分 30 秒。以分秒表示的开始时间为 2:00，结束时间为 5:30。

在人工观看这节虚构课程后，标签为 `explains_definition`。证据备注说明画面展示了内边缘。确认该标签的是观看视频这一步，而不是字幕片段文本本身。

计算时段属于另一种概念类型，范围为 330 至 570 秒。570 - 330 = 240 秒。240 秒即 4:00。其开始时间为 5:30。将其标记为 `worked_example`。不要将它并入定义讲解。

4 个教学时段的长度分别为 120、210、240 和 150 秒。120 + 210 + 240 + 150 = 720 秒。它们合起来覆盖了这节虚构课程的全部时长。时间覆盖完整，不代表每个概念都得到了解释。

“测量”一词也出现在 600 秒处，即 10:00。它位于适用限制时段内，是一条提醒。请将其保留为 `mention_only`，或标为适用限制。不要将主要定义讲解的时间移到 600 秒。

还有一个虚构的时段边界需要人工判断。某个字幕片段从 310 秒开始，持续 30 秒，结束时间为 310 + 30 = 340 秒。下一个时段从 330 秒开始。340 - 330 = 10 秒，存在 10 秒的重叠。请保留这段重叠，或在观看后调整边界。不要只为了让边界整齐，就在 330 秒处截断话语。

这里的 `scrapedAt` 未知，因为没有读取真实的字幕轨道。`videoDurationSeconds` 也未知。720 秒来自虚构的时段长度，不是视频时长字段的值。未知值仍应保留为未知。

### 4 个虚构时段的时间计算

| 部分 | 开始时间（秒） | 结束时间（秒） | 时长 |
| --- | --- | --- | --- |
| 准备 | 0 | 120 | 120 |
| 宽度定义 | 120 | 330 | 330 - 120 = 210 |
| 计算 | 330 | 570 | 570 - 330 = 240 |
| 适用限制 | 570 | 720 | 720 - 570 = 150 |
| 合计 | 0 | 720 | 120 + 210 + 240 + 150 = 720 |

### 同一虚构课程中的边界情况

| 情况 | 计算 | 处理决定 |
| --- | --- | --- |
| 定义讲解的最后一个字幕片段 | 300 + 30 = 330 | 以此结束时间作为宽度讲解时段的终点。 |
| 重叠部分延伸到 330 秒之后 | 310 + 30 = 340，且 340 - 330 = 10 | 保留这 10 秒重叠，或在观看后调整。 |
| 600 秒处再次出现的词语 | 600 位于 570 至 720 之间 | 属于 `mention_only` 的适用限制内容，不是定义讲解。 |

### 已核查的虚构课程索引

| 概念 | 学习问题 | 视频 | 字幕语言 | 开始时间（秒） | 结束时间（秒） | 开始时间 | 结束时间 | 类型 | 核查时间 | 证据备注 | 核查评级 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 课程准备 | 测量前要做什么？ | 仅有虚构标题，没有真实 URL。 | en，仅为教学示例标签 | 0 | 120 | 0:00 | 2:00 | unresolved | 仅作教学示例核查 | 名称标为准备部分。未提供字幕片段文本，因此尚未确认这一说法。 | 观看前无法确定 |
| 使用统一单位表示宽度 | 如何使用统一的单位测量宽度？ | 仅有虚构标题，没有真实 URL。 | en，仅为教学示例标签 | 120 | 330 | 2:00 | 5:30 | explains_definition | 仅作教学示例核查 | 最后的结束时间为 300 + 30 = 330。观看备注：画面展示了内边缘。 | 已在本次虚构课程核查中确认 |
| 花坛计算 | 如何演示一次计算？ | 仅有虚构标题，没有真实 URL。 | en，仅为教学示例标签 | 330 | 570 | 5:30 | 9:30 | worked_example | 仅作教学示例核查 | 属于单独的类型。570 - 330 = 240 秒，即 4:00。 | 仅确认其为例题 |
| 后面出现的测量提醒 | 后面出现的这个词是否解释了宽度？ | 仅有虚构标题，没有真实 URL。 | en，仅为教学示例标签 | 570 | 720 | 9:30 | 12:00 | mention_only | 仅作教学示例核查 | 600 秒处，这个词出现在一条提醒中。将其保留为适用限制。 | 仅提及 |

宽度问题对应的是 120 至 330 秒这一行。你应从 2:00 开始观看，并将 5:30 作为本次核查的结束时间。你应保存起始时间链接、结束时间和证据备注。这条虚构记录没有真实链接。对于真实视频，请打开“分享”，再选择“开始时间”，打开复制的链接，并记录你看到的内容。

这个虚构示例没有经过实测的学习速度结果。其中的数字仅用于讲解时段计算。

## 下一步

将整个示例列表替换为一个你已知的公开课程视频。使用 [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper) Actor 的 [YouTube Transcript Data for Video Chapter Generation](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-chapters) Task。将 `outputFormats` 设为 `["json"]`。观看原视频中的一个候选时段。保存其起始时间链接、结束时间和一条简短的证据备注。

## 来源和延伸阅读

- [YouTube Transcript Scraper](https://apify.com/chronometrica/youtube-transcript-scraper)
- [YouTube Transcript Data for Video Chapter Generation](https://apify.com/chronometrica/youtube-transcript-scraper/examples/youtube-chapters)
- [分享视频和频道](https://support.google.com/youtube/answer/57741?hl=en&ref_topic=9257102)
- [关于长篇课程视频的亲身体验笔记](https://www.reddit.com/r/chrome_extensions/comments/1vhu5aj/built_a_lightweight_extension_that_attaches/)