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
8 changes: 8 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## Version 5.12.4

* Fixing #675 "Default Source Folder" not used when adding Complete Folders (thanks to Krawk)
* Fixing #678 Cannot copy the cover (thanks to danielly2020)
* Fixing #679 Subtitle extraction (thanks to danielly2020)
* Fixing adding subtitle track would fail if video has a title (thanks to The_Donn)


## Version 5.12.3

* Fixing #673 changing subtitle langauge in the UI did not take effect in the command (thanks to danielly2020)
Expand Down
171 changes: 171 additions & 0 deletions fastflix/data/languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11101,3 +11101,174 @@ Could not extract subtitle track:
ukr: Не вдалося витягти доріжку субтитрів
kor: 자막 트랙을 추출할 수 없습니다.
ron: Nu s-a putut extrage pista de subtitrare
Select Subtitle Track:
eng: Select Subtitle Track
deu: Untertitelspur auswählen
fra: Sélectionner la piste des sous-titres
ita: Selezionare la traccia dei sottotitoli
spa: Seleccionar pista de subtítulos
jpn: 字幕トラックを選択
rus: Выберите дорожку субтитров
por: Selecionar a faixa de legendas
swe: Välj undertextspår
pol: Wybór ścieżki napisów
chs: 选择字幕轨道
ukr: Виберіть доріжку субтитрів
kor: 자막 트랙 선택
ron: Selectați pista de subtitrare
Subtitle Track:
eng: Subtitle Track
deu: Untertitel Spur
fra: Piste de sous-titres
ita: Traccia dei sottotitoli
spa: Pista de subtítulos
jpn: 字幕トラック
rus: Дорожка субтитров
por: Faixa de legendas
swe: Spår för undertexter
pol: Ścieżka napisów
chs: 字幕轨道
ukr: Доріжка з субтитрами
kor: 자막 트랙
ron: Track subtitrare
Subtitle Files (*.srt *.ass *.vtt *.ssa);;All Files (*):
eng: Subtitle Files (*.srt *.ass *.vtt *.ssa);;All Files (*)
deu: Untertiteldateien (*.srt *.ass *.vtt *.ssa);;Alle Dateien (*)
fra: Fichiers de sous-titres (*.srt *.ass *.vtt *.ssa);;Tous les fichiers (*)
ita: File dei sottotitoli (*.srt *.ass *.vtt *.ssa);;Tutti i file (*)
spa: Archivos de subtítulos (*.srt *.ass *.vtt *.ssa);;Todos los archivos (*)
jpn: 字幕ファイル (*.srt *.ass *.vtt *.ssa);;すべてのファイル (*)
rus: Файлы субтитров (*.srt *.ass *.vtt *.ssa);;Все файлы (*)
por: Ficheiros de legendas (*.srt *.ass *.vtt *.ssa);;Todos os ficheiros (*)
swe: Undertextfiler (*.srt *.ass *.vtt *.ssa);;Alla filer (*)
pol: Pliki napisów (*.srt *.ass *.vtt *.ssa);;Wszystkie pliki (*)
chs: 字幕文件 (*.srt *.ass *.vtt *.ssa);;All Files (*)
ukr: Файли субтитрів (*.srt *.ass *.vtt *.ssa);;Всі файли (*)
kor: 자막 파일 (*.srt *.ass *.vtt *.ssa);;모든 파일 (*)
ron: Fișiere subtitrare (*.srt *.ass *.vtt *.ssa);;Toate fișierele (*)
Select Audio Track:
eng: Select Audio Track
deu: Audiospur auswählen
fra: Sélectionner la piste audio
ita: Selezionare la traccia audio
spa: Seleccionar pista de audio
jpn: オーディオトラックを選択
rus: Выберите аудиодорожку
por: Selecionar faixa de áudio
swe: Välj ljudspår
pol: Wybierz ścieżkę audio
chs: 选择音轨
ukr: Виберіть аудіодоріжку
kor: 오디오 트랙 선택
ron: Selectați pista audio
Audio Files (*.mp3 *.aac *.wav *.flac);;All Files (*):
eng: Audio Files (*.mp3 *.aac *.wav *.flac);;All Files (*)
deu: Audio-Dateien (*.mp3 *.aac *.wav *.flac);;Alle Dateien (*)
fra: Fichiers audio (*.mp3 *.aac *.wav *.flac);;Tous les fichiers (*)
ita: File audio (*.mp3 *.aac *.wav *.flac);;Tutti i file (*)
spa: Archivos de audio (*.mp3 *.aac *.wav *.flac);;Todos los archivos (*)
jpn: オーディオファイル (*.mp3 *.aac *.wav *.flac);;すべてのファイル (*)
rus: Аудиофайлы (*.mp3 *.aac *.wav *.flac);;Все файлы (*)
por: Ficheiros de áudio (*.mp3 *.aac *.wav *.flac);;Todos os ficheiros (*)
swe: Ljudfiler (*.mp3 *.aac *.wav *.flac);;Alla filer (*)
pol: Pliki audio (*.mp3 *.aac *.wav *.flac);;Wszystkie pliki (*)
chs: 音频文件 (*.mp3 *.aac *.wav *.flac);;All Files (*)
ukr: Аудіофайли (*.mp3 *.aac *.wav *.flac);;Всі файли (*)
kor: 오디오 파일(*.mp3 *.aac *.wav *.flac);;모든 파일(*)
ron: Fișiere audio (*.mp3 *.aac *.wav *.flac);;Toate fișierele (*)
is not in supported format (SRT, ASS, SSA, PGS), skipping extraction:
eng: is not in supported format (SRT, ASS, SSA, PGS), skipping extraction
deu: nicht im unterstützten Format ist (SRT, ASS, SSA, PGS), wird die
Extraktion übersprungen
fra: n'est pas dans un format supporté (SRT, ASS, SSA, PGS), l'extraction est
ignorée.
ita: non è in un formato supportato (SRT, ASS, SSA, PGS), si salta
l'estrazione.
spa: no está en un formato compatible (SRT, ASS, SSA, PGS), se omite la
extracción
jpn: がサポートされているフォーマット(SRT、ASS、SSA、PGS)でない場合、抽出をスキップする。
rus: не в поддерживаемом формате (SRT, ASS, SSA, PGS), пропуск извлечения
por: não está num formato suportado (SRT, ASS, SSA, PGS), saltando a extração
swe: inte är i ett format som stöds (SRT, ASS, SSA, PGS), hoppa över
extraktionen
pol: nie jest w obsługiwanym formacie (SRT, ASS, SSA, PGS), pomijanie
ekstrakcji
chs: 不支持的格式(SRT、ASS、SSA、PGS),跳过提取
ukr: не у підтримуваному форматі (SRT, ASS, SSA, PGS), пропускається вилучення
kor: 가 지원되지 않는 형식(SRT, ASS, SSA, PGS)이므로 추출 건너뛰기
ron: nu este în format acceptat (SRT, ASS, SSA, PGS), extragerea este ignorată
Could not determine subtitle format for track:
eng: Could not determine subtitle format for track
deu: Das Untertitelformat für die Spur konnte nicht ermittelt werden
fra: Impossible de déterminer le format des sous-titres pour la piste
ita: Impossibile determinare il formato dei sottotitoli per la traccia
spa: No se ha podido determinar el formato de subtítulos de la pista
jpn: トラックの字幕フォーマットを決定できませんでした
rus: Не удалось определить формат субтитров для дорожки
por: Não foi possível determinar o formato das legendas para a faixa
swe: Kunde inte fastställa undertextformat för spår
pol: Nie można określić formatu napisów dla ścieżki
chs: 无法确定轨道的字幕格式
ukr: Не вдалося визначити формат субтитрів для доріжки
kor: 트랙의 자막 형식을 결정할 수 없습니다.
ron: Nu s-a putut determina formatul subtitrărilor pentru pistă
skipping extraction:
eng: skipping extraction
deu: Überspringen der Extraktion
fra: Sauter l'extraction
ita: saltare l'estrazione
spa: omitir la extracción
jpn: スキップ抽出
rus: пропуск добычи
por: saltar a extração
swe: hoppa över extraktion
pol: pomijanie ekstrakcji
chs: 跳转提取
ukr: пропуск видобутку
kor: 추출 건너뛰기
ron: omiterea extracției
Could not probe subtitle track:
eng: Could not probe subtitle track
deu: Untertitelspur konnte nicht geprüft werden
fra: Impossible de sonder la piste de sous-titres
ita: Impossibile sondare la traccia dei sottotitoli
spa: No se ha podido sondear la pista de subtítulos
jpn: 字幕トラックをプローブできませんでした
rus: Не удалось обнаружить дорожку субтитров
por: Não foi possível sondar a faixa de legendas
swe: Kunde inte undersöka undertextspåret
pol: Nie można sondować ścieżki napisów
chs: 无法探测字幕轨道
ukr: Не вдалося дослідити доріжку субтитрів
kor: 자막 트랙을 조사할 수 없습니다.
ron: Nu s-a putut sonda pista de subtitrare
Error checking subtitle format for track:
eng: Error checking subtitle format for track
deu: Fehler bei der Überprüfung des Untertitelformats für die Spur
fra: Erreur de vérification du format des sous-titres pour la piste
ita: Errore nella verifica del formato dei sottotitoli per la traccia
spa: Error al comprobar el formato de subtítulos de la pista
jpn: トラックの字幕フォーマットのチェックエラー
rus: Ошибка при проверке формата субтитров для дорожки
por: Erro ao verificar o formato da legenda para a faixa
swe: Fel vid kontroll av undertextformat för spår
pol: Błąd sprawdzania formatu napisów dla ścieżki
chs: 错误检查轨道的字幕格式
ukr: Помилка перевірки формату субтитрів для доріжки
kor: 트랙의 자막 형식 확인 중 오류 발생
ron: Eroare la verificarea formatului subtitrărilor pentru pistă
'Note: start and end time will be ignored':
eng: 'Note: start and end time will be ignored'
deu: 'Hinweis: Start- und Endzeit werden ignoriert.'
fra: 'Note : les heures de début et de fin seront ignorées.'
ita: "Nota: l'ora di inizio e di fine viene ignorata."
spa: 'Nota: se ignorarán las horas de inicio y fin.'
jpn: 注:開始時間と終了時間は無視されます
rus: 'Примечание: время начала и окончания будет игнорироваться'
por: 'Nota: as horas de início e de fim serão ignoradas'
swe: 'Obs: start- och sluttid kommer att ignoreras'
pol: 'Uwaga: czas rozpoczęcia i zakończenia będzie ignorowany.'
chs: 注意:开始和结束时间将被忽略
ukr: 'Примітка: час початку та закінчення ігнорується'
kor: '참고: 시작 및 종료 시간은 무시됩니다.'
ron: 'Notă: ora de început și de sfârșit vor fi ignorate'
17 changes: 3 additions & 14 deletions fastflix/encoders/modify/command_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@

