summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2023-02-23 18:31:29 -0500
committermorpheus65535 <[email protected]>2023-02-23 18:32:54 -0500
commit5dc4e782ae31ed36aaf4d27d9a46af3e494c7491 (patch)
tree1f5364692b95f0e159a594552070fbe3eb1840dc
parent5b283098f9ec0804706225cc0b1266515e034be7 (diff)
downloadbazarr-1.1.5-beta.23.tar.gz
bazarr-1.1.5-beta.23.zip
Added option to deeply analyze audio tracks from media files or not to determine languages. Default is to use Sonarr/Radarr provided languages instead. Should prevent API limit ban for cloud user.v1.1.5-beta.23
-rw-r--r--bazarr/app/config.py18
-rw-r--r--bazarr/radarr/sync/parser.py33
-rw-r--r--bazarr/sonarr/sync/parser.py43
-rw-r--r--frontend/src/pages/Series/index.tsx8
-rw-r--r--frontend/src/pages/Settings/Languages/index.tsx35
5 files changed, 112 insertions, 25 deletions
diff --git a/bazarr/app/config.py b/bazarr/app/config.py
index ba4bc8a26..37da0f744 100644
--- a/bazarr/app/config.py
+++ b/bazarr/app/config.py
@@ -81,7 +81,8 @@ defaults = {
'hi_extension': 'hi',
'embedded_subtitles_parser': 'ffprobe',
'default_und_audio_lang': '',
- 'default_und_embedded_subtitles_lang': ''
+ 'default_und_embedded_subtitles_lang': '',
+ 'parse_embedded_audio_track': 'False'
},
'auth': {
'type': 'None',
@@ -385,6 +386,7 @@ def save_settings(settings_items):
use_embedded_subs_changed = False
undefined_audio_track_default_changed = False
undefined_subtitles_track_default_changed = False
+ audio_tracks_parsing_changed = False
# Subzero Mods
update_subzero = False
@@ -423,6 +425,9 @@ def save_settings(settings_items):
if key == 'settings-general-default_und_audio_lang':
undefined_audio_track_default_changed = True
+ if key == 'settings-general-parse_embedded_audio_track':
+ audio_tracks_parsing_changed = True
+
if key == 'settings-general-default_und_embedded_subtitles_lang':
undefined_subtitles_track_default_changed = True
@@ -565,6 +570,17 @@ def save_settings(settings_items):
if settings.general.getboolean('use_radarr'):
scheduler.add_job(movies_full_scan_subtitles, kwargs={'use_cache': True})
+ if audio_tracks_parsing_changed:
+ from .scheduler import scheduler
+ if settings.general.getboolean('use_sonarr'):
+ from sonarr.sync.episodes import sync_episodes
+ from sonarr.sync.series import update_series
+ scheduler.add_job(update_series, kwargs={'send_event': True}, max_instances=1)
+ scheduler.add_job(sync_episodes, kwargs={'send_event': True}, max_instances=1)
+ if settings.general.getboolean('use_radarr'):
+ from radarr.sync.movies import update_movies
+ scheduler.add_job(update_movies, kwargs={'send_event': True}, max_instances=1)
+
if update_subzero:
settings.set('general', 'subzero_mods', ','.join(subzero_mods))
diff --git a/bazarr/radarr/sync/parser.py b/bazarr/radarr/sync/parser.py
index 7537bcec2..60b4c7024 100644
--- a/bazarr/radarr/sync/parser.py
+++ b/bazarr/radarr/sync/parser.py
@@ -2,6 +2,8 @@
import os
+from app.config import settings
+from languages.get_languages import language_from_alpha2
from radarr.info import get_radarr_info
from utilities.video_analyzer import embedded_audio_reader
from utilities.path_mappings import path_mappings
@@ -90,10 +92,31 @@ def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles)
videoCodec = None
audioCodec = None
- audio_language = embedded_audio_reader(path_mappings.path_replace_movie(movie['movieFile']['path']),
- file_size=movie['movieFile']['size'],
- movie_file_id=movie['movieFile']['id'],
- use_cache=True)
+ if settings.general.getboolean('parse_embedded_audio_track'):
+ audio_language = embedded_audio_reader(path_mappings.path_replace_movie(movie['movieFile']['path']),
+ file_size=movie['movieFile']['size'],
+ movie_file_id=movie['movieFile']['id'],
+ use_cache=True)
+ else:
+ audio_language = []
+ if get_radarr_info.is_legacy():
+ if 'mediaInfo' in movie['movieFile']:
+ if 'audioLanguages' in movie['movieFile']['mediaInfo']:
+ audio_languages_list = movie['movieFile']['mediaInfo']['audioLanguages'].split('/')
+ if len(audio_languages_list):
+ for audio_language_list in audio_languages_list:
+ audio_language.append(audio_language_list.strip())
+ if not audio_language:
+ audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles)
+ else:
+ if 'languages' in movie['movieFile'] and len(movie['movieFile']['languages']):
+ for item in movie['movieFile']['languages']:
+ if isinstance(item, dict):
+ if 'name' in item:
+ language = item['name']
+ if item['name'] == 'Portuguese (Brazil)':
+ language = language_from_alpha2('pb')
+ audio_language.append(language)
tags = [d['label'] for d in tags_dict if d['id'] in movie['tags']]
@@ -146,8 +169,8 @@ def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles)
def profile_id_to_language(id, profiles):
+ profiles_to_return = []
for profile in profiles:
- profiles_to_return = []
if id == profile[0]:
profiles_to_return.append(profile[1])
return profiles_to_return
diff --git a/bazarr/sonarr/sync/parser.py b/bazarr/sonarr/sync/parser.py
index 9fc3c4db2..341229d48 100644
--- a/bazarr/sonarr/sync/parser.py
+++ b/bazarr/sonarr/sync/parser.py
@@ -2,8 +2,11 @@
import os
+from app.config import settings
+from app.database import TableShows
from utilities.path_mappings import path_mappings
from utilities.video_analyzer import embedded_audio_reader
+from sonarr.info import get_sonarr_info
from .converter import SonarrFormatVideoCodec, SonarrFormatAudioCodec
@@ -28,6 +31,16 @@ def seriesParser(show, action, tags_dict, serie_default_profile, audio_profiles)
imdbId = show['imdbId'] if 'imdbId' in show else None
+ audio_language = []
+ if not settings.general.getboolean('parse_embedded_audio_track'):
+ if get_sonarr_info.is_legacy():
+ audio_language = profile_id_to_language(show['qualityProfileId'], audio_profiles)
+ else:
+ if 'languageProfileId' in show:
+ audio_language = profile_id_to_language(show['languageProfileId'], audio_profiles)
+ else:
+ audio_language = []
+
if action == 'update':
return {'title': show["title"],
'path': show["path"],
@@ -36,7 +49,7 @@ def seriesParser(show, action, tags_dict, serie_default_profile, audio_profiles)
'overview': overview,
'poster': poster,
'fanart': fanart,
- 'audio_language': str([]),
+ 'audio_language': str(audio_language),
'sortTitle': show['sortTitle'],
'year': str(show['year']),
'alternativeTitles': alternate_titles,
@@ -52,7 +65,7 @@ def seriesParser(show, action, tags_dict, serie_default_profile, audio_profiles)
'overview': overview,
'poster': poster,
'fanart': fanart,
- 'audio_language': str([]),
+ 'audio_language': str(audio_language),
'sortTitle': show['sortTitle'],
'year': str(show['year']),
'alternativeTitles': alternate_titles,
@@ -85,10 +98,28 @@ def episodeParser(episode):
else:
sceneName = None
- audio_language = embedded_audio_reader(path_mappings.path_replace(episode['episodeFile']['path']),
- file_size=episode['episodeFile']['size'],
- episode_file_id=episode['episodeFile']['id'],
- use_cache=True)
+ if settings.general.getboolean('parse_embedded_audio_track'):
+ audio_language = embedded_audio_reader(path_mappings.path_replace(episode['episodeFile']
+ ['path']),
+ file_size=episode['episodeFile']['size'],
+ episode_file_id=episode['episodeFile']['id'],
+ use_cache=True)
+ else:
+ audio_language = []
+ if 'language' in episode['episodeFile'] and len(episode['episodeFile']['language']):
+ item = episode['episodeFile']['language']
+ if isinstance(item, dict):
+ if 'name' in item:
+ audio_language.append(item['name'])
+ elif 'languages' in episode['episodeFile'] and len(episode['episodeFile']['languages']):
+ items = episode['episodeFile']['languages']
+ if isinstance(items, list):
+ for item in items:
+ if 'name' in item:
+ audio_language.append(item['name'])
+ else:
+ audio_language = TableShows.get(
+ TableShows.sonarrSeriesId == episode['seriesId']).audio_language
if 'mediaInfo' in episode['episodeFile']:
if 'videoCodec' in episode['episodeFile']['mediaInfo']:
diff --git a/frontend/src/pages/Series/index.tsx b/frontend/src/pages/Series/index.tsx
index da20c4459..6dfe07230 100644
--- a/frontend/src/pages/Series/index.tsx
+++ b/frontend/src/pages/Series/index.tsx
@@ -1,5 +1,6 @@
import { useSeriesModification, useSeriesPagination } from "@/apis/hooks";
import { Action } from "@/components";
+import { AudioList } from "@/components/bazarr";
import LanguageProfileName from "@/components/bazarr/LanguageProfile";
import { ItemEditModal } from "@/components/forms/ItemEditForm";
import { useModals } from "@/modules/modals";
@@ -44,6 +45,13 @@ const SeriesView: FunctionComponent = () => {
},
},
{
+ Header: "Audio",
+ accessor: "audio_language",
+ Cell: ({ value }) => {
+ return <AudioList audios={value}></AudioList>;
+ },
+ },
+ {
Header: "Languages Profile",
accessor: "profileId",
Cell: ({ value }) => {
diff --git a/frontend/src/pages/Settings/Languages/index.tsx b/frontend/src/pages/Settings/Languages/index.tsx
index 4616ab1ab..64c3e58b2 100644
--- a/frontend/src/pages/Settings/Languages/index.tsx
+++ b/frontend/src/pages/Settings/Languages/index.tsx
@@ -69,19 +69,28 @@ const SettingsLanguagesView: FunctionComponent = () => {
></LanguageSelector>
</Section>
- <Section header="Default Unknown Track Language">
- <Selector
- clearable
- settingKey={defaultUndAudioLang}
- label="Treat unknown language audio track as (changing this will trigger missing subtitles calculation)"
- placeholder="Select languages"
- options={und_audio_languages.map((v) => {
- return { label: v.name, value: v.code2 };
- })}
- settingOptions={{
- onSubmit: (v) => (v === null ? "" : v),
- }}
- ></Selector>
+ <Section header="Embedded Tracks Language">
+ <Check
+ label="Deep analyze media file to get audio tracks language."
+ settingKey="settings-general-parse_embedded_audio_track"
+ ></Check>
+ <CollapseBox
+ indent
+ settingKey="settings-general-parse_embedded_audio_track"
+ >
+ <Selector
+ clearable
+ settingKey={defaultUndAudioLang}
+ label="Treat unknown language audio track as (changing this will trigger missing subtitles calculation)"
+ placeholder="Select languages"
+ options={und_audio_languages.map((v) => {
+ return { label: v.name, value: v.code2 };
+ })}
+ settingOptions={{
+ onSubmit: (v) => (v === null ? "" : v),
+ }}
+ ></Selector>
+ </CollapseBox>
<Selector
clearable