Skip to content

Commit 99bafca

Browse files
committed
* Adding audio normalization (thanks to Xoanon88)
* Adding ability to add subtitle or audio track
1 parent 34bb96b commit 99bafca

File tree

15 files changed

+252
-2
lines changed

15 files changed

+252
-2
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## Version 5.12.0
44

55
* Adding automatic downloads for rigaya encoders on Windows
6+
* Adding audio normalization (thanks to Xoanon88)
7+
* Adding ability to add subtitle or audio track
68
* Fixing custom_crf not being found (thanks to Norbert)
79

810
## Version 5.11.0

fastflix/application.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def init_encoders(app: FastFlixApp, **_):
8383
from fastflix.encoders.vaapi_hevc import main as vaapi_hevc_plugin
8484
from fastflix.encoders.vaapi_vp9 import main as vaapi_vp9_plugin
8585
from fastflix.encoders.vaapi_mpeg2 import main as vaapi_mpeg2_plugin
86+
from fastflix.encoders.modify import main as modify_plugin
8687

8788
encoders = [
8889
hevc_plugin,
@@ -103,6 +104,7 @@ def init_encoders(app: FastFlixApp, **_):
103104
vaapi_vp9_plugin,
104105
vaapi_mpeg2_plugin,
105106
copy_plugin,
107+
modify_plugin,
106108
]
107109

108110
if DEVMODE:

fastflix/data/icons/loading.gif

85.3 KB
Loading

fastflix/data/languages.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10787,3 +10787,13 @@ Enable either auto split or parallel encoding mode.:
1078710787
ukr: Увімкніть режим автоматичного розділення або паралельного кодування.
1078810788
kor: 자동 분할 또는 병렬 인코딩 모드를 활성화합니다.
1078910789
ron: Activați divizarea automată sau modul de codare paralelă.
10790+
Update Rigaya's Encoders:
10791+
eng: Update Rigaya's Encoders
10792+
Detect GPUs:
10793+
eng: Detect GPUs
10794+
Run Audio Normalize:
10795+
eng: Run Audio Normalize
10796+
Add Audio Track:
10797+
eng: Add Audio Track
10798+
Add Text Based Subtitle Track:
10799+
eng: Add Text Based Subtitle Track

fastflix/encoders/copy/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
enable_subtitles = True
1616
enable_audio = True
1717
enable_attachments = True
18-
18+
enable_advanced = False
1919

2020
from fastflix.encoders.copy.command_builder import build
2121
from fastflix.encoders.copy.settings_panel import Copy as settings_panel

fastflix/encoders/modify/__init__.py

