已選的影片卡連到一份已核對的字幕清單,旁邊是編碼表和缺文字托盤。
做研究編碼之前,先核對字幕文字。

一則公開的研究問題,問怎樣為一項研究收集 TikTok 字幕文字。它也問怎樣檢查準確度,以及怎樣在 R 裡分析文字。R 是用來處理表格和次數的程式。這條問題顯示有這個需要。它沒有證明這個方法有效。它也沒有顯示有多少研究需要它。見關於 TikTok 字幕文字的公開問題。

你用 Actor 收集資料行。Actor 是託管的資料收集程式。託管是指它以服務形式運行,不是你電腦上的一個檔案。這個 Actor 是 TikTok Transcript Scraper。Task 是已儲存的輸入預設。預設是一套已儲存的輸入選擇。目前的 Task 是 TikTok Transcript Dataset for Content Analysis。Actor 收集來源資料行。編碼和計數由你來做。公開的 Task 只是起始輸入。它不代表分析會自己運行。

目前的收集程式回傳甚麼

這些公開事實在 2026-10-13 已核對。目前版本是 0.1.36。每次執行在 `startUrls` 接受 1 至 100 個已知的公開目標。目標可以是影片 URL、短連結,或數字影片 ID。這個 Actor 不會搜尋個人檔案、關鍵字或聲音頁。你必須已經知道那些影片。

`preferredLanguages` 是一份按次序排列的公開字幕語言清單。Actor 選第一條相符的公開字幕軌。空白清單會用第一條公開字幕軌。它不會翻譯文字。沒有字幕的聲音,它不會從聲音產生文字。它不收集留言。它不指派內容編碼。

已儲存的 Task 輸入是:

json
{"startUrls": ["https://www.tiktok.com/@hankgreen1/video/7047596209028074758"], "preferredLanguages": []}
目前的收集程式回傳甚麼

用你自己已知的公開影片,取代那個樣本。若只試一條影片,在 `startUrls` 放一個 URL。若研究語言是英文,把 `preferredLanguages` 設為 `["en"]`。若研究用另一種語言,寫下該語言規則,並用它的語言代碼。不要把 `["en"]` 抄進另一種語言的研究。空白清單可能回傳某一條其他公開字幕軌。

資料集的每一行對應一個已提交的輸入。失敗的輸入仍會有一行。保留該行。它是這次嘗試的證據。這些欄位名稱必須完全一致:`inputIndex`、`inputUrl`、`videoId`、`videoUrl`、`authorHandle`、`durationSeconds`、`languageCode`、`text`、`segments`、`status`、`statusReason`、`isBillable` 和 `scrapedAt`。每個片段有 `startSeconds`、`endSeconds` 和 `text`。TikTok 的時間用這兩個鍵。`startSeconds` 和 `endSeconds` 照回傳值使用。每個 `videoId` 都當文字保留,不要當數字。若程式把很長的 ID 存成數字,這個 ID 可能會改變。

`status` 可以是 `succeeded`、`no_public_captions`、`language_unavailable`、`duplicate_input`、`not_tiktok`、`invalid_input`、`unsupported_url`、`video_unavailable`、`not_public` 或 `blocked_or_challenged`。擷取失敗和字幕失敗也可能出現。成功必須有非空白的文字。失敗狀態配上空值或空白字幕,並不是說話中的沉默。影片仍可能有說話。你只知道沒有可用的字幕回來。

只有成功的原生字幕結果,`isBillable` 才是 true。這個欄位名稱用小寫的 b。其他行仍留在資料裡,作為證據。`isBillable` 不是描述整次執行。一次執行可以同時有 true 和 false 的行。不要把整次執行說成免費。

這次執行的帳目使用這些準確名稱:`inputsReceived`、`resultRows`、`billableTranscriptRows`、`nonBillableResultRows`、`duplicateVideosSkipped` 和 `statusCounts`。這份帳目用來核對這次執行。它不表示你的影片代表所有創作者。

2026-10-13 的一次單片核對,用了已儲存的樣本。該行成功。影片 ID 是所要求的 ID,`7047596209028074758`。語言代碼是 `eng-US`。像 `eng-US` 這樣的代碼是地區字幕標籤。它表示英文,並帶有美國地區標籤。它不是翻譯。文字不是空白。該行有 12 個片段。片段時間資料包含 `startSeconds` 和 `endSeconds` 這兩個鍵。這裡不重複該影片的字幕字詞。這次核對只證明那一個來源有公開字幕路徑。它不證明字詞完全正確。它不證明每一條影片都會成功。它不證明你的內容編碼有效。你仍須做自己的試行。

