File size: 3,643 Bytes
58f00c9
84e63a1
58f00c9
 
 
 
 
 
 
 
 
 
84e63a1
 
5f400f8
 
 
 
58f00c9
 
 
84e63a1
 
 
 
 
 
 
 
58f00c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import json
import logging
import os
import shutil
import subprocess
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from bot.errorlog import ChannelLogHandler  # noqa: E402

from .appkit import ctx  # noqa: E402  the handler-level fixture, shared by every test module

__all__ = ["ctx", "needs_ffmpeg"]

HAVE_FFMPEG = shutil.which("ffmpeg") is not None and shutil.which("ffprobe") is not None
needs_ffmpeg = pytest.mark.skipif(not HAVE_FFMPEG, reason="ffmpeg/ffprobe not installed")


@pytest.fixture(autouse=True)
def _no_stray_error_reporters():
    """A test that stops halfway must not leave an error reporter on the root logger for the tests after it."""
    yield
    for handler in [h for h in logging.getLogger().handlers if isinstance(h, ChannelLogHandler)]:
        handler.detach()

SRT_A = "1\n00:00:00,000 --> 00:00:01,000\nkonnichiwa\n\n"
SRT_B = "1\n00:00:00,000 --> 00:00:01,000\nhello\n\n"
FFMETA = """;FFMETADATA1
title=Original Title
[CHAPTER]
TIMEBASE=1/1000
START=0
END=1000
title=Intro
[CHAPTER]
TIMEBASE=1/1000
START=1000
END=2000
title=Main
"""


def run(cmd):
    subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)


def ffprobe_json(path, *extra):
    out = subprocess.run(
        ["ffprobe", "-v", "error", "-print_format", "json", "-show_format", "-show_streams", *extra, str(path)],
        check=True, capture_output=True,
    ).stdout
    return json.loads(out)


@pytest.fixture(scope="session")
def media_dir(tmp_path_factory):
    d = tmp_path_factory.mktemp("media")
    if not HAVE_FFMPEG:
        return d
    (d / "a.srt").write_text(SRT_A)
    (d / "b.srt").write_text(SRT_B)
    (d / "meta.ffmeta").write_text(FFMETA)
    (d / "font.ttf").write_bytes(os.urandom(2048))
    lavfi_v = ["-f", "lavfi", "-i", "testsrc=duration=2:size=320x240:rate=15"]
    lavfi_a = lambda f: ["-f", "lavfi", "-i", f"sine=frequency={f}:duration=2"]  # noqa: E731

    # MKV: 1 video, 3 audio (jpn, eng, hin), 2 subs (jpn, eng), 1 font attachment, 2 chapters
    run(
        ["ffmpeg", "-y", "-loglevel", "error", *lavfi_v, *lavfi_a(440), *lavfi_a(880), *lavfi_a(220),
         "-i", str(d / "a.srt"), "-i", str(d / "b.srt"), "-i", str(d / "meta.ffmeta"),
         "-attach", str(d / "font.ttf"), "-metadata:s:t:0", "mimetype=application/x-truetype-font",
         "-map", "0:v", "-map", "1:a", "-map", "2:a", "-map", "3:a", "-map", "4:s", "-map", "5:s",
         "-map_metadata", "6", "-map_chapters", "6",
         "-c:v", "libx264", "-preset", "ultrafast", "-c:a", "aac", "-c:s", "srt",
         "-metadata:s:a:0", "language=jpn", "-metadata:s:a:0", "title=Japanese Original",
         "-metadata:s:a:1", "language=eng", "-metadata:s:a:2", "language=hin",
         "-metadata:s:s:0", "language=jpn", "-metadata:s:s:1", "language=eng",
         "-disposition:a:0", "default", str(d / "sample.mkv")]
    )
    # MP4: 1 video, 2 audio (jpn, eng), 1 eng subtitle (mov_text)
    run(
        ["ffmpeg", "-y", "-loglevel", "error", *lavfi_v, *lavfi_a(440), *lavfi_a(880), "-i", str(d / "b.srt"),
         "-map", "0:v", "-map", "1:a", "-map", "2:a", "-map", "3:s",
         "-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p", "-c:a", "aac", "-c:s", "mov_text",
         "-metadata:s:a:0", "language=jpn", "-metadata:s:a:1", "language=eng", "-metadata:s:s:0", "language=eng",
         str(d / "sample.mp4")]
    )
    # MP3 with a title tag
    run(
        ["ffmpeg", "-y", "-loglevel", "error", *lavfi_a(440), "-c:a", "libmp3lame", "-metadata", "title=Old",
         str(d / "sample.mp3")]
    )
    return d