Test Failed
Push — dev ( 525e4d...14334c )
by Konstantinos
04:52
created

test_downloading.download_video()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
import pytest
2
3
4
@pytest.fixture
5
def download_video():
6
    from music_album_creation.downloading import CMDYoutubeDownloader
7
8
    yd = CMDYoutubeDownloader()
9
    return yd.download_trials
10
11
12
@pytest.mark.network_bound
13
@pytest.mark.parametrize(
14
    'url',
15
    [
16
        'https://www.youtube.com/watch?v=OvC-4BixxkY',
17
    ],
18
)
19
def test_downloading_audio_stream_without_specifying_output(
20
    url, tmp_path_factory, download_video
21
):
22
    # GIVEN a youtube video url
23
    runtime_url: str = url
24
25
    # WHEN downloading the audio stream
26
    output_directory = tmp_path_factory.mktemp("youtubedownloads")
27
    TIMES = 3
28
    local_file = download_video(runtime_url, output_directory, times=TIMES)
29
30
    # THEN the audio stream is downloaded
31
    from pathlib import Path
32
33
    runtime_file = Path(local_file)
34
    assert runtime_file.exists()
35
36
    # AND the audio stream is saved in the output directory
37
    assert runtime_file.parent == output_directory
38
39
    # AND the audio stream has the expected name
40
    assert runtime_file.name == 'Burning.webm'
41
    # AND the audio stream has the expected extension
42
    assert runtime_file.suffix == '.webm'
43
44
    # AND the audio stream has the expected size
45
    expected_bytes_size = 6560225
46
    assert runtime_file.stat().st_size == expected_bytes_size  # 6.26 MB
47
    assert 6, 256318092 - expected_bytes_size / 1024.0 / 1024.0 < 0.1
48
    """
49
    ffprobe -v error -show_entries stream_tags=rotate:format=size,duration:stream=codec_name,bit_rate -of default=noprint_wrappers=1 ./Burning.webm
50
    """
51
    import os
52
53
    from music_album_creation.ffmpeg import FFProbe
54
    from music_album_creation.ffprobe_client import FFProbeClient
55
56
    ffprobe = FFProbe(os.environ.get('MUSIC_FFPROBE', 'ffprobe'))
57
    ffprobe_client = FFProbeClient(ffprobe)
58
59
    # Query Media File to get metadata information
60
    data = ffprobe_client.get_stream_info(str(runtime_file))
61
    import json
62
63
    print(json.dumps(data, indent=4, sort_keys=True))
64
65
    assert data['programs'] == []
66
    assert len(data['streams']) == 1
67
68
    assert data['streams'][0]['tags'] == {}
69
70
    # AND the audio stream has the expected Sample Rate (Hz)
71
    assert data['streams'][0]['sample_rate'] == '48000'
72
73
    # AND the audio stream has the expected codec
74
    assert data['streams'][0]['codec_name'] == 'opus'
75
76
    # AND the audio stream has the expected number of channels
77
    assert data['streams'][0]['channels'] == 2
78
79
    assert data['format']['format_name'] == 'matroska,webm'
80
    assert data['format']['format_long_name'] == 'Matroska / WebM'
81
    assert data['format']['start_time'] == '-0.007000'
82
    assert data['format']['duration'] == '393.161000'
83
    assert data['format']['size'] == str(expected_bytes_size)
84
    assert data['format']['bit_rate'] == '133486'  # bits per second
85
    assert data['format']['probe_score'] == 100
86
    assert data['format']['tags']['encoder'] == 'google/video-file'
87
88
89
@pytest.mark.network_bound
90
@pytest.mark.parametrize(
91
    'url',
92
    [
93
        'https://www.youtube.com/watch?v=OvC-4BixxkY',
94
    ],
95
)
96
def test_downloading_audio_stream_specifying_mp3_output(url, tmp_path_factory):
97
    # GIVEN a youtube video url
98
    runtime_url: str = url
99
100
    # WHEN downloading the audio stream
101
    from pytube import YouTube
102
103
    output_directory = tmp_path_factory.mktemp("youtubedownloads")
104
105
    youtube_video = YouTube(runtime_url)
106
    try:
107
        title: str = youtube_video.title
108
    except Exception as error:
109
        print(error)
110
        title = 'Burning'
111
112
    highest_bitrate_audio_stream = youtube_video.streams.filter(only_audio=True).order_by(
113
        'bitrate'
114
    )[-1]
115
116
    local_file = highest_bitrate_audio_stream.download(
117
        output_path=str(output_directory),
118
        filename=f'{title}.mp3',
119
        filename_prefix=None,
120
        skip_existing=False,  # Skip existing files, defaults to True
121
        timeout=None,  # Request timeout length in seconds. Uses system default
122
        max_retries=0,  # Number of retries to attempt after socket timeout. Defaults to 0
123
    )
124
125
    # THEN the audio stream is downloaded
126
    from pathlib import Path
127
128
    runtime_file = Path(local_file)
129
    assert runtime_file.exists()
130
131
    # AND the audio stream is saved in the output directory
132
    assert runtime_file.parent == output_directory
133
134
    # AND the audio stream has the expected name
135
    assert runtime_file.name == 'Burning.mp3'
136
    # AND the audio stream has the expected extension
137
    assert runtime_file.suffix == '.mp3'
138
139
    # AND the audio stream has the expected size
140
    expected_bytes_size = 6560225
141
    assert runtime_file.stat().st_size == expected_bytes_size  # 6.26 MB
142
    assert 6, 256318092 - expected_bytes_size / 1024.0 / 1024.0 < 0.1
143
    """
144
    ffprobe -v error -show_entries stream_tags=rotate:format=size,duration:stream=codec_name,bit_rate -of default=noprint_wrappers=1 ./Burning.webm
145
    """
146
    import subprocess
147
148
    # Query Media File to get metadata information
149
    cp = subprocess.run(  # pylint: disable=W1510
150
        [
151
            'ffprobe',
152
            '-v',
153
            'error',
154
            '-show_entries',
155
            'stream_tags=rotate:format=size,duration:stream=codec_name,bit_rate,sample_rate,channels,nb_frames',
156
            '-of',
157
            'default=noprint_wrappers=1',
158
            str(runtime_file),
159
        ],
160
        capture_output=True,  # capture stdout and stderr separately
161
        # cwd=project_directory,
162
        check=True,
163
    )
164
165
    res: str = str(cp.stdout, encoding='utf-8')
166
    print(res)
167
    data = dict(x.split('=') for x in res.strip().split('\n'))
168
169
    # AND size reported by ffprobe is the same
170
    assert data['size'] == str(expected_bytes_size)
171
172
    # AND the audio stream has the expected duration
173
    assert data['duration'] == '393.161000'
174
175
    # AND the audio stream has the expected Sample Rate (Hz)
176
    assert data['sample_rate'] == '48000'
177
178
    # AND the audio stream has the expected codec
179
    assert data['codec_name'] == 'opus'
180
181
    # AND the audio stream has the expected bitrate
182
    assert data['bit_rate'] == 'N/A'
183
184
    # AND the audio stream has the expected number of channels
185
    assert data['channels'] == '2'
186
187
    # AND the audio stream has the expected number of frames
188
    assert data['nb_frames'] == 'N/A'
189