八個步驟

  1. 界定問題、編碼和樣本

寫一條研究問題。寫一條你可以數算的內容編碼。內容編碼是你標為出現或不出現的特徵。按一條你能說清楚的規則,選擇已知的影片 URL。收集之前,先說明時段、語言和創作者範圍。

抽樣清單是你選中的每一條影片的名單。先填好這份清單,再看字幕。不要只因為有字幕就選影片。若你只保留有字幕的影片,樣本就已經改變。沒有字幕的影片會消失,而不是顯示為缺失。

  1. 先聲明計算單位

選擇你要數算的單位。單位可以是一條影片、一個字幕片段,或你界定的一段文字。在這些步驟裡,被數算的單位是影片。片段是一段有時間的字幕文字。片段是該影片的證據。它們不是額外的影片。

三個片段有同一個編碼,仍只算一條影片。執行之前先寫下這條規則。保留輸入 URL、回傳的 `videoId`,以及你自己的 `selected_video_key`。研究鍵是你的。即使 URL 形式改變,它仍保持不變。

  1. 先測試一條已選影片

任何批次之前,先執行一條已選影片。這是試行。試行是對整條路徑的小型測試。檢查 `status`、`videoId`、`languageCode` 和 `text`。成功時文字必須非空白。若研究語言是英文,在這次試行把 `preferredLanguages` 設為 `["en"]`。

然後把一段短文字和聲音比較。也看畫面上的影像。寫下漏掉的字、多出的字和錯誤的字。成功的一行不證明字詞準確。上面的 12 個片段核對,只顯示公開路徑可以回傳字幕。那不是你的核對。

  1. 執行有上限的清單,再對帳

只送出你已知的 URL,一次執行最多 100 個。更長的已選清單需要另一次執行。把每個已提交的輸入對到一行結果。用 `inputIndex`、`inputUrl` 和 `videoId`。再把那些行對到這次執行的帳目。

檢查 `inputsReceived`、`resultRows`、`billableTranscriptRows`、`nonBillableResultRows`、`duplicateVideosSkipped` 和 `statusCounts`。重複項記在備註裡,該影片只算一次。缺失的字幕留在清單裡,但放在成功集合之外。來源存取失敗也一樣處理。那些狀態包括 `video_unavailable`、`not_public`、`blocked_or_challenged`、`unsupported_url`、`not_tiktok` 和 `invalid_input`。

決不要把失敗的空白文字編碼成「編碼不存在」。空白文字表示你沒有觀察到該編碼。它不表示該編碼不存在。

  1. 做影片表和片段表

每條已選影片做一行。用這些欄:`selected_video_key`、`videoId`、`videoUrl`、`languageCode`、`caption_status`、`caption_validated`、`study_eligible` 和 `exclusion_reason`。`study_eligible` 記錄該影片可否納入計數。它不是內容編碼。`caption_validated` 記錄你有沒有把字幕和影片核對。

未能核對字幕時,用 `unknown`。真實狀態是未知時,不要把 `caption_validated` 寫成 no。失敗的一行沒有被核對。未完成的覆核也沒有被核對。

片段放在第二張表。用影片鍵、`startSeconds`、`endSeconds`、`text`,以及一項來源觀察。把片段陣列放在試算表的一個儲存格裡,是很差的匯出。CSV 是平面文字表,資料按行和欄排列。嵌套的片段清單不能安全地直接放進這種表格結構。先匯出 JSON。JSON 是一種文字格式,可以在一個項目裡保留清單。然後另行把片段清單攤平。攤平是指每個片段做成單獨的一行。在每個片段的那一行重複影片鍵。不要按逗號拆開文字。句子裡有逗號。原始字幕文字保持不變。每個編碼都放在新欄。

  1. 寫一條小編碼規則,並在虛構例子上試用

從這一步起的例子都是虛構。它們不是 Actor 的輸出。不要把這些 ID 貼進真實輸入。它們的影片 URL 是未知的。

寫一條短規則,並給它一個版本。若是簡單的全字相符規則,要界定該字、字母大小寫,以及字詞邊界。字詞邊界避免一個短字在較長的字裡面相符。含糊用法由你自己覆核。關鍵字規則只找出該模式。它不證明說話的人想表達甚麼。只靠畫面傳達的訊息,可以和字幕文字不一致。諷刺也可以和文字不一致。這些情況需要人來編碼。

