Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions ffmpeg4discord/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ def twopass_loop(
break

print(
dedent(
f"""\033[31m
"\033[31m"
+ dedent(
f"""
The output file size ({round(result.output_filesize, 2)}MB) is still above the target of {target_filesize}MB.
Restarting...
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)
Path(result.output_filename).unlink()

Expand Down Expand Up @@ -433,12 +435,14 @@ def main() -> None:

if version_info.update_available:
print(
dedent(
f"""\033[33m
"\033[33m"
+ dedent(
f"""
Update available: {version_info.latest_version} (you are running {version_info.current_version}).
Upgrade with: pip install -U ffmpeg4discord
\033[0m"""
"""
).strip()
+ "\033[0m"
)

# get args from the command line
Expand Down
10 changes: 6 additions & 4 deletions ffmpeg4discord/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,16 @@ def _parse_astreams(args: dict) -> dict:
parsed = [int(p) for p in parts]
except ValueError:
logging.error(
dedent(
"""\033[31m
"\033[31m"
+ dedent(
"""
Invalid --astreams format.

Provide a comma-separated list of integers, e.g. --astreams "0,1,2".
Ignoring --astreams.
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)
args["astreams"] = None
return args
Expand Down
66 changes: 39 additions & 27 deletions ffmpeg4discord/twopass.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,20 @@ def run_pass(ffoutput, pass_name: str, hint: str = "", **run_kwargs):
# compile() can contain Path objects, so stringify each argument before joining.
command = " ".join(str(arg) for arg in ffoutput.compile())
raise RuntimeError(
dedent(
f"""\033[31m
"\033[31m"
+ dedent(
f"""
FFmpeg failed during the {pass_name} pass.

Look for FFmpeg's error message printed above this traceback -- it names the actual
problem (an unsupported option, a bad filter, a missing encoder, etc.).

The command that failed was:
{command}
\033[0m"""
)
+ (f"\033[31m{hint}\033[0m\n" if hint else "")
"""
).strip()
+ (f"\n\n{hint}" if hint else "")
+ "\033[0m"
) from exc


Expand Down Expand Up @@ -368,12 +370,14 @@ def _check_hdr(self):
self.tonemap = tonemap_filters(self.probe)
if not self.tonemap:
logging.warning(
dedent(
"""\033[31m
"\033[31m"
+ dedent(
"""
This video is HDR, but your ffmpeg can't convert it to SDR. It needs ffmpeg 8.0
or newer, or a build with zscale (libzimg). The output may look washed out.
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)

def clip_times(self, settings: EncodeSettings) -> tuple[float, float]:
Expand All @@ -394,17 +398,19 @@ def clip_times(self, settings: EncodeSettings) -> tuple[float, float]:

if end <= start:
raise ValueError(
dedent(
f"""\033[31m
"\033[31m"
+ dedent(
f"""
Time Paradox?

Something is wrong with your clipping times. Use this
information to further diagnose the problem:

- Your video is {self.duration / 60} minutes long
- Your video is {seconds_to_timestamp(self.duration)} long
- Your clipping times are {seconds_to_timestamp(start)} to {seconds_to_timestamp(end)}
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)

return start, end
Expand Down Expand Up @@ -472,12 +478,14 @@ def _generate_params(self, settings: EncodeSettings, bitrate_targets: dict) -> d
params["pass2"]["r"] = settings.framerate
else:
logging.warning(
dedent(
f"""\033[31m
"\033[31m"
+ dedent(
f"""
Desired framerate ({settings.framerate}) is more than original framerate ({self.init_framerate}).
Keeping the original framerate...
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)

# add in configurations specific to the codec
Expand Down Expand Up @@ -603,12 +611,14 @@ def _output_filename(self, settings: EncodeSettings) -> str:

if output.suffix != ext:
logging.warning(
dedent(
f"""\033[31m
"\033[31m"
+ dedent(
f"""
You specified {settings.codec}, but your output file name ends with {output.suffix}.
I've corrected this.
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)
output = output.with_suffix(ext)

Expand Down Expand Up @@ -636,12 +646,14 @@ def _apply_video_filters(self, video, settings: EncodeSettings):

if ratio != outputratio:
logging.warning(
dedent(
"""\033[31m
"\033[31m"
+ dedent(
"""
Your output resolution's aspect ratio does not match the
input resolution's or your croped resolution's aspect ratio.
\033[0m"""
)
input resolution's or your cropped resolution's aspect ratio.
"""
).strip()
+ "\033[0m"
)

# Tone map last, so a smaller --resolution means fewer pixels to process.
Expand Down
10 changes: 6 additions & 4 deletions ffmpeg4discord/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@

if platform.system() != "Windows":
logging.warning(
dedent(
"""\033[31m
"\033[31m"
+ dedent(
"""
THIS SCRIPT IS INTENDED FOR WINDOWS USERS

If you are running this script on macOS, consider installing ffmpeg with
Homebrew: https://formulae.brew.sh/formula/ffmpeg

If you are running this script on some Linux, learn more about your options
to install ffmpeg on its website: https://ffmpeg.org/download.html#build-linux
\033[0m"""
)
"""
).strip()
+ "\033[0m"
)

sys.exit()
Expand Down
12 changes: 11 additions & 1 deletion tests/test_twopass.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ def test_end_not_after_start_raises(make_twopass, start, end):
make_twopass().clip_times(make_settings(start=start, end=end))


def test_end_not_after_start_message_has_no_indentation(make_twopass):
with pytest.raises(ValueError) as excinfo:
make_twopass().clip_times(make_settings(start="00:00:20", end="00:00:10"))
message = str(excinfo.value)
assert not any(line.startswith(" ") for line in message.splitlines())
assert "Your video is 00:02:00 long" in message # the test video is 120 seconds


def test_target_larger_than_input_raises(make_twopass):
# the fake input is 53,000,000 bytes, about 50.5 MiB
with pytest.raises(ValueError, match="larger than the input file"):
Expand Down Expand Up @@ -704,8 +712,10 @@ def test_run_pass_adds_hint_to_error():
ffoutput = MagicMock()
ffoutput.run.side_effect = ffmpeg.Error("ffmpeg", b"", b"")
ffoutput.compile.return_value = ["ffmpeg"]
with pytest.raises(RuntimeError, match="try x264"):
with pytest.raises(RuntimeError) as excinfo:
run_pass(ffoutput, "single", hint="try x264")
# the hint gets its own paragraph, inside the red text
assert str(excinfo.value).endswith("\n\ntry x264\033[0m")


# --- HDR tone mapping (issue #77) ---
Expand Down
Loading