Youtube Workflow
Wichtig
Um diesen Workflow ohne Probleme reproduzieren zu können, führen Sie ihn am besten auf dem RStudio-Server durch. Machen Sie regelmäßig lokale Backups, indem Sie einzelne Dateien oder den gesamten Projektordner herunterladen. Hierzu markieren Sie im Files-Tab rechts unten die gewünschten Dateien oder den Ordner (Häkchen links neben dem Namen setzen) und dann auf “More” -> “Export…” klicken.
RStudio Projekt anlegen
Wir legen ein neues RStudio-Projekt an, z.B. youtube-workflow. Dazu klicken wir rechts oben in RStudio auf das Symbol für Projekte und wählen “New Project…”. Anschließend wählen wir “New Directory” und dann “New Project”. Wir geben dem Projekt den Namen youtube-workflow und klicken auf “Create Project”.
Virtuelle Python-Umgebung erstellen
In der Kommandozeile (Achtung: Nicht in der R-Konsole) führen wir den folgenden Befehl aus, der die virtuelle Python-Umgebung anlegt. Um das Terminal zu öffnen, wechseln wir links oben im RStudio-Fenster auf den Tab “Terminal”. Dort sollte nun ein Terminal geöffnet sein. Falls nicht, klicken wir auf das “Terminal” und wählen “New Terminal”. Wenn das Terminal geöffnet ist, sollte in der Eingabemaske Ihr Nutzername und der Pfad des Projektordners angezeigt werden (z.B: meinname@rstudio:~/youtube-workflow$). Nun können wir den folgenden Befehl ausführen:
Im Files-Tab rechts unten sollte nun ein neuer Ordner namens python-env erscheinen. Wenn dies geklappt hat, aktivieren wir die virtuelle Umgebung mit dem folgenden Befehl:
Nun sollte der Name der virtuellen Umgebung in Klammern vor dem Prompt im Terminal erscheinen, z.B. (python-env) meinname@rstudio:~/youtube-workflow$. Wenn das Terminal neu gestartet wird, wird auch die virtuelle Umgebung neu gestartet. Dies erkennen wir daran, dass der Name der Umgebung nicht mehr vor dem Prompt erscheint. In diesem Fall müssen wir die virtuelle Umgebung erneut mit dem obigen Befehl aktivieren.
Pakete installieren
Anschließend installieren wir die benötigten Python-Pakete. Die Installation muss nur einmal durchgeführt werden, die Pakete stehen anschließend in der virtuellen Umgebung zur Verfügung.
Wenn Sie Videos herunterladen möchten, installieren Sie yt-dlp mit dem folgenden Befehl:
Wenn Sie Videos auch transkribieren möchten, installieren Sie außerdem whisper-ctranslate2 mit dem folgenden Befehl:
Ausgewählte YouTube-Videos herunterladen
Um ausgewählte Videos herunterzuladen, speichern wir die Video-URLs in einer Textdatei, wobei jede URL in einer neuen Zeile stehen sollte. Zu Testzwecken können wir eine Datei erstellen über “File”, “dann”New File” und “Text File”. Wir fügen einige YouTube-Video-URLs in die Datei ein und speichern sie als video-urls.txt im Projektordner.
Anschließend können wir die Videos mit dem folgenden Befehl herunterladen (im Terminal, nicht in der R-Konsole). Stellen Sie sicher, dass die virtuelle Umgebung aktiviert ist, bevor Sie den Befehl ausführen. Der Parameter "video-urls.txt" sollte durch den Namen der Datei ersetzt werden, die Ihre Video-URLs enthält.
Terminal
yt-dlp -w --write-info-json --write-thumbnail --no-write-playlist-metafiles \
-c -o "%(id)s.%(ext)s" -P "videos" -a "video-urls.txt" \
-f "bestvideo[ext=mp4][height<=480]+bestaudio[ext=m4a]/best[ext=mp4][height<=480]" --merge-output-format mp4 \
--download-archive "__downloaded.txt" \
--min-sleep-interval 30 --max-sleep-interval 60 \
--write-commentsDieser Befehl lädt die Videos in den Ordner videos herunter. Die Videos werden in einer Auflösung von maximal 480p heruntergeladen, um Speicherplatz zu sparen. Außerdem werden Metadaten und Kommentare der Videos gespeichert. Bereits heruntergeladene Videos werden in der Datei “__downloaded.txt” dokumentiert und bei erneutem Ausführen übersprungen, um doppelte Downloads zu vermeiden. Wenn alle Videos heruntergeladen sind, sichern Sie den Ordner videos nach Möglichkeit auch lokal, indem Sie ihn herunterladen (im Files-Tab rechts unten den Ordner markieren und auf “More” -> “Export…” klicken). Achtung: Je nach Anzahl und Länge der Videos kann der Download einige Zeit in Anspruch nehmen und viel Speicherplatz benötigen.
Wenn Sie nur Videos aus einem bestimmten Zeitraum herunterladen möchten, können Sie den Befehl wie folgt anpassen, indem Sie die gewünschten Start- und Enddaten im Format YYYYMMDD angeben:
Terminal
yt-dlp -w --write-info-json --write-thumbnail --no-write-playlist-metafiles \
-c -o "%(id)s.%(ext)s" -P "videos" -a "video-urls.txt" \
-f "bestvideo[ext=mp4][height<=480]+bestaudio[ext=m4a]/best[ext=mp4][height<=480]" --merge-output-format mp4 \
--download-archive "__downloaded.txt" \
--min-sleep-interval 30 --max-sleep-interval 60 \
--write-comments \
--dateafter 20220101 --datebefore 20221231Alle Videos oder Shorts eines Kanals herunterladen
Alternativ können wir auch alle Videos oder Shorts eines Kanals herunterladen:
Terminal
yt-dlp -w --write-info-json --write-thumbnail --no-write-playlist-metafiles \
-c -o "%(id)s.%(ext)s" \
-f "bestvideo[ext=mp4][height<=480]+bestaudio[ext=m4a]/best[ext=mp4][height<=480]" \
--merge-output-format mp4 \
--download-archive "__downloaded.txt" \
--min-sleep-interval 30 --max-sleep-interval 60 \
--write-comments \
-P "videos" \
https://www.youtube.com/@johnmayer/shortsAls letzten Parameter geben wir die URL des Kanals oder der Playlist an, die heruntergeladen werden soll. Wenn wir Shorts herunterladen möchten, fügen wir /shorts an die Kanal-URL an. Wenn wir nur die Videos eines Kanals herunterladen möchten, fügen wir statt /shorts /videos an die Kanal-URL an. Auch hier können wir, wie oben beschrieben, die Datumsfilter --dateafter und --datebefore verwenden, um nur Videos oder Shorts aus einem bestimmten Zeitraum herunterzuladen.
Nur Metadaten (ohne Videos) herunterladen
Wenn Sie zunächst nur die Metadaten (z.B. die Titel der Videos) aller Videos eines Kanals herunterladen möchten, um eine Vorselektion der Inhalte zu treffen, bevor Sie ausgewählte Videos herunterladen, können Sie den folgenden Befehl verwenden:
Terminal
Diese können wir anschließend in R einlesen und analysieren, um eine Vorauswahl der Videos zu treffen, die wir herunterladen möchten.
TikTok Videos herunterladen
Um TikTok Videos herunterzuladen, können wir ebenfalls yt-dlp verwenden. Das Vorgehen ist dabei sehr ähnlich, wobei wir bei TikTok leider nicht direkt die Kommentare laden können (dazu nutzen Sie bitte die Browser-Erweiterung Zeeschuimer). Der folgende Befehl lädt alle Videos eines TikTok-Kanals herunter (alterativ können Sie wie oben beschrieben auch ausgewählte Video-URLs in einer Textdatei speichern und diese mit dem Parameter -a angeben):
Kommentare in R einlesen
Nachdem die Videos und Metadaten heruntergeladen wurden, können wir die Kommentare in R einlesen und analysieren. Dazu verwenden wir das folgende R-Skript:
library(tidyverse)
library(jsonlite)
comments <-
map(
list.files("videos", pattern = "*.info.json", full.names = TRUE),
~ fromJSON(.x)$comments |>
as_tibble() |>
mutate(
id = fromJSON(.x)$id,
title = fromJSON(.x)$title,
description = fromJSON(.x)$description
)
) |>
list_rbind() |>
mutate(datetime = as_datetime(timestamp))Zur Sicherheit speichern wir die Kommentare als CSV-Datei:
Sichern Sie diese Datei nach Möglichkeit auch lokal, indem Sie sie herunterladen (im Files-Tab rechts unten die Datei markieren und auf “More” -> “Export…” klicken).
Videos transkribieren
Um die heruntergeladenen Videos zu transkribieren, verwenden wir den folgenden Befehl im Terminal (nicht in der R-Konsole). Stellen Sie sicher, dass die virtuelle Umgebung aktiviert ist, bevor Sie den Befehl ausführen.
Transkripte in R einlesen und Segmente erstellen
Nachdem die Videos transkribiert wurden, können wir die Transkripte in R einlesen und in 60-Sekunden-Segmente unterteilen. Die Segmentlänge können wir beliebig anpassen. Dazu verwenden wir das folgende R-Skript:
transcripts <-
map(
list.files("transcripts", pattern = "*.tsv", full.names = TRUE),
~ read_tsv(.x, col_types = "iic")) |>
set_names(list.files("transcripts", pattern = "*.tsv", full.names = FALSE) |> str_remove(".tsv")) |>
list_rbind(names_to = "id") |>
group_by(id) |>
mutate(interval = floor(start / 60000)) |> # hier kann die Segmentlänge angepasst werden (60000 ms = 60 Sekunden)
group_by(id, interval) |>
reframe(
start_time = min(start) + 3000, # Sicherheitsabstand von 3 Sekunden
end_time = max(end) - 3000,
text = str_c(text, collapse = " ")
) |>
ungroup() |>
distinct()Wenn wir keine Segmente erstellen wollen, sondern jeweils das gesammte Videotranskript auf einmal codieren möchten, können wir folgende vereinfachte Version verwenden:
transcripts <-
map(
list.files("transcripts", pattern = "*.tsv", full.names = TRUE),
~ read_tsv(.x, col_types = "iic")
) |>
set_names(
list.files("transcripts", pattern = "*.tsv", full.names = FALSE) |>
str_remove(".tsv")
) |>
list_rbind(names_to = "id") |>
group_by(id) |>
reframe(
start_time = min(start),
end_time = max(end),
text = str_c(text, collapse = " ")
) |>
ungroup() |>
distinct()Zur Sicherheit speichern wir die Transkripte als CSV-Datei:
Sichern Sie diese Datei nach Möglichkeit auch lokal, indem Sie sie herunterladen (im Files-Tab rechts unten die Datei markieren und auf “More” -> “Export…” klicken).
Klassifizieren
Um die Kommentare oder Transkript-Segmente zu klassifizieren, kombinieren wir sie mit dem interpolate()-Befehl aus dem ellmer-Paket (siehe auch hier).
Je nach größe des Datensatzes kann die Klassifikation einige Zeit in Anspruch nehmen. Daher bietet es sich an, die Klassifikation in einzelne Batches aufzuteilen und nacheinander zu verarbeiten. So können Sie außerdem die Batches untereinander aufteilen und mehrere API-Keys gleichzeitig verwenden.
batch_size <- 100
# Ordner erstellen, falls nicht vorhanden
if (!dir.exists("batches")) dir.create("batches", recursive = TRUE)
# In Batches aufteilen und speichern
comments |> # oder transcripts
mutate(.batch_id = rep(1:ceiling(n() / batch_size),
each = batch_size,
length.out = n())) |>
group_split(.batch_id) |>
map(~ select(.x, -.batch_id)) |>
iwalk(~ write_csv(.x, file.path("batches", sprintf("%s_%03d.csv", "batch", .y))))
# Anschließend können die einzelnen Batch-Dateien einzeln eingelesen und dann wie oben klassifiziert werden:
batch_01 <- read_csv("batches/batch_001.csv")
# usw...