這裡的虛構編碼,是量度水的明確指示。規則版本 v1:已核對的字幕文字給出該指示時,標為編碼 1。整個字 "measure" 在任何字母大小寫都計算。字 "measurement" 是另一個字。要覆核它。不要只靠關鍵字規則標它。只有已核對、而且沒有該指示的字幕,才可以標編碼 0。否則編碼保持未知。

  1. 先核對一小組試行資料,再匯入 R

大型研究之前,先為一小組試行資料編碼。兩個人可以分開編碼。或者你稍後再編一次,然後比較。儲存 `code`、`code_version`、`coder`、`decision_note` 和一個時間戳。時間戳記錄決定是何時作出的。原始文字放在自己的欄。

R 可以讀取平面 CSV。告訴 R,ID 欄是文字。不要讓 R 把 ID 猜成數字。下面的片段只用 base R。它用虛構的行。它不加入套件。它不是經過測試的研究標準。這裡 `denom` 是分母。分母是你用來相除的合資格影片數目。`NA` 表示不可用。這個例子用 `NA` 表示未知編碼。

r
videos <- data.frame(
  videoId = c("video-v1", "video-v2", "video-v3", "video-v4", "video-v5"),
  study_eligible = c("yes", "yes", "no", "no", "no"),
  code = c(1, 0, NA, NA, NA),
  stringsAsFactors = FALSE
)
stopifnot(is.character(videos[["videoId"]]))
eligible <- videos[["study_eligible"]] == "yes"
stopifnot(!any(is.na(videos[["code"]][eligible])))
code_count <- sum(videos[["code"]][eligible])
denom <- sum(eligible)
share <- code_count / denom
八個步驟

`code_count` 是 1。`denom` 是 2。`share` 是 0.5。`NA` 值是未知編碼。它們不是零。`stopifnot` 那一行會在合資格影片有未知編碼時停止這個指令碼。

匯出真實 CSV 時,保留同一個文字檢查:

r
videos_from_csv <- read.csv(
  "video_table.csv",
  stringsAsFactors = FALSE,
  colClasses = c(videoId = "character")
)
stopifnot(is.character(videos_from_csv[["videoId"]]))
八個步驟

你也可以在 base R 測試這條虛構的字詞規則:

r
raw_text <- "I measure the water before I pour it"
hit <- grepl("\\bmeasure\\b", raw_text, ignore.case = TRUE)
ambiguous <- grepl("\\bmeasure\\b", "measurement", ignore.case = TRUE)
八個步驟

`hit` 是 TRUE。`ambiguous` 是 FALSE。第二個結果說明:較長的字需要人工覆核規則,不能未經覆核就視為相符。

  1. 連同完整結果清單一起報告次數

編碼占比的分母,只用合資格影片。合資格是指 `succeeded`、文字非空白,以及 `caption_validated` 為 yes。在該占比旁邊,報告每條已選影片的結果。讀者必須看到失敗和未完成的行。把發現限制在你選中並觀察到的影片。不要把它說成所有創作者的結果。不要把它說成所有政治言論的結果。

缺失的字幕可以改變結論。本文停在這份清單。它不教那些缺失的行可以令結果改變多少。

虛構的五條影片計數

同一個虛構例子在這裡繼續。V1 至 V5 是編造的研究標籤。`videoId` 的值是編造的文字標籤。它們不是真實的 TikTok ID。每一行的 `videoUrl` 都是未知。不要把這些標籤送給 Actor。真實的 `languageCode` 可以是地區值,例如 `eng-US`。這個虛構例子用 `en`,因為聲明的研究語言是英文。在表裡,unknown 是研究用的值。在 R 例子裡,`NA` 儲存同一個未知。不要把未知存成 0。

所聲明的編碼仍是量度水的明確指示。

V1 是英文。它成功。字幕已核對。文字是 "I measure the water before I pour it"。這段文字是量度水的明確指示。編碼是 1。

V2 是英文。它成功。字幕已核對。文字是 "I pour water into the tray"。它叫人倒水。它沒有叫人量度。編碼是 0。

V3 的狀態是 `no_public_captions`。文字是空白。`languageCode` 是未知。不要編造一個。`caption_validated` 是 unknown,不是 no。編碼是未知。空白文字不是編碼 0。它也不是沉默的證明。

V4 的狀態是 `language_unavailable`。文字是空白。`languageCode` 是未知。`caption_validated` 是 unknown。編碼是未知。這個失敗和 V3 的失敗不同。把兩個原因分開保留。