Whitespace-only changes.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# -*- coding: utf-8 -*-
2+
import re
3+
from pprint import pprint
4+
from fastflix.encoders.common.helpers import Command, generate_all
5+
from fastflix.models.fastflix import FastFlix
6+
from fastflix.shared import clean_file_string
7+
8+
9+
def build(fastflix: FastFlix):
10+
beginning, ending, output_fps = generate_all(fastflix, "copy", disable_filters=True, audio=False, subs=False)
11+
start_time = fastflix.current_video.video_settings.start_time
12+
fast_seek = fastflix.current_video.video_settings.fast_seek
13+
end_time = fastflix.current_video.video_settings.end_time
14+
video_title = fastflix.current_video.video_settings.video_title
15+
video_track_title = fastflix.current_video.video_settings.video_track_title
16+
ffmpeg = fastflix.config.ffmpeg
17+
source = fastflix.current_video.source
18+
19+
time_settings = f'{f"-ss {start_time}" if start_time else ""} {f"-to {end_time}" if end_time else ""} '
20+
time_one = time_settings if fast_seek else ""
21+
time_two = time_settings if not fast_seek else ""
22+
23+
if video_title:
24+
video_title = video_title.replace('"', '\\"')
25+
title = f'-metadata title="{video_title}"' if video_title else ""
26+
source = clean_file_string(source)
27+
ffmpeg = clean_file_string(ffmpeg)
28+
if video_track_title:
29+
video_track_title = video_track_title.replace('"', '\\"')
30+
track_title = f'-metadata:s:v:0 title="{video_track_title}"'
31+
32+
beginning = " ".join(
33+
[
34+
f'"{ffmpeg}"',
35+
"-y",
36+
time_one,
37+
f'-i "{source}"',
38+
time_two,
39+
title,
40+
f"{track_title if video_track_title else ''}",
41+
" ", # Leave space after commands
42+
]
43+
)
44+
45+
audio = fastflix.current_video.video_settings.video_encoder_settings.add_audio_track
46+
subs = fastflix.current_video.video_settings.video_encoder_settings.add_subtitle_track
47+
48+
if audio and subs:
49+
audio_path_clean = clean_file_string(audio)
50+
subs_path_clean = clean_file_string(subs)
51+
return [
52+
Command(
53+
command=f'{beginning} -i "{audio_path_clean}" -i "{subs_path_clean}" -map 0 -map 1:a -map 2:s -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
54+
name="Add audio and subtitle track",
55+
exe="ffmpeg",
56+
)
57+
]
58+
59+
if audio:
60+
audio_path_clean = clean_file_string(audio)
61+
return [
62+
Command(
63+
command=f'{beginning} -i "{audio_path_clean}" -map 0 -map 1:a -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
64+
name="Add audio track",
65+
exe="ffmpeg",
66+
)
67+
]
68+
69+
if subs:
70+
subs_path_clean = clean_file_string(subs)
71+
return [
72+
Command(
73+
command=f'{beginning} -i "{subs_path_clean}" -map 0 -map 1:s -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
74+
name="Add subtitle track",
75+
exe="ffmpeg",
76+
)
77+
]