def build(fastflix: FastFlix):
beginning, ending, output_fps = generate_all(fastflix, "copy", disable_filters=True, audio=False, subs=False)
start_time = fastflix.current_video.video_settings.start_time
fast_seek = fastflix.current_video.video_settings.fast_seek
end_time = fastflix.current_video.video_settings.end_time
video_title = fastflix.current_video.video_settings.video_title
video_track_title = fastflix.current_video.video_settings.video_track_title
ffmpeg = fastflix.config.ffmpeg
source = fastflix.current_video.source

time_settings = f"{f'-ss {start_time}' if start_time else ''} {f'-to {end_time}' if end_time else ''} "
time_one = time_settings if fast_seek else ""
time_two = time_settings if not fast_seek else ""

if video_title:
video_title = video_title.replace('"', '\\"')
title = f'-metadata title="{video_title}"' if video_title else ""
Expand All @@ -31,11 +24,7 @@ def build(fastflix: FastFlix):
[
f'"{ffmpeg}"',
"-y",
time_one,
f'-i "{source}"',
time_two,
title,
f"{track_title if video_track_title else ''}",
" ", # Leave space after commands
]
)
Expand All @@ -48,7 +37,7 @@ def build(fastflix: FastFlix):
subs_path_clean = clean_file_string(subs)
return [
Command(
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}',
command=f'{beginning} -i "{audio_path_clean}" -i "{subs_path_clean}" -map 0 -map 1:a -map 2:s {title} {track_title if video_track_title else ""} -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
name="Add audio and subtitle track",
exe="ffmpeg",
)
Expand All @@ -58,7 +47,7 @@ def build(fastflix: FastFlix):
audio_path_clean = clean_file_string(audio)
return [
Command(
command=f'{beginning} -i "{audio_path_clean}" -map 0 -map 1:a -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
command=f'{beginning} -i "{audio_path_clean}" -map 0 -map 1:a {title} {track_title if video_track_title else ""} -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
name="Add audio track",
exe="ffmpeg",
)
Expand All @@ -68,7 +57,7 @@ def build(fastflix: FastFlix):
subs_path_clean = clean_file_string(subs)
return [
Command(
command=f'{beginning} -i "{subs_path_clean}" -map 0 -map 1:s -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
command=f'{beginning} -i "{subs_path_clean}" -map 0 -map 1:s {title} {track_title if video_track_title else ""} -c copy {fastflix.current_video.video_settings.video_encoder_settings.extra} {ending}',
name="Add subtitle track",
exe="ffmpeg",
)
Expand Down
2 changes: 2 additions & 0 deletions fastflix/encoders/modify/settings_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def __init__(self, parent, main, app: FastFlixApp):
grid.addWidget(add_sub_track, 4, 0, 1, 1)
grid.addWidget(self.add_sub_track_file_path, 4, 1, 1, 2)

grid.addWidget(QtWidgets.QLabel(t("Note: start and end time will be ignored")), 5, 0)

grid.addWidget(QtWidgets.QWidget(), 6, 0, 6, 1)
grid.addLayout(self._add_custom(disable_both_passes=True), 11, 0, 1, 6)
self.setLayout(grid)
Expand Down
2 changes: 1 addition & 1 deletion fastflix/ff_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def update_conversion_command(vid, old_path: str, new_path: str):
if not Path(track["file_path"]).exists():
logger.exception("Could not save cover to queue recovery location, removing cover")
continue
new_file = queue_covers / f"{uuid.uuid4().hex}_{track['file_path'].name}"
new_file = queue_covers / f"{uuid.uuid4().hex}_{Path(track['file_path']).name}"
try:
shutil.copy(track["file_path"], new_file)
except OSError:
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__ = "5.12.3"
__version__ = "5.12.4"
__author__ = "Chris Griffith"
84 changes: 79 additions & 5 deletions fastflix/widgets/background_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,38 @@ def __init__(self, app: FastFlixApp, main, index, signal, language):
self.language = language

def run(self):
subtitle_format = self._get_subtitle_format()
if subtitle_format is None:
self.main.thread_logging_signal.emit(
f"WARNING:{t('Could not determine subtitle format for track')} {self.index}, {t('skipping extraction')}"
)
self.signal.emit()
return

if subtitle_format == "srt":
extension = "srt"
output_args = ["-c", "srt", "-f", "srt"]
elif subtitle_format == "ass":
extension = "ass"
output_args = ["-c", "copy"]
elif subtitle_format == "ssa":
extension = "ssa"
output_args = ["-c", "copy"]
elif subtitle_format == "pgs":
extension = "sup"
output_args = ["-c", "copy"]
else:
self.main.thread_logging_signal.emit(
f"WARNING:{t('Subtitle Track')} {self.index} {t('is not in supported format (SRT, ASS, SSA, PGS), skipping extraction')}: {subtitle_format}"
)
self.signal.emit()
return

# filename = str(
# Path(self.main.output_video).parent / f"{self.main.output_video}.{self.index}.{self.language}.srt"
# ).replace("\\", "/")
filename = str(
Path(self.main.output_video).parent / f"{self.main.output_video}.{self.index}.{self.language}.srt"
Path(self.main.output_video).parent / f"{self.main.output_video}.{self.index}.{self.language}.{extension}"
).replace("\\", "/")
self.main.thread_logging_signal.emit(f"INFO:{t('Extracting subtitles to')} {filename}")

Expand All @@ -69,10 +99,7 @@ def run(self):
self.main.input_video,
"-map",
f"0:s:{self.index}",
"-c",
"srt",
"-f",
"srt",
*output_args,
filename,
],
stdout=PIPE,
Expand All @@ -90,6 +117,53 @@ def run(self):
self.main.thread_logging_signal.emit(f"INFO:{t('Extracted subtitles successfully')}")
self.signal.emit()

def _get_subtitle_format(self):
try:
result = run(
[
self.app.fastflix.config.ffprobe,
"-v",
"error",
"-select_streams",
f"s:{self.index}",
"-show_entries",
"stream=codec_name",
"-of",
"default=noprint_wrappers=1:nokey=1",
self.main.input_video,
],
stdout=PIPE,
stderr=STDOUT,
text=True,
)

if result.returncode != 0:
self.main.thread_logging_signal.emit(
f"WARNING:{t('Could not probe subtitle track')} {self.index}: {result.stdout}"
)
return None

codec_name = result.stdout.strip().lower()
if codec_name in ["subrip", "xsub", "webvtt", "mov_text"]:
return "srt"
elif codec_name == "ass":
return "ass"
elif codec_name == "ssa":
return "ssa"
elif codec_name == "hdmv_pgs_subtitle":
return "pgs"
else:
self.main.thread_logging_signal.emit(
f"WARNING:{t('Subtitle Track')} {self.index} {t('is not in supported format (SRT, ASS, SSA, PGS), skipping extraction')}: {codec_name}"
)
return None

except Exception as err:
self.main.thread_logging_signal.emit(
f"WARNING:{t('Error checking subtitle format for track')} {self.index} - {err}"
)
return None


class AudioNoramlize(QtCore.QThread):
def __init__(self, app: FastFlixApp, main, audio_type, signal):
Expand Down
1 change: 1 addition & 0 deletions fastflix/widgets/panels/audio_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def dup_me(self):
def del_me(self):
self.parent.remove_track(self)
del self.app.fastflix.current_video.audio_tracks[self.index]
self.parent.reorder(update=True)

def set_outdex(self, outdex):
self.app.fastflix.current_video.audio_tracks[self.index].outdex = outdex
Expand Down
Loading