Skip to content

Commit

Permalink
* Adding #163 elapsed time in encoding panel (thanks to Benedicte Emi…
Browse files Browse the repository at this point in the history
…lie Brækken)

* Fixing #165 Custom Bitrate loaded from Profile (thanks to Etz)
  • Loading branch information
cdgriffith committed Jan 9, 2021
1 parent 9bac746 commit 1f8be8a
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 63 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
* Adding logging level selector in settings for GUI
* Adding button to extract text based subtitles
* Adding dual pass option for ffmpeg options (thanks to Catatau)
* Adding #163 elapsed time in encoding panel (thanks to Benedicte Emilie Brækken)
* Changing all builds to use Python 3.8, removing idea of "legacy" windows until later time
* Fixing #156 Copy was broken due to ffmpeg extras not being passed (thanks to leonardyan)
* Fixing #158 Translation and icon of tab name "Quality" lost when output codec switched (thanks to leonardyan)
* Fixing #120 Custom bitrate forgets to add a "k" (thanks to seighail3)
* Fixing #162 Main window was not resizeable (thanks to bmcassagne)
* Fixing #165 Custom Bitrate loaded from Profile (thanks to Etz)
* Fixing snap packaged, and other symlinked FFmpeg installs were not linked correctly (thanks to Catatau)
* Fixing loading video could encounter a bug and crash fastflix (thanks to Jan)
* Fixing being able to set landscape cover
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/av1_aom/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ def update_video_encoder_settings(self):

