Add testing on github

This commit is contained in:
Ivan Habunek 2024-04-24 07:55:43 +02:00
parent ad0f0d2a41
commit 900914377b
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
7 changed files with 250 additions and 10 deletions

27
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Run tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"
- name: Run tests
run: |
pytest
- name: Validate minimum required version
run: |
vermin --no-tips twitchdl

View File

@ -43,6 +43,11 @@ dev = [
"vermin",
]
test = [
"pytest",
"vermin",
]
[project.urls]
"Homepage" = "https://twitch-dl.bezdomni.net/"
"Source" = "https://github.com/ihabunek/twitch-dl"

View File

@ -2,7 +2,7 @@ import logging
import platform
import re
import sys
from typing import Optional
from typing import Optional, Tuple
import click
@ -255,7 +255,7 @@ def clips(
default=5,
)
def download(
ids: tuple[str, ...],
ids: Tuple[str, ...],
auth_token: Optional[str],
chapter: Optional[int],
concat: bool,
@ -374,7 +374,7 @@ def videos(
channel_name: str,
all: bool,
compact: bool,
games_tuple: tuple[str, ...],
games_tuple: Tuple[str, ...],
json: bool,
limit: Optional[int],
pager: Optional[int],

View File

@ -7,6 +7,7 @@ from twitchdl import twitch, utils
from twitchdl.commands.download import get_video_placeholders
from twitchdl.exceptions import ConsoleError
from twitchdl.output import bold, print_clip, print_json, print_log, print_table, print_video
from twitchdl.playlists import parse_playlists
from twitchdl.twitch import Chapter, Clip, Video
@ -50,13 +51,13 @@ def info(id: str, *, json: bool = False):
raise ConsoleError(f"Invalid input: {id}")
def video_info(video: Video, playlists, chapters: List[Chapter]):
def video_info(video: Video, playlists: str, chapters: List[Chapter]):
click.echo()
print_video(video)
click.echo("Playlists:")
for p in m3u8.loads(playlists).playlists:
click.echo(f"{bold(p.stream_info.video)} {p.uri}")
for p in parse_playlists(playlists):
click.echo(f"{bold(p.name)} {p.url}")
if chapters:
click.echo()
@ -72,7 +73,7 @@ def video_info(video: Video, playlists, chapters: List[Chapter]):
print_table(["Placeholder", "Value"], placeholders)
def video_json(video, playlists, chapters):
def video_json(video: Video, playlists: str, chapters: List[Chapter]):
playlists = m3u8.loads(playlists).playlists
video["playlists"] = [

View File

@ -29,11 +29,15 @@ class Vod:
"""Segment duration in seconds"""
def parse_playlists(playlists_m3u8: str):
def parse_playlists(playlists_m3u8: str) -> List[Playlist]:
def _parse(source: str) -> Generator[Playlist, None, None]:
document = load_m3u8(source)
for p in document.playlists:
from pprint import pp
pp(p.__dict__)
pp(p.stream_info.__dict__)
if p.stream_info.resolution:
name = p.media[0].name
resolution = "x".join(str(r) for r in p.stream_info.resolution)

View File

@ -3,7 +3,7 @@ Twitch API access.
"""
import json
from typing import Dict, Generator, List, Literal, Mapping, Optional, TypedDict
from typing import Dict, Generator, List, Literal, Mapping, Optional, Tuple, TypedDict
import click
import httpx
@ -345,7 +345,7 @@ def channel_videos_generator(
sort: VideosSort,
type: VideosType,
game_ids: Optional[List[str]] = None,
) -> tuple[int, Generator[Video, None, None]]:
) -> Tuple[int, Generator[Video, None, None]]:
game_ids = game_ids or []
def _generator(videos: Data, max_videos: int) -> Generator[Video, None, None]:

203
video_before.json Normal file
View File

@ -0,0 +1,203 @@
{
"id": "2115833882",
"title": "Games I Feel Like Speedrun Marathon !newyt !Slender !Merch",
"description": null,
"publishedAt": "2024-04-10T05:01:12Z",
"broadcastType": "ARCHIVE",
"lengthSeconds": 30163,
"game": {
"id": "21063",
"name": "Saw"
},
"creator": {
"login": "ecdycis",
"displayName": "Ecdycis"
},
"playlists": [
{
"bandwidth": 6395968,
"resolution": [
1920,
1080
],
"codecs": "avc1.64002A,mp4a.40.2",
"video": "chunked",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/chunked/index-muted-GKGIUOE29B.m3u8"
},
{
"bandwidth": 3430341,
"resolution": [
1280,
720
],
"codecs": "avc1.4D0020,mp4a.40.2",
"video": "720p60",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/720p60/index-muted-GKGIUOE29B.m3u8"
},
{
"bandwidth": 1448243,
"resolution": [
852,
480
],
"codecs": "avc1.4D001F,mp4a.40.2",
"video": "480p30",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/480p30/index-muted-GKGIUOE29B.m3u8"
},
{
"bandwidth": 215544,
"resolution": null,
"codecs": "mp4a.40.2",
"video": "audio_only",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/audio_only/index-muted-GKGIUOE29B.m3u8"
},
{
"bandwidth": 709051,
"resolution": [
640,
360
],
"codecs": "avc1.4D001E,mp4a.40.2",
"video": "360p30",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/360p30/index-muted-GKGIUOE29B.m3u8"
},
{
"bandwidth": 288844,
"resolution": [
284,
160
],
"codecs": "avc1.4D000C,mp4a.40.2",
"video": "160p30",
"uri": "https://d2nvs31859zcd8.cloudfront.net/3104d817048588f268fa_ecdycis_43996750059_1712725267/160p30/index-muted-GKGIUOE29B.m3u8"
}
],
"chapters": [
{
"id": "6049e803f47a0b9cf64ce95adcf3d96d",
"durationMilliseconds": 4891000,
"positionMilliseconds": 0,
"type": "GAME_CHANGE",
"description": "Saw",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "21063",
"displayName": "Saw",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/21063_IGDB-40x53.jpg",
"__typename": "Game"
}
},
{
"id": "c3be4ce5a7bae802d7a6df02baf62a85",
"durationMilliseconds": 6235000,
"positionMilliseconds": 4891000,
"type": "GAME_CHANGE",
"description": "Resident Evil 7: Biohazard",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "492934",
"displayName": "Resident Evil 7: Biohazard",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/492934_IGDB-40x53.jpg",
"__typename": "Game"
}
},
{
"id": "bd584f17bc1f91fc11ed14dcec5e4742",
"durationMilliseconds": 3401000,
"positionMilliseconds": 11126000,
"type": "GAME_CHANGE",
"description": "Silent Hill: Homecoming",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "18864",
"displayName": "Silent Hill: Homecoming",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/18864_IGDB-40x53.jpg",
"__typename": "Game"
}
},
{
"id": "9f4be8bc7b5bf398213bc602a4b39c4d",
"durationMilliseconds": 3490000,
"positionMilliseconds": 14527000,
"type": "GAME_CHANGE",
"description": "Silent Hill 2",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "9891",
"displayName": "Silent Hill 2",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/9891_IGDB-40x53.jpg",
"__typename": "Game"
}
},
{
"id": "7a42d537681decc10660c33f9071a37f",
"durationMilliseconds": 7241000,
"positionMilliseconds": 18017000,
"type": "GAME_CHANGE",
"description": "The Darkness",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "8448",
"displayName": "The Darkness",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/8448_IGDB-40x53.jpg",
"__typename": "Game"
}
},
{
"id": "64418186f436d80b1359d2e6686222ef",
"durationMilliseconds": 4905000,
"positionMilliseconds": 25258000,
"type": "GAME_CHANGE",
"description": "Silent Hill 4: The Room",
"subDescription": "",
"thumbnailURL": "",
"video": {
"id": "2115833882",
"lengthSeconds": 30163,
"__typename": "Video"
},
"__typename": "VideoMoment",
"game": {
"id": "5804",
"displayName": "Silent Hill 4: The Room",
"boxArtURL": "https://static-cdn.jtvnw.net/ttv-boxart/5804_IGDB-40x53.jpg",
"__typename": "Game"
}
}
]
}