fastflix/encoders/modify/main.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
__author__ = "Chris Griffith"
4+
import importlib.resources
5+
6+
name = "Modify"
7+
8+
video_extensions = [".mkv", ".mp4", ".ts", ".mov", ".webm", ".avi", ".mts", ".m2ts", ".m4v", ".gif", ".avif", ".webp"]
9+
video_dimension_divisor = 1
10+
11+
ref = importlib.resources.files("fastflix") / "data/icons/black/onyx-advanced.svg"
12+
with importlib.resources.as_file(ref) as icon_file:
13+
icon = str(icon_file.resolve())
14+
15+
enable_subtitles = False
16+
enable_audio = False
17+
enable_attachments = False
18+
enable_advanced = False
19+
20+
from fastflix.encoders.modify.command_builder import build
21+
from fastflix.encoders.modify.settings_panel import Modify as settings_panel
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# -*- coding: utf-8 -*-
2+
import logging
3+
import os
4+
from pathlib import Path
5+
6+
from PySide6 import QtWidgets, QtGui, QtCore
7+
8+
from fastflix.encoders.common.setting_panel import SettingPanel
9+
from fastflix.language import t
10+
from fastflix.models.encode import ModifySettings
11+
from fastflix.models.fastflix_app import FastFlixApp
12+
from fastflix.shared import message
13+
from fastflix.widgets.background_tasks import AudioNoramlize
14+
from fastflix.resources import loading_movie, get_icon
15+
16+
logger = logging.getLogger("fastflix")
17+
18+
19+
class Modify(SettingPanel):
20+
profile_name = "modify_settings"
21+
signal = QtCore.Signal(str)
22+
23+
def __init__(self, parent, main, app: FastFlixApp):
24+
super().__init__(parent, main, app)
25+
self.main = main
26+
self.app = app
27+
self.signal.connect(self.audio_norm_done)
28+
29+
self.extract_label = QtWidgets.QLabel(self)
30+
self.extract_label.hide()
31+
self.movie = QtGui.QMovie(loading_movie)
32+
self.movie.setScaledSize(QtCore.QSize(25, 25))
33+
self.extract_label.setMovie(self.movie)
34+
35+
grid = QtWidgets.QGridLayout()
36+
37+
grid.addWidget(QtWidgets.QLabel(""), 1, 0)
38+
self.audio_normalize = QtWidgets.QPushButton(t("Run Audio Normalize"))
39+
self.audio_normalize.clicked.connect(self.select_run_audio_normalize)
40+
grid.addWidget(self.audio_normalize, 2, 0, 1, 1)
41+
grid.addWidget(self.extract_label, 2, 2, 1, 1)
42+
43+
add_audio_track = QtWidgets.QPushButton(t("Add Audio Track"))
44+
add_audio_track.clicked.connect(self.select_audio_file)
45+
self.add_audio_track_file_path = QtWidgets.QLineEdit()
46+
grid.addWidget(add_audio_track, 3, 0, 1, 1)
47+
grid.addWidget(self.add_audio_track_file_path, 3, 2, 1, 1)
48+
49+
add_sub_track = QtWidgets.QPushButton(t("Add Text Based Subtitle Track"))
50+
add_sub_track.clicked.connect(self.select_subtitle_file)
51+
self.add_sub_track_file_path = QtWidgets.QLineEdit()
52+
grid.addWidget(add_sub_track, 4, 0, 1, 1)
53+
grid.addWidget(self.add_sub_track_file_path, 4, 2, 1, 1)
54+
55+
grid.addWidget(QtWidgets.QWidget(), 6, 0, 6, 1)
56+
grid.addLayout(self._add_custom(disable_both_passes=True), 11, 0, 1, 6)
57+
self.setLayout(grid)
58+
self.hide()
59+
60+
def update_video_encoder_settings(self):
61+
self.app.fastflix.current_video.video_settings.video_encoder_settings = ModifySettings(
62+
audio_normalize=self.audio_normalize.isChecked(),
63+
add_audio_track=self.add_audio_track_file_path.text() or None,
64+
add_subtitle_track=self.add_sub_track_file_path.text() or None,
65+
)
66+
self.app.fastflix.current_video.video_settings.video_encoder_settings.extra = self.ffmpeg_extras
67+
self.app.fastflix.current_video.video_settings.video_encoder_settings.extra_both_passes = False
68+
69+
def select_audio_file(self):
70+
file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
71+
self, t("Select Audio Track"), "", t("Audio Files (*.mp3 *.aac *.wav *.flac);;All Files (*)")
72+
)
73+
if file_path:
74+
logger.info(f"Selected audio track: {file_path}")
75+
self.add_audio_track_file_path.setText(file_path)
76+
self.main.build_commands()
77+
78+
def select_subtitle_file(self):
79+
file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
80+
self, t("Select Subtitle Track"), "", t("Subtitle Files (*.srt *.ass *.vtt *.ssa);;All Files (*)")
81+
)
82+
if file_path:
83+
logger.info(f"Selected subtitle track: {file_path}")
84+
self.add_sub_track_file_path.setText(file_path)
85+
self.main.build_commands()
86+
87+
def select_run_audio_normalize(self):
88+
self.norm_thread = AudioNoramlize(self.app, self.main, self.signal)
89+
self.norm_thread.start()
90+
self.movie.start()
91+
self.extract_label.show()
92+
self.audio_normalize.setDisabled(True)
93+
94+
def audio_norm_done(self, status):
95+
self.movie.stop()
96+
self.extract_label.hide()
97+
self.audio_normalize.setDisabled(False)
98+
message(f"Audio normalization done: {status}")

fastflix/models/encode.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,13 @@ class CopySettings(EncoderSettings):
617617
name: str = "Copy"
618618

619619

620+
class ModifySettings(EncoderSettings):
621+
name: str = "Modify"
622+
audio_normalize: bool = False
623+
add_audio_track: str | None = None
624+
add_subtitle_track: str | None = None
625+
626+
620627
class VAAPIH264Settings(EncoderSettings):
621628
name: str = "VAAPI H264" # must be same as encoder name in main
622629

@@ -685,6 +692,7 @@ class VAAPIMPEG2Settings(EncoderSettings):
685692
"gif": GIFSettings,
686693
"webp": WebPSettings,
687694
"copy_settings": CopySettings,
695+
"modify_settings": ModifySettings,
688696
"ffmpeg_hevc_nvenc": FFmpegNVENCSettings,
689697
"qsvencc_hevc": QSVEncCSettings,
690698
"qsvencc_av1": QSVEncCAV1Settings,

0 commit comments

Comments
 (0)