if self.mode == "CRF":
crf = self.widgets.crf.currentText()
settings.crf = int(crf.split(" ", 1)[0]) if crf.lower() != "custom" else self.widgets.custom_crf.text()
if self.widgets.custom_crf.isEnabled():
settings.crf = int(self.widgets.custom_crf.text())
else:
settings.crf = int(crf.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/avc_x264/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ def update_video_encoder_settings(self):

if self.mode == "CRF":
crf = self.widgets.crf.currentText()
settings.crf = int(crf.split(" ", 1)[0]) if crf != "Custom" else int(self.widgets.custom_crf.text())
if self.widgets.custom_crf.isEnabled():
settings.crf = int(self.widgets.custom_crf.text())
else:
settings.crf = int(crf.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
4 changes: 2 additions & 2 deletions fastflix/encoders/common/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def generate_filters(
scale_width=None,
scale_height=None,
remove_hdr=False,
rotate=None,
rotate=0,
vertical_flip=None,
horizontal_flip=None,
burn_in_subtitle_track=None,
Expand All @@ -145,7 +145,7 @@ def generate_filters(
filter_list.append(f"scale={scale_width}:-8:flags={scale_filter}")
elif scale_height:
filter_list.append(f"scale=-8:{scale_height}:flags={scale_filter}")
if rotate is not None:
if rotate:
if rotate < 3:
filter_list.append(f"transpose={rotate}")
if rotate == 4:
Expand Down
18 changes: 18 additions & 0 deletions fastflix/encoders/common/setting_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ def _add_modes(
recommended_qps,
qp_name="crf",
):
self.recommended_bitrates = recommended_bitrates
self.recommended_qps = recommended_qps
self.qp_name = qp_name
layout = QtWidgets.QGridLayout()
qp_group_box = QtWidgets.QGroupBox()
qp_group_box.setStyleSheet("QGroupBox{padding-top:5px; margin-top:-18px}")
Expand Down Expand Up @@ -279,9 +282,24 @@ def update_profile(self):
if bitrate:
self.qp_radio.setChecked(False)
self.bitrate_radio.setChecked(True)
for i, rec in enumerate(self.recommended_bitrates):
if rec.startswith(bitrate):
self.widgets.bitrate.setCurrentIndex(i)
break
else:
self.widgets.bitrate.setCurrentText("Custom")
self.widgets.custom_bitrate.setText(bitrate.rstrip("kKmMgGbB"))
else:
self.qp_radio.setChecked(True)
self.bitrate_radio.setChecked(False)
qp = str(self.app.fastflix.config.encoder_opt(self.profile_name, self.qp_name))
for i, rec in enumerate(self.recommended_qps):
if rec.startswith(qp):
self.widgets[self.qp_name].setCurrentIndex(i)
break
else:
self.widgets[self.qp_name].setCurrentText("Custom")
self.widgets[f"custom_{self.qp_name}"].setText(qp)
ffmpeg_extra_command = self.app.fastflix.config.encoder_opt(self.profile_name, "extra")
self.ffmpeg_extras_widget.setText(ffmpeg_extra_command)

Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/hevc_x265/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,10 @@ def update_video_encoder_settings(self):

if self.mode == "CRF":
crf = self.widgets.crf.currentText()
settings.crf = int(crf.split(" ", 1)[0]) if crf != "Custom" else int(self.widgets.custom_crf.text())
if self.widgets.custom_crf.isEnabled() and self.widgets.custom_crf.text():
settings.crf = int(self.widgets.custom_crf.text())
else:
settings.crf = int(crf.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/rav1e/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ def update_video_encoder_settings(self):
)
if self.mode == "QP":
qp = self.widgets.qp.currentText()
settings.qp = int(qp.split(" ", 1)[0]) if qp.lower() != "custom" else self.widgets.custom_qp.text()
if self.widgets.custom_qp.isEnabled():
settings.qp = int(self.widgets.custom_qp.text())
else:
settings.qp = int(qp.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/svt_av1/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ def update_video_encoder_settings(self):
)
if self.mode == "QP":
qp = self.widgets.qp.currentText()
settings.qp = int(qp.split(" ", 1)[0]) if qp.lower() != "custom" else self.widgets.custom_qp.text()
if self.widgets.custom_qp.isEnabled():
settings.qp = int(self.widgets.custom_qp.text())
else:
settings.qp = int(qp.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/vp9/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ def update_video_encoder_settings(self):
)
if self.mode == "CRF":
crf = self.widgets.crf.currentText()
settings.crf = int(crf.split(" ", 1)[0]) if crf.lower() != "custom" else self.widgets.custom_crf.text()
if self.widgets.custom_crf.isEnabled():
settings.crf = int(self.widgets.custom_crf.text())
else:
settings.crf = int(crf.split(" ", 1)[0])
else:
bitrate = self.widgets.bitrate.currentText()
if bitrate.lower() == "custom":
Expand Down
5 changes: 4 additions & 1 deletion fastflix/encoders/webp/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ def update_video_encoder_settings(self):
extra_both_passes=self.widgets.extra_both_passes.isChecked(),
)
qscale = self.widgets.qscale.currentText()
settings.qscale = int(qscale) if qscale.lower() != "custom" else int(self.widgets.custom_qscale.text())
if self.widgets.custom_qscale.isEnabled():
settings.qscale = int(self.widgets.custom_qscale.text())
else:
settings.qscale = int(qscale.split(" ", 1)[0])
self.app.fastflix.current_video.video_settings.video_encoder_settings = settings

def new_source(self):
Expand Down
43 changes: 19 additions & 24 deletions fastflix/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@

NO_OPT = object()

setting_types = {
"x265": x265Settings,
"x264": x264Settings,
"rav1e": rav1eSettings,
"svt_av1": SVTAV1Settings,
"vp9": VP9Settings,
"aom_av1": AOMAV1Settings,
"gif": GIFSettings,
"webp": WebPSettings,
"copy_settings": CopySettings,
}


class Profile(BaseModel):
auto_crop: bool = False
Expand Down Expand Up @@ -60,26 +72,6 @@ class Profile(BaseModel):
webp: Optional[WebPSettings] = None
copy_settings: Optional[CopySettings] = None

setting_types = {
"x265": x265Settings,
"x264": x264Settings,
"rav1e": rav1eSettings,
"svt_av1": SVTAV1Settings,
"vp9": VP9Settings,
"aom_av1": AOMAV1Settings,
"gif": GIFSettings,
"webp": WebPSettings,
"copy_settings": CopySettings,
}

def to_dict(self):
output = {}
for k, v in self.dict().items():
if k in self.setting_types.keys():
output[k] = v.dict()
else:
output[k] = v


empty_profile = Profile(x265=x265Settings())

Expand Down Expand Up @@ -158,7 +150,7 @@ def encoder_opt(self, profile_name, profile_option_name):
if encoder_settings:
return getattr(encoder_settings, profile_option_name)
else:
return getattr(empty_profile.setting_types[profile_name](), profile_option_name)
return getattr(setting_types[profile_name](), profile_option_name)

def opt(self, profile_option_name, default=NO_OPT):
if default != NO_OPT:
Expand Down Expand Up @@ -189,10 +181,13 @@ def load(self):
continue
profile = Profile()
for setting_name, setting in v.items():
if setting_name in profile.setting_types.keys() and setting is not None:
setattr(profile, setting_name, profile.setting_types[setting_name](**setting))
if setting_name in setting_types.keys() and setting is not None:
setattr(profile, setting_name, setting_types[setting_name](**setting))
else:
setattr(profile, setting_name, setting)
try:
setattr(profile, setting_name, setting)
except ValueError:
pass # This field is no longer supported

self.profiles[k] = profile
continue
Expand Down
24 changes: 12 additions & 12 deletions fastflix/models/encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class x265Settings(EncoderSettings):
repeat_headers: bool = False
aq_mode: int = 2
hdr10plus_metadata: str = ""
crf: Union[int, None] = None
bitrate: Union[str, None] = None
crf: Optional[int] = 22
bitrate: Optional[str] = None
x265_params: List[str] = Field(default_factory=list)
bframes: int = 4
lossless: bool = False
Expand All @@ -70,8 +70,8 @@ class x264Settings(EncoderSettings):
profile: str = "default"
tune: Optional[str] = None
pix_fmt: str = "yuv420p"
crf: Union[int, None] = None
bitrate: Union[str, None] = None
crf: Optional[int] = 23
bitrate: Optional[str] = None


class rav1eSettings(EncoderSettings):
Expand All @@ -81,8 +81,8 @@ class rav1eSettings(EncoderSettings):
tile_rows: str = "-1"
tiles: str = "0"
single_pass: bool = False
qp: Union[int, None] = None
bitrate: Union[str, None] = None
qp: Optional[int] = 24
bitrate: Optional[str] = None


class SVTAV1Settings(EncoderSettings):
Expand All @@ -93,8 +93,8 @@ class SVTAV1Settings(EncoderSettings):
# scene_detection: str = "false"
single_pass: bool = False
speed: str = "7"
qp: Union[int, None] = None
bitrate: Union[str, None] = None
qp: Optional[int] = 24
bitrate: Optional[str] = None


class VP9Settings(EncoderSettings):
Expand All @@ -104,8 +104,8 @@ class VP9Settings(EncoderSettings):
speed: str = "0"
row_mt: int = 0
single_pass: bool = False
crf: Union[int, None] = None
bitrate: Union[str, None] = None
crf: Optional[int] = 31
bitrate: Optional[str] = None


class AOMAV1Settings(EncoderSettings):
Expand All @@ -115,8 +115,8 @@ class AOMAV1Settings(EncoderSettings):
usage: str = "good"
row_mt: str = "enabled"
cpu_used: str = "4"
crf: Union[int, None] = None
bitrate: Union[str, None] = None
crf: Optional[int] = 26
bitrate: Optional[str] = None


class WebPSettings(EncoderSettings):
Expand Down
24 changes: 12 additions & 12 deletions fastflix/models/video.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import uuid
from pathlib import Path
from typing import List, Union
from typing import List, Union, Optional

from box import Box
from pydantic import BaseModel, Field
Expand All @@ -25,11 +25,11 @@


class VideoSettings(BaseModel):
crop: Union[str, None] = None
crop: Optional[str] = None
start_time: Union[float, int] = 0
end_time: Union[float, int] = 0
fast_seek: bool = True
rotate: Union[str, None] = None
rotate: int = 0
vertical_flip: bool = False
horizontal_flip: bool = False
remove_hdr: bool = False
Expand All @@ -38,19 +38,19 @@ class VideoSettings(BaseModel):
video_title: str = ""
selected_track: int = 0
output_path: Path = None
scale: Union[str, None] = None
scale: Optional[str] = None
deinterlace: bool = False
video_speed: Union[float, int] = 1
tone_map: str = "hable"
denoise: Union[str, None] = None
deblock: Union[str, None] = None
denoise: Optional[str] = None
deblock: Optional[str] = None
deblock_size: int = 4
color_space: Union[str, None] = None
color_transfer: Union[str, None] = None
color_primaries: Union[str, None] = None
source_fps: Union[str, None] = None
output_fps: Union[str, None] = None
vsync: Union[str, None] = None
color_space: Optional[str] = None
color_transfer: Optional[str] = None
color_primaries: Optional[str] = None
source_fps: Optional[str] = None
output_fps: Optional[str] = None
vsync: Optional[str] = None
video_encoder_settings: Union[
x265Settings,
x264Settings,
Expand Down
2 changes: 1 addition & 1 deletion fastflix/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__version__ = "4.1.0b1"
__version__ = "4.1.0b2"
__author__ = "Chris Griffith"
5 changes: 3 additions & 2 deletions fastflix/widgets/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from fastflix.widgets.profile_window import ProfileWindow
from fastflix.widgets.progress_bar import ProgressBar, Task
from fastflix.widgets.settings import Settings
from fastflix.models.config import setting_types

logger = logging.getLogger("fastflix")

Expand Down Expand Up @@ -262,7 +263,7 @@ def __init__(self, profile_name, profile):
profile_title.setFont(QtGui.QFont("helvetica", 10, weight=70))
main_section.addWidget(profile_title)
for k, v in profile.dict().items():
if k not in profile.setting_types.keys():
if k not in setting_types.keys():
item_1 = QtWidgets.QLabel(" ".join(str(k).split("_")).title())
item_2 = QtWidgets.QLabel(str(v))
item_2.setMaximumWidth(150)
Expand All @@ -277,7 +278,7 @@ def __init__(self, profile_name, profile):
splitter.setStyleSheet("background-color: #999999")
self.layout.addWidget(splitter)

for setting_name in profile.setting_types.keys():
for setting_name in setting_types.keys():
setting = getattr(profile, setting_name)
if setting:
self.layout.addWidget(self.profile_widget(setting))
Expand Down
6 changes: 3 additions & 3 deletions fastflix/widgets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,12 +456,12 @@ def init_rotate(self):
return self.widgets.rotate

def rotation_to_transpose(self):
mapping = {0: None, 1: 1, 2: 4, 3: 2}
mapping = {0: 0, 1: 1, 2: 4, 3: 2}
return mapping[self.widgets.rotate.currentIndex()]

def transpose_to_rotation(self, transpose):
mapping = {None: 0, 1: 1, 4: 2, 2: 3}
return mapping[int(transpose) if transpose else None]
mapping = {0: 0, 1: 1, 4: 2, 2: 3}
return mapping[int(transpose)]

def change_output_types(self):
self.widgets.convert_to.clear()
Expand Down

0 comments on commit 1f8be8a

Please sign in to comment.