feat: Twitch VOD download support#553
Closed
biodrone wants to merge 25 commits into
Closed
Conversation
Bumps [WyriHaximus/github-action-get-previous-tag](https://github.com/wyrihaximus/github-action-get-previous-tag) from 1 to 2. - [Release notes](https://github.com/wyrihaximus/github-action-get-previous-tag/releases) - [Commits](WyriHaximus/github-action-get-previous-tag@v1...v2) --- updated-dependencies: - dependency-name: WyriHaximus/github-action-get-previous-tag dependency-version: '2' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](docker/login-action@v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v4...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](docker/setup-qemu-action@v3...v4) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](docker/setup-buildx-action@v3...v4) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [grpcio](https://github.com/grpc/grpc) from 1.76.0 to 1.80.0. - [Release notes](https://github.com/grpc/grpc/releases) - [Commits](grpc/grpc@v1.76.0...v1.80.0) --- updated-dependencies: - dependency-name: grpcio dependency-version: 1.80.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@v5...v6) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [yt-dlp](https://github.com/yt-dlp/yt-dlp) from 2025.10.22 to 2026.3.17. - [Release notes](https://github.com/yt-dlp/yt-dlp/releases) - [Changelog](https://github.com/yt-dlp/yt-dlp/blob/master/Changelog.md) - [Commits](yt-dlp/yt-dlp@2025.10.22...2026.03.17) --- updated-dependencies: - dependency-name: yt-dlp dependency-version: 2026.3.17 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [streamlink](https://github.com/streamlink/streamlink) from 7.6.0 to 8.3.0. - [Release notes](https://github.com/streamlink/streamlink/releases) - [Changelog](https://github.com/streamlink/streamlink/blob/master/CHANGELOG.md) - [Commits](streamlink/streamlink@7.6.0...8.3.0) --- updated-dependencies: - dependency-name: streamlink dependency-version: 8.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [curl-cffi](https://github.com/lexiforest/curl_cffi) from 0.13.0 to 0.15.0. - [Release notes](https://github.com/lexiforest/curl_cffi/releases) - [Changelog](https://github.com/lexiforest/curl_cffi/blob/main/docs/changelog.rst) - [Commits](lexiforest/curl_cffi@v0.13.0...v0.15.0) --- updated-dependencies: - dependency-name: curl-cffi dependency-version: 0.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(release): update dependencies and bump version to 3.5.0 * Revert "chore(release): update dependencies and bump version to 3.5.0" This reverts commit 847aca3. * chore(release)🤖: v3.5.1 [skip ci] [skip ci] * chore(release)🤖: v3.6.0 [skip ci] [skip ci] * chore(deps): bump pygments from 2.18.0 to 2.20.0 Bumps [pygments](https://github.com/pygments/pygments) from 2.18.0 to 2.20.0. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](pygments/pygments@2.18.0...2.20.0) --- updated-dependencies: - dependency-name: pygments dependency-version: 2.20.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Josh Jacobs <josh.jacobs@datasolace.com> Co-authored-by: Conventional Changelog Action <conventional.changelog.action@github.com> Co-authored-by: Josh J <josh@joshjacobs.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(release): update dependencies and bump version to 3.5.0 * Revert "chore(release): update dependencies and bump version to 3.5.0" This reverts commit 847aca3. * chore(release)🤖: v3.5.1 [skip ci] [skip ci] * chore(release)🤖: v3.6.0 [skip ci] [skip ci] * chore(deps): bump requests from 2.32.3 to 2.33.0 Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.33.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](psf/requests@v2.32.3...v2.33.0) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Josh Jacobs <josh.jacobs@datasolace.com> Co-authored-by: Conventional Changelog Action <conventional.changelog.action@github.com> Co-authored-by: Josh J <josh@joshjacobs.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(release): update dependencies and bump version to 3.5.0 * Revert "chore(release): update dependencies and bump version to 3.5.0" This reverts commit 847aca3. * chore(release)🤖: v3.5.1 [skip ci] [skip ci] * chore(release)🤖: v3.6.0 [skip ci] [skip ci] * chore(deps): bump pytest from 8.3.3 to 9.0.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.3 to 9.0.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](pytest-dev/pytest@8.3.3...9.0.3) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Josh Jacobs <josh.jacobs@datasolace.com> Co-authored-by: Conventional Changelog Action <conventional.changelog.action@github.com> Co-authored-by: Josh J <josh@joshjacobs.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(release): update dependencies and bump version to 3.5.0 * Revert "chore(release): update dependencies and bump version to 3.5.0" This reverts commit 847aca3. * chore(release)🤖: v3.5.1 [skip ci] [skip ci] * chore(release)🤖: v3.6.0 [skip ci] [skip ci] * chore(deps): bump urllib3 from 2.2.3 to 2.6.3 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.3 to 2.6.3. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](urllib3/urllib3@2.2.3...2.6.3) --- updated-dependencies: - dependency-name: urllib3 dependency-version: 2.6.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Josh Jacobs <josh.jacobs@datasolace.com> Co-authored-by: Conventional Changelog Action <conventional.changelog.action@github.com> Co-authored-by: Josh J <josh@joshjacobs.net> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…g/actions/checkout-6' into staging
…g/actions/setup-node-6' into staging
…g/docker/login-action-4' into staging
…g/docker/setup-qemu-action-4' into staging
…g/docker/setup-buildx-action-4' into staging
…g/WyriHaximus/github-action-get-previous-tag-2' into staging
Add ability to download past broadcasts (VODs) from Twitch channels. Per-channel `vod: true` config toggle switches from live stream to VOD mode, with a SQLite database tracking download state to avoid re-downloading and handle crash recovery via stale threshold detection. - Add GetVods gRPC RPC using yt-dlp for VOD enumeration - Add SQLite VOD tracking with status-based lifecycle (downloading/completed/failed) - Add downloadVOD function with stream copy and VOD-specific filenames - Add -data, -vod-out, -vod-move flags for configurable paths - Wire VOD branch into main tick loop with ShouldDownloadVOD gating - Add VOD phase to integration test - Update README and example config
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (23)
📝 WalkthroughWalkthroughThis PR implements a VOD (Video On Demand) download feature for Twitch, including SQLite-backed download state tracking, gRPC service extension, CLI/config support, and integration tests. GitHub Actions workflows are updated to newer major versions, and Python/Go dependencies are bumped. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as StreamDL Client
participant CtxMgr as Control Logic<br/>(streamdl.go)
participant GrpcSrv as gRPC Server<br/>(Python)
participant YtDlp as yt-dlp
participant VodDB as SQLite DB<br/>(VOD State)
participant FFmpeg as FFmpeg Process
participant FileIO as Output Directories
CtxMgr->>GrpcSrv: getVods(site, user, limit)
GrpcSrv->>YtDlp: extract_info(url, download=False)
YtDlp-->>GrpcSrv: VOD metadata list
GrpcSrv-->>CtxMgr: [VodResult{id, title, ...}]
loop For each discovered VOD
CtxMgr->>VodDB: ShouldDownloadVOD(vodID, staleThreshold)
alt VOD not yet downloaded
VodDB-->>CtxMgr: true (proceed)
CtxMgr->>GrpcSrv: getStream(site, "videos/"+vodID, quality)
GrpcSrv-->>CtxMgr: resolved URL
CtxMgr->>VodDB: MarkVODStarted(vodID, user, site, title)
CtxMgr->>FFmpeg: downloadVOD(user, vod, url, outLoc, moveLoc, vodDB)
FFmpeg->>FileIO: Write video with stream-copy
FFmpeg-->>CtxMgr: completion status
alt Success
CtxMgr->>VodDB: MarkVODCompleted(vodID)
CtxMgr->>FileIO: Move to final destination
else Failure
CtxMgr->>VodDB: MarkVODFailed(vodID)
end
else VOD already downloaded or in-progress
VodDB-->>CtxMgr: false (skip)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Collaborator
Author
|
Duplicate — updating existing draft PR #551 instead. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
vod: trueconfig toggle to download Twitch past broadcasts instead of live streamsGetVodsgRPC RPC enumerates VODs via yt-dlp; existingGetStreamresolves each VOD URL through Streamlink/yt-dlp-vod-out/-vod-moveflags allow routing VOD downloads to different directories than live streams{user}_vod_{id}_{title}.mp4naming with stream copy (no re-encoding)Test plan
TestParseConfig_VODFields— VOD config parsingTestVodDB_InitAndClose— DB creationTestVodDB_FullLifecycle— started → completed lifecycleTestVodDB_FailedVODIsRetried— failed VODs are retriedTestVodDB_StaleDownloadIsRetried— stale downloads detected and retriedTestVodDB_DifferentVODsAreIndependent— VOD isolationtests/integration/run.shvod: trueand verify VODs download and are tracked in DBSummary by CodeRabbit
Release Notes
New Features
vodandvod_limit)-data,-vod-out, and-vod-movefor managing VOD downloads and persistent state trackingDocumentation
Dependencies
Chores