Skip to content

Commit

Permalink
* Fixing #171 Be able to select encoder before selecting video
Browse files Browse the repository at this point in the history
  • Loading branch information
cdgriffith committed Feb 13, 2021
1 parent 9b429b3 commit d59111e
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 130 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Adding Windows 10 notification for queue complete success
* Adding #194 fast two pass encoding (thanks to Ugurtan)
* Fixing German translations (thanks to SMESH)
* Fixing #171 Be able to select encoder before selecting video
* Fixing #176 Unable to change queue order or delete task from queue since 4.1.0 (thanks to Etz)
* Fixing #185 need to specify channel layout when downmixing (thanks to Ugurtan)
* Fixing #187 cleaning up partial download of FFmpeg (thanks to Todd Wilkinson)
Expand Down
1 change: 1 addition & 0 deletions fastflix/conversion_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def start_command():
currently_encoding = False
allow_sleep_mode()
status_queue.put(("cancelled", video.uuid if video else ""))
log_queue.put("STOP_TIMER")

if request[0] == "pause queue":
logger.debug(t("Command worker received request to pause encoding after the current item completes"))
Expand Down
2 changes: 2 additions & 0 deletions fastflix/data/languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3052,3 +3052,5 @@ vsync:
zho: vsync
There are no videos to start converting:
eng: There are no videos to start converting
No crop, scale, rotation,flip nor any other filters will be applied.:
eng: No crop, scale, rotation,flip nor any other filters will be applied.
65 changes: 65 additions & 0 deletions fastflix/encoders/common/nvencc_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
from typing import List, Dict
import logging

from fastflix.models.video import SubtitleTrack, AudioTrack
from fastflix.encoders.common.audio import lossless


logger = logging.getLogger("fastflix")


def get_stream_pos(streams) -> Dict:
return {x.index: i for i, x in enumerate(streams, start=1)}


def build_audio(audio_tracks: List[AudioTrack], audio_streams):
command_list = []
copies = []
track_ids = set()
stream_ids = get_stream_pos(audio_streams)

for track in sorted(audio_tracks, key=lambda x: x.outdex):
if track.index in track_ids:
logger.warning("NVEncC does not support copy and duplicate of audio tracks!")
track_ids.add(track.index)
audio_id = stream_ids[track.index]
if track.language:
command_list.append(f"--audio-metadata {audio_id}?language={track.language}")
if not track.conversion_codec or track.conversion_codec == "none":
copies.append(str(audio_id))
elif track.conversion_codec:
downmix = f"--audio-stream {audio_id}?:{track.downmix}" if track.downmix else ""
bitrate = ""
if track.conversion_codec not in lossless:
bitrate = f"--audio-bitrate {audio_id}?{track.conversion_bitrate.rstrip('k')} "
command_list.append(
f"{downmix} --audio-codec {audio_id}?{track.conversion_codec} {bitrate} "
f"--audio-metadata {audio_id}?clear"
)

if track.title:
command_list.append(
f'--audio-metadata {audio_id}?title="{track.title}" '
f'--audio-metadata {audio_id}?handler="{track.title}" '
)

return f" --audio-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"


def build_subtitle(subtitle_tracks: List[SubtitleTrack], subtitle_streams) -> str:
command_list = []
copies = []
stream_ids = get_stream_pos(subtitle_streams)

for track in sorted(subtitle_tracks, key=lambda x: x.outdex):
sub_id = stream_ids[track.index]
if track.burn_in:
command_list.append(f"--vpp-subburn track={sub_id}")
else:
copies.append(str(sub_id))
if track.disposition:
command_list.append(f"--sub-disposition {sub_id}?{track.disposition}")
command_list.append(f"--sub-metadata {sub_id}?language='{track.language}'")

return f" --sub-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"
2 changes: 2 additions & 0 deletions fastflix/encoders/hevc_x265/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ def hdr_opts():
self.updating_settings = False

def new_source(self):
if not self.app.fastflix.current_video:
return
super().new_source()
self.setting_change()
if self.app.fastflix.current_video.hdr10_plus:
Expand Down
53 changes: 2 additions & 51 deletions fastflix/encoders/nvencc_avc/command_builder.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,16 @@
# -*- coding: utf-8 -*-
from typing import List
import logging

from fastflix.encoders.common.helpers import Command
from fastflix.models.encode import NVEncCAVCSettings
from fastflix.models.video import SubtitleTrack, Video
from fastflix.models.video import Video
from fastflix.models.fastflix import FastFlix
from fastflix.shared import unixy

lossless = ["flac", "truehd", "alac", "tta", "wavpack", "mlp"]
from fastflix.encoders.common.nvencc_helpers import build_subtitle, build_audio

logger = logging.getLogger("fastflix")


def build_audio(audio_tracks):
command_list = []
copies = []
track_ids = set()