V5 是英文。它成功。有人把字幕和聲音比較。字幕漏了量度語句。核對未完成。`caption_validated` 是 unknown,不是 no。`study_eligible` 是 no。編碼保持未知。成功不等於可信的字幕。不要把這一行變成編碼 0。

只有 `study_eligible` 是 yes 時,影片才進入占比。這個決定和編碼分開。V1 和 V2 合資格,因為字幕成功、文字非空白,而且有人核對過。V3 和 V4 不合資格,因為收集失敗。V5 不合資格,因為核對未完成。V1、V2 和 V5 的 `isBillable` 會是 true,因為那些字幕結果成功。V3 和 V4 的 `isBillable` 會是 false。V5 可計費,但仍不合資格。可計費標記不決定研究中計算的影片數目。

影片表:

虛構的五條影片計數
selected_video_keyvideoIdvideoUrllanguageCodecaption_statuscaption_validatedstudy_eligibleexclusion_reason
V1video-v1unknownensucceededyesyesnone
V2video-v2unknownensucceededyesyesnone
V3video-v3unknownunknownno_public_captionsunknownno沒有公開字幕;空白文字未編碼
V4video-v4unknownunknownlanguage_unavailableunknownno所要求的語言缺失;空白文字未編碼
V5video-v5unknownensucceededunknownno聲音覆核未完成;漏了量度語句

編碼表:

虛構的五條影片計數
selected_video_keycodecode_versioncoderdecision_notetimestamp
V11v1coder-a量度水的明確指示example-only
V20v1coder-a只有倒水的指示;沒有量度的指示example-only
V3unknownv1coder-a字幕失敗;未觀察到編碼example-only
V4unknownv1coder-a字幕失敗;未觀察到編碼example-only
V5unknownv1coder-a字幕未核對;未觀察到編碼example-only

片段表:

虛構的五條影片計數
selected_video_keystartSecondsendSecondstextsource_observation
V10.52.5I measure the water before I pour it已核對的字幕證據,支持編碼 1
V1unknownunknownunknown第二個量度片段;只作額外證據;這裡未設定時間
V2unknownunknownI pour water into the tray已核對的字幕證據,支持編碼 0
V5unknownunknownunknown字幕漏了一句已說出的量度語句;這裡未設定字詞

V3 和 V4 沒有片段行。它們的結果文字是空白。不要在 0 秒加一個片段。零會看起來像真實時間。缺失的時間保持未知。

第一個 V1 片段在 2.5 秒結束,在 0.5 秒開始。2.5 減 0.5 是 2.0 秒。這個長度用 `endSeconds` 和 `startSeconds`。第二個 V1 片段也支持量度編碼。它不產生第二條影片。V1 仍是一條已編碼的影片。被數算的單位是影片。

已核對且合資格的影片:2。編碼為 1 的影片:1。1 / 2 = 0.5,即 50%。已選清單仍有 5 條影片。1 / 5 = 0.2,即 20%。不要報告 20%。V3、V4 和 V5 沒有被核實為編碼 0。未知不是零。

五條已選影片的結果次數:2 條已核對且合資格,2 條失敗,1 條核對未完成。兩個失敗的狀態不同。一個是 `no_public_captions`。另一個是 `language_unavailable`。

假設你把這五個輸入提交了一次。假設沒有重複。下面的預期帳目數字是根據這個虛構例子計算出來的。這不是真實執行的回執。`inputsReceived` 會是 5。`resultRows` 會是 5。`billableTranscriptRows` 會是 3。`nonBillableResultRows` 會是 2。`duplicateVideosSkipped` 會是 0。`statusCounts` 會顯示 `succeeded` 3、`no_public_captions` 1,以及 `language_unavailable` 1。你的真實執行必須對照你實際收到的帳目來檢查。

這個例子顯示,額外片段不會增加影片。它也顯示合資格分母。它不顯示一組真實影片。它不顯示字幕準確率。它不顯示這些編造行以外的效應。

已知 V1 片段的平面 JSON 資料結構是:

json
{
  "videoId": "video-v1",
  "segments": [
    {
      "startSeconds": 0.5,
      "endSeconds": 2.5,
      "text": "I measure the water before I pour it"
    }
  ]
}
虛構的五條影片計數

那個物件是給攤平步驟用的虛構例子。攤平之後,上面的片段表是編碼副本。影片表仍是計數副本。

來源與延伸閱讀

作者 Chronometrica · 更新日期

返回頂端 ↑