diff --git a/.gitignore b/.gitignore index 6723323..47b9e79 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ livestreams.dat archive.txt twitch-monitor.dat Dockerfile +*.log +*.log.gz diff --git a/server/internal/downloaders/common.go b/server/internal/downloaders/common.go index bc8b040..cb591a8 100644 --- a/server/internal/downloaders/common.go +++ b/server/internal/downloaders/common.go @@ -22,7 +22,7 @@ func (d *DownloaderBase) FetchMetadata(fetcher func(url string) (*common.Downloa meta, err := fetcher(d.URL) if err != nil { - slog.Error("failed to retrieve metadata", slog.Any("err", err)) + slog.Error("failed to retrieve metadata", slog.String("err", err.Error())) return } diff --git a/server/internal/downloaders/generic.go b/server/internal/downloaders/generic.go index 65824ff..09da950 100644 --- a/server/internal/downloaders/generic.go +++ b/server/internal/downloaders/generic.go @@ -108,7 +108,9 @@ func (g *GenericDownloader) Start() error { slog.Info("requesting download", slog.String("url", g.URL), slog.Any("params", params)) - cmd := exec.Command(config.Instance().Paths.DownloaderPath, params...) + ctx, cancel := context.WithCancel(context.Background()) + + cmd := exec.CommandContext(ctx, config.Instance().Paths.DownloaderPath, params...) cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} stdout, err := cmd.StdoutPipe() @@ -130,18 +132,24 @@ func (g *GenericDownloader) Start() error { g.proc = cmd.Process - ctx, cancel := context.WithCancel(context.Background()) - defer func() { + stop := func() { stdout.Close() g.Complete() + g.progress.Status = internal.StatusCompleted cancel() - }() + } + defer stop() - logs := make(chan []byte) + logs := make(chan []byte, 2) go produceLogs(stdout, logs) go consumeLogs(ctx, logs, g.logConsumer, g) - go printYtDlpErrors(stderr, g.Id, g.URL) + go func() { + err := printYtDlpErrors(stderr, g.Id, g.URL) + if err != nil { + stop() + } + }() g.SetPending(false) return cmd.Wait() diff --git a/server/internal/downloaders/logging.go b/server/internal/downloaders/logging.go index 3b3c951..d4106c7 100644 --- a/server/internal/downloaders/logging.go +++ b/server/internal/downloaders/logging.go @@ -26,18 +26,20 @@ func (j *JSONLogConsumer) ParseLogEntry(entry []byte, d Downloader) { var postprocess internal.PostprocessTemplate if err := json.Unmarshal(entry, &progress); err == nil { - d.SetProgress(internal.DownloadProgress{ - Status: internal.StatusDownloading, - Percentage: progress.Percentage, - Speed: progress.Speed, - ETA: progress.Eta, - }) + if progress.Percentage != "" { + d.SetProgress(internal.DownloadProgress{ + Status: internal.StatusDownloading, + Percentage: progress.Percentage, + Speed: progress.Speed, + ETA: progress.Eta, + }) - slog.Info("progress", - slog.String("id", j.GetShortId(d.GetId())), - slog.String("url", d.GetUrl()), - slog.String("percentage", progress.Percentage), - ) + slog.Info("progress", + slog.String("id", j.GetShortId(d.GetId())), + slog.String("url", d.GetUrl()), + slog.String("percentage", progress.Percentage), + ) + } } if err := json.Unmarshal(entry, &postprocess); err == nil { diff --git a/server/internal/downloaders/utils.go b/server/internal/downloaders/utils.go index 9c38a95..cdd9dab 100644 --- a/server/internal/downloaders/utils.go +++ b/server/internal/downloaders/utils.go @@ -38,14 +38,14 @@ func buildFilename(o *internal.DownloadOutput) { ) } -func produceLogs(r io.Reader, logs chan<- []byte) { - go func() { - scanner := bufio.NewScanner(r) +func produceLogs(r io.Reader, logs chan<- []byte) error { + scanner := bufio.NewScanner(r) - for scanner.Scan() { - logs <- scanner.Bytes() - } - }() + for scanner.Scan() { + logs <- scanner.Bytes() + } + + return scanner.Err() } func consumeLogs(ctx context.Context, logs <-chan []byte, c LogConsumer, d Downloader) { @@ -63,7 +63,7 @@ func consumeLogs(ctx context.Context, logs <-chan []byte, c LogConsumer, d Downl } } -func printYtDlpErrors(stdout io.Reader, shortId, url string) { +func printYtDlpErrors(stdout io.Reader, shortId, url string) error { scanner := bufio.NewScanner(stdout) for scanner.Scan() { @@ -73,4 +73,6 @@ func printYtDlpErrors(stdout io.Reader, shortId, url string) { slog.String("err", scanner.Text()), ) } + + return scanner.Err() } diff --git a/server/internal/kv/store.go b/server/internal/kv/store.go index a976460..7a659c8 100644 --- a/server/internal/kv/store.go +++ b/server/internal/kv/store.go @@ -79,6 +79,12 @@ func (m *Store) Delete(id string) { m.mu.Lock() delete(m.table, id) m.mu.Unlock() + + m.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket(bucket) + b.Delete([]byte(id)) + return nil + }) } func (m *Store) Keys() *[]string { diff --git a/server/server.go b/server/server.go index 1c847bb..4e97e00 100644 --- a/server/server.go +++ b/server/server.go @@ -274,6 +274,7 @@ func gracefulShutdown(ctx context.Context, srv *http.Server, cfg *serverConfig) slog.Info("shutdown signal received") defer func() { + cfg.mdb.Snapshot() cfg.db.Close() srv.Shutdown(context.Background()) }() diff --git a/yt-dlp-webui.log b/yt-dlp-webui.log deleted file mode 100644 index 29f3e10..0000000 --- a/yt-dlp-webui.log +++ /dev/null @@ -1,100 +0,0 @@ -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker spawned" worker=3 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="metadata worker spawned" worker=1 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker spawned" worker=1 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker spawned" worker=4 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker spawned" worker=2 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="published download" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="published download" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker starting download" worker=1 id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="queued for metadata" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="download worker starting download" worker=3 id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="queued for metadata" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="requesting download" url="https://www.youtube.com/watch?v=-fZM9wOvbh0" params="[https://www.youtube.com/watch?v=-fZM9wOvbh0 --newline --no-colors --no-playlist --progress-template download:{\"eta\":%(progress.eta)s,\"percentage\":\"%(progress._percent_str)s\",\"speed\":%(progress.speed)s} --progress-template postprocess:{\"filepath\":\"%(info.filepath)s\"} --no-exec --js-runtimes deno:/home/marco/.deno/bin/deno --remote-components ejs:github -o ./downloads/%(title)s.%(ext)s -o ./downloads/%(title)s.%(ext)s]" -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="metadata worker started" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="metadata worker started" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="requesting download" url="https://www.youtube.com/watch?v=-fZM9wOvbh0" params="[https://www.youtube.com/watch?v=-fZM9wOvbh0 --newline --no-colors --no-playlist --progress-template download:{\"eta\":%(progress.eta)s,\"percentage\":\"%(progress._percent_str)s\",\"speed\":%(progress.speed)s} --progress-template postprocess:{\"filepath\":\"%(info.filepath)s\"} --no-exec --js-runtimes deno:/home/marco/.deno/bin/deno --remote-components ejs:github -r 50K -o ./downloads/%(title)s.%(ext)s -o ./downloads/%(title)s.%(ext)s -o ./downloads/%(title)s.%(ext)s]" -time=2026-06-29T12:10:42.936+02:00 level=INFO msg="retrieving metadata" url="https://www.youtube.com/watch?v=-fZM9wOvbh0" -time=2026-06-29T12:10:42.945+02:00 level=INFO msg="yt-dlp-webui started" address=0.0.0.0:3033 -time=2026-06-29T12:10:43.031+02:00 level=ERROR msg="yt-dlp process error" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err="WARNING: Your yt-dlp version (2026.03.17) is older than 90 days!" -time=2026-06-29T12:10:43.031+02:00 level=ERROR msg="yt-dlp process error" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" It is strongly recommended to always use the latest version." -time=2026-06-29T12:10:43.031+02:00 level=ERROR msg="yt-dlp process error" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" As yt-dlp has been installed via apt, you should use that to update. If you're on a stable release, also check backports.." -time=2026-06-29T12:10:43.031+02:00 level=ERROR msg="yt-dlp process error" id=cd696a78-21a9-41d4-9a3f-47b75ed0cb38 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" To suppress this warning, add --no-update to your command/config." -time=2026-06-29T12:10:43.033+02:00 level=ERROR msg="yt-dlp process error" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err="WARNING: Your yt-dlp version (2026.03.17) is older than 90 days!" -time=2026-06-29T12:10:43.033+02:00 level=ERROR msg="yt-dlp process error" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" It is strongly recommended to always use the latest version." -time=2026-06-29T12:10:43.033+02:00 level=ERROR msg="yt-dlp process error" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" As yt-dlp has been installed via apt, you should use that to update. If you're on a stable release, also check backports.." -time=2026-06-29T12:10:43.033+02:00 level=ERROR msg="yt-dlp process error" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" err=" To suppress this warning, add --no-update to your command/config." -time=2026-06-29T12:10:44.859+02:00 level=INFO msg="metadata worker started" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 -time=2026-06-29T12:10:44.859+02:00 level=INFO msg="metadata worker started" id=98c62f5e-0fda-4dc3-b59f-f6e8e4d9c7a2 -time=2026-06-29T12:10:44.860+02:00 level=INFO msg="retrieving metadata" url="https://www.youtube.com/watch?v=-fZM9wOvbh0" -time=2026-06-29T12:10:45.115+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.115+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.135+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.153+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.172+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.196+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.229+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.234+02:00 level=INFO msg=progress id=98c62f5e url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.263+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.6%" -time=2026-06-29T12:10:45.274+02:00 level=INFO msg=progress id=98c62f5e url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.305+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.6%" -time=2026-06-29T12:10:45.348+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.7%" -time=2026-06-29T12:10:45.354+02:00 level=INFO msg=progress id=98c62f5e url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.394+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.407+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.428+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.428+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.428+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.429+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.429+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.429+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.429+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.0%" -time=2026-06-29T12:10:45.430+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.1%" -time=2026-06-29T12:10:45.433+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.1%" -time=2026-06-29T12:10:45.437+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.1%" -time=2026-06-29T12:10:45.446+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.2%" -time=2026-06-29T12:10:45.475+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.3%" -time=2026-06-29T12:10:45.504+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.5%" -time=2026-06-29T12:10:45.514+02:00 level=INFO msg=progress id=98c62f5e url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.525+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.6%" -time=2026-06-29T12:10:45.549+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.6%" -time=2026-06-29T12:10:45.551+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.6%" -time=2026-06-29T12:10:45.556+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.6%" -time=2026-06-29T12:10:45.565+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.7%" -time=2026-06-29T12:10:45.583+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 95.8%" -time=2026-06-29T12:10:45.619+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.0%" -time=2026-06-29T12:10:45.633+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.1%" -time=2026-06-29T12:10:45.687+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.1%" -time=2026-06-29T12:10:45.687+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.1%" -time=2026-06-29T12:10:45.689+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.1%" -time=2026-06-29T12:10:45.691+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.1%" -time=2026-06-29T12:10:45.696+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.2%" -time=2026-06-29T12:10:45.705+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.2%" -time=2026-06-29T12:10:45.723+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.3%" -time=2026-06-29T12:10:45.759+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.6%" -time=2026-06-29T12:10:45.772+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.6%" -time=2026-06-29T12:10:45.829+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.7%" -time=2026-06-29T12:10:45.831+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.7%" -time=2026-06-29T12:10:45.834+02:00 level=INFO msg=progress id=98c62f5e url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 94.5%" -time=2026-06-29T12:10:45.835+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.7%" -time=2026-06-29T12:10:45.844+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.8%" -time=2026-06-29T12:10:45.864+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 96.9%" -time=2026-06-29T12:10:45.899+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.1%" -time=2026-06-29T12:10:45.915+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.969+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.969+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.969+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.969+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.970+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.970+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.970+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.971+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.974+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.978+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.2%" -time=2026-06-29T12:10:45.987+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.3%" -time=2026-06-29T12:10:46.005+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.4%" -time=2026-06-29T12:10:46.041+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.6%" -time=2026-06-29T12:10:46.055+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.7%" -time=2026-06-29T12:10:46.109+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.7%" -time=2026-06-29T12:10:46.111+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.7%" -time=2026-06-29T12:10:46.114+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.7%" -time=2026-06-29T12:10:46.119+02:00 level=INFO msg=progress id=cd696a78 url="https://www.youtube.com/watch?v=-fZM9wOvbh0" percentage=" 97.8%"