for track in audio_tracks:
if track.index in track_ids:
logger.warning("NVEncC does not support copy and duplicate of audio tracks!")
track_ids.add(track.index)
if track.language:
command_list.append(f"--audio-metadata {track.outdex}?language={track.language}")
if not track.conversion_codec or track.conversion_codec == "none":
copies.append(str(track.outdex))
elif track.conversion_codec:
downmix = f"--audio-stream {track.outdex}?:{track.downmix}" if track.downmix else ""
bitrate = ""
if track.conversion_codec not in lossless:
bitrate = f"--audio-bitrate {track.outdex}?{track.conversion_bitrate.rstrip('k')} "
command_list.append(
f"{downmix} --audio-codec {track.outdex}?{track.conversion_codec} {bitrate} "
f"--audio-metadata {track.outdex}?clear"
)

if track.title:
command_list.append(
f'--audio-metadata {track.outdex}?title="{track.title}" '
f'--audio-metadata {track.outdex}?handler="{track.title}" '
)

return f" --audio-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"


def build_subtitle(subtitle_tracks: List[SubtitleTrack]) -> str:
command_list = []
copies = []
for i, track in enumerate(subtitle_tracks, start=1):
if track.burn_in:
command_list.append(f"--vpp-subburn track={i}")
else:
copies.append(str(i))
if track.disposition:
command_list.append(f"--sub-disposition {i}?{track.disposition}")
command_list.append(f"--sub-metadata {i}?language='{track.language}'")

return f" --sub-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"


def build(fastflix: FastFlix):
video: Video = fastflix.current_video
settings: NVEncCAVCSettings = fastflix.current_video.video_settings.video_encoder_settings
Expand Down
2 changes: 2 additions & 0 deletions fastflix/encoders/nvencc_avc/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ def set_mode(self, x):
self.main.build_commands()

def new_source(self):
if not self.app.fastflix.current_video:
return
super().new_source()
if self.app.fastflix.current_video.hdr10_plus:
self.extract_button.show()
Expand Down
62 changes: 2 additions & 60 deletions fastflix/encoders/nvencc_hevc/command_builder.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,16 @@
# -*- coding: utf-8 -*-
from typing import List, Dict
import logging

from fastflix.encoders.common.helpers import Command
from fastflix.models.encode import NVEncCSettings
from fastflix.models.video import SubtitleTrack, Video
from fastflix.models.video import Video
from fastflix.models.fastflix import FastFlix
from fastflix.encoders.common.nvencc_helpers import build_subtitle, build_audio
from fastflix.flix import unixy

lossless = ["flac", "truehd", "alac", "tta", "wavpack", "mlp"]

logger = logging.getLogger("fastflix")


def get_stream_pos(streams) -> Dict:
return {x.index: i for i, x in enumerate(streams, start=1)}


def build_audio(audio_tracks, audio_streams):
command_list = []
copies = []
track_ids = set()
stream_ids = get_stream_pos(audio_streams)

for track in sorted(audio_tracks, key=lambda x: x.outdex):
if track.index in track_ids:
logger.warning("NVEncC does not support copy and duplicate of audio tracks!")
track_ids.add(track.index)
audio_id = stream_ids[track.index]
if track.language:
command_list.append(f"--audio-metadata {audio_id}?language={track.language}")
if not track.conversion_codec or track.conversion_codec == "none":
copies.append(str(audio_id))
elif track.conversion_codec:
downmix = f"--audio-stream {audio_id}?:{track.downmix}" if track.downmix else ""
bitrate = ""
if track.conversion_codec not in lossless:
bitrate = f"--audio-bitrate {audio_id}?{track.conversion_bitrate.rstrip('k')} "
command_list.append(
f"{downmix} --audio-codec {audio_id}?{track.conversion_codec} {bitrate} "
f"--audio-metadata {audio_id}?clear"
)

if track.title:
command_list.append(
f'--audio-metadata {audio_id}?title="{track.title}" '
f'--audio-metadata {audio_id}?handler="{track.title}" '
)

return f" --audio-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"


def build_subtitle(subtitle_tracks: List[SubtitleTrack], subtitle_streams) -> str:
command_list = []
copies = []
stream_ids = get_stream_pos(subtitle_streams)

for track in sorted(subtitle_tracks, key=lambda x: x.outdex):
sub_id = stream_ids[track.index]
if track.burn_in:
command_list.append(f"--vpp-subburn track={sub_id}")
else:
copies.append(str(sub_id))
if track.disposition:
command_list.append(f"--sub-disposition {sub_id}?{track.disposition}")
command_list.append(f"--sub-metadata {sub_id}?language='{track.language}'")

return f" --sub-copy {','.join(copies)} {' '.join(command_list)}" if copies else f" {' '.join(command_list)}"


def build(fastflix: FastFlix):
video: Video = fastflix.current_video
settings: NVEncCSettings = fastflix.current_video.video_settings.video_encoder_settings
Expand Down
2 changes: 2 additions & 0 deletions fastflix/encoders/nvencc_hevc/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ def set_mode(self, x):
self.main.build_commands()

def new_source(self):
if not self.app.fastflix.current_video:
return
super().new_source()
if self.app.fastflix.current_video.hdr10_plus:
self.extract_button.show()
Expand Down
1 change: 1 addition & 0 deletions fastflix/widgets/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, app: FastFlixApp, **kwargs):
self.setMinimumSize(QtCore.QSize(1280, 650))
self.icon = QtGui.QIcon(main_icon)
self.setWindowIcon(self.icon)
self.main.set_profile()

def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
if self.pb:
Expand Down
42 changes: 23 additions & 19 deletions fastflix/widgets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ def __init__(self, parent, app: FastFlixApp):

self.disable_all()
self.setLayout(self.grid)
self.set_profile()
self.show()
self.initialized = True
self.loading_video = False
self.last_page_update = time.time()

def init_top_bar(self):
Expand Down Expand Up @@ -412,23 +412,25 @@ def set_profile(self):
return
self.app.fastflix.config.selected_profile = self.widgets.profile_box.currentText()
self.app.fastflix.config.save()
self.widgets.convert_to.setCurrentText(f" {self.app.fastflix.config.opt('encoder')}")
self.widgets.convert_to.setCurrentText(self.app.fastflix.config.opt("encoder"))
if self.app.fastflix.config.opt("auto_crop") and not self.build_crop():
self.get_auto_crop()
self.loading_video = True
self.widgets.scale.keep_aspect.setChecked(self.app.fastflix.config.opt("keep_aspect_ratio"))
self.widgets.rotate.setCurrentIndex(self.app.fastflix.config.opt("rotate") or 0 // 90)

v_flip = self.app.fastflix.config.opt("vertical_flip")
h_flip = self.app.fastflix.config.opt("horizontal_flip")

self.widgets.flip.setCurrentIndex(self.flip_to_int(v_flip, h_flip))
self.video_options.change_conversion(self.app.fastflix.config.opt("encoder"))
self.video_options.update_profile()
if self.app.fastflix.current_video:
self.video_options.new_source()
# Hack to prevent a lot of thumbnail generation
self.loading_video = False
try:
self.widgets.scale.keep_aspect.setChecked(self.app.fastflix.config.opt("keep_aspect_ratio"))
self.widgets.rotate.setCurrentIndex(self.app.fastflix.config.opt("rotate") or 0 // 90)

v_flip = self.app.fastflix.config.opt("vertical_flip")
h_flip = self.app.fastflix.config.opt("horizontal_flip")

self.widgets.flip.setCurrentIndex(self.flip_to_int(v_flip, h_flip))
self.video_options.change_conversion(self.app.fastflix.config.opt("encoder"))
self.video_options.update_profile()
if self.app.fastflix.current_video:
self.video_options.new_source()
finally:
# Hack to prevent a lot of thumbnail generation
self.loading_video = False
self.page_update()

def save_profile(self):
Expand Down Expand Up @@ -483,7 +485,7 @@ def init_rotate(self):

def change_output_types(self):
self.widgets.convert_to.clear()
self.widgets.convert_to.addItems([f" {x}" for x in self.app.fastflix.encoders.keys()])
self.widgets.convert_to.addItems(self.app.fastflix.encoders.keys())
for i, plugin in enumerate(self.app.fastflix.encoders.values()):
if getattr(plugin, "icon", False):
self.widgets.convert_to.setItemIcon(i, QtGui.QIcon(plugin.icon))
Expand All @@ -507,9 +509,11 @@ def init_encoder_drop_down(self):
return layout

def change_encoder(self):
if not self.initialized or not self.app.fastflix.current_video or not self.convert_to:
if not self.initialized or not self.convert_to:
return
self.video_options.change_conversion(self.convert_to)
if not self.app.fastflix.current_video:
return
if not self.output_video_path_widget.text().endswith(self.current_encoder.video_extension):
# Make sure it's using the right file extension
self.output_video_path_widget.setText(self.generate_output_filename)
Expand Down Expand Up @@ -977,7 +981,7 @@ def keep_aspect_update(self) -> None:

def disable_all(self):
for name, widget in self.widgets.items():
if name in ("preview", "convert_button", "pause_resume"):
if name in ("preview", "convert_button", "pause_resume", "convert_to", "profile_box"):
continue
if isinstance(widget, dict):
for sub_widget in widget.values():
Expand All @@ -992,7 +996,7 @@ def disable_all(self):

def enable_all(self):
for name, widget in self.widgets.items():
if name in ("preview", "convert_button", "pause_resume"):
if name in ("preview", "convert_button", "pause_resume", "convert_to", "profile_box"):
continue
if isinstance(widget, dict):
for sub_widget in widget.values():
Expand Down
2 changes: 2 additions & 0 deletions fastflix/widgets/video_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def get_settings(self):
self.main.container.profile.update_settings()

def new_source(self):
if not self.app.fastflix.current_video:
return
if getattr(self.main.current_encoder, "enable_audio", False):
self.audio.new_source(self.audio_formats)
if getattr(self.main.current_encoder, "enable_subtitles", False):
Expand Down

0 comments on commit d59111e

Please sign in to comment.