Added mediainfo as potential embedded subtitles parser. #2007

This commit is contained in:
morpheus65535 2022-12-20 23:37:52 -05:00
parent 1233026adc
commit c4b8345e65
5 changed files with 79 additions and 23 deletions

View File

@ -78,7 +78,8 @@ defaults = {
'wanted_search_frequency_movie': '3',
'subzero_mods': '[]',
'dont_notify_manual_actions': 'False',
'hi_extension': 'hi'
'hi_extension': 'hi',
'embedded_subtitles_parser': 'ffprobe'
},
'auth': {
'type': 'None',

View File

@ -32,38 +32,45 @@ def refine_from_ffprobe(path, video):
data = parse_video_metadata(file=path, file_size=file_id['file_size'],
episode_file_id=file_id['episode_file_id'])
if not data['ffprobe']:
if not data['ffprobe'] or data['mediainfo']:
logging.debug("No FFprobe available in cache for this file: {}".format(path))
return video
logging.debug('FFprobe found: %s', data['ffprobe'])
if 'video' not in data['ffprobe']:
logging.debug('BAZARR FFprobe was unable to find video tracks in the file!')
if data['ffprobe']:
logging.debug('FFprobe found: %s', data['ffprobe'])
parser_data = data['ffprobe']
elif data['mediainfo']:
logging.debug('Mediainfo found: %s', data['mediainfo'])
parser_data = data['mediainfo']
else:
if 'resolution' in data['ffprobe']['video'][0]:
parser_data = {}
if 'video' not in parser_data:
logging.debug('BAZARR parser was unable to find video tracks in the file!')
else:
if 'resolution' in parser_data['video'][0]:
if not video.resolution:
video.resolution = data['ffprobe']['video'][0]['resolution']
if 'codec' in data['ffprobe']['video'][0]:
video.resolution = parser_data['video'][0]['resolution']
if 'codec' in parser_data['video'][0]:
if not video.video_codec:
video.video_codec = data['ffprobe']['video'][0]['codec']
if 'frame_rate' in data['ffprobe']['video'][0]:
video.video_codec = parser_data['video'][0]['codec']
if 'frame_rate' in parser_data['video'][0]:
if not video.fps:
if isinstance(data['ffprobe']['video'][0]['frame_rate'], float):
video.fps = data['ffprobe']['video'][0]['frame_rate']
if isinstance(parser_data['video'][0]['frame_rate'], float):
video.fps = parser_data['video'][0]['frame_rate']
else:
try:
video.fps = data['ffprobe']['video'][0]['frame_rate'].magnitude
video.fps = parser_data['video'][0]['frame_rate'].magnitude
except AttributeError:
video.fps = data['ffprobe']['video'][0]['frame_rate']
video.fps = parser_data['video'][0]['frame_rate']
if 'audio' not in data['ffprobe']:
logging.debug('BAZARR FFprobe was unable to find audio tracks in the file!')
if 'audio' not in parser_data:
logging.debug('BAZARR parser was unable to find audio tracks in the file!')
else:
if 'codec' in data['ffprobe']['audio'][0]:
if 'codec' in parser_data['audio'][0]:
if not video.audio_codec:
video.audio_codec = data['ffprobe']['audio'][0]['codec']
for track in data['ffprobe']['audio']:
video.audio_codec = parser_data['audio'][0]['codec']
for track in parser_data['audio']:
if 'language' in track:
video.audio_languages.add(track['language'].alpha3)

View File

@ -11,6 +11,7 @@ from enzyme.exceptions import MalformedMKVError
from languages.custom_lang import CustomLanguage
from app.database import TableEpisodes, TableMovies
from utilities.path_mappings import path_mappings
from app.config import settings
def _handle_alpha3(detected_language: dict):
@ -46,6 +47,24 @@ def embedded_subs_reader(file, file_size, episode_file_id=None, movie_file_id=No
codec = detected_language.get("format") # or None
subtitles_list.append([language, forced, hearing_impaired, codec])
elif 'mediainfo' in data and data["mediainfo"] and "subtitle" in data["mediainfo"]:
for detected_language in data["mediainfo"]["subtitle"]:
if "language" not in detected_language:
continue
# Avoid commentary subtitles
name = detected_language.get("name", "").lower()
if "commentary" in name:
logging.debug("Ignoring commentary subtitle: %s", name)
continue
language = _handle_alpha3(detected_language)
forced = detected_language.get("forced", False)
hearing_impaired = detected_language.get("hearing_impaired", False)
codec = detected_language.get("format") # or None
subtitles_list.append([language, forced, hearing_impaired, codec])
elif data["enzyme"]:
for subtitle_track in data["enzyme"].subtitle_tracks:
hearing_impaired = (
@ -68,6 +87,7 @@ def parse_video_metadata(file, file_size, episode_file_id=None, movie_file_id=No
# Define default data keys value
data = {
"ffprobe": {},
"mediainfo": {},
"enzyme": {},
"file_id": episode_file_id or movie_file_id,
"file_size": file_size,
@ -102,12 +122,19 @@ def parse_video_metadata(file, file_size, episode_file_id=None, movie_file_id=No
# if not, we retrieve the metadata from the file
from utilities.binaries import get_binary
ffprobe_path = get_binary("ffprobe")
ffprobe_path = mediainfo_path = None
if settings.general.embedded_subtitles_parser == 'ffprobe':
ffprobe_path = get_binary("ffprobe")
elif settings.general.embedded_subtitles_parser == 'mediainfo':
mediainfo_path = get_binary("mediainfo")
# if we have ffprobe available
if ffprobe_path:
data["ffprobe"] = know(video_path=file, context={"provider": "ffmpeg", "ffmpeg": ffprobe_path})
# if not, we use enzyme for mkv files
# or if we have mediainfo available
elif mediainfo_path:
data["mediainfo"] = know(video_path=file, context={"provider": "mediainfo", "mediainfo": mediainfo_path})
# else, we use enzyme for mkv files
else:
if os.path.splitext(file)[1] == ".mkv":
with open(file, "rb") as f:
@ -116,7 +143,7 @@ def parse_video_metadata(file, file_size, episode_file_id=None, movie_file_id=No
except MalformedMKVError:
logging.error(
"BAZARR cannot analyze this MKV with our built-in MKV parser, you should install "
"ffmpeg/ffprobe: " + file
"ffmpeg/ffprobe or mediainfo: " + file
)
else:
data["enzyme"] = mkv

View File

@ -20,6 +20,7 @@ import {
adaptiveSearchingDeltaOption,
antiCaptchaOption,
colorOptions,
embeddedSubtitlesParserOption,
folderOptions,
hiExtensionOptions,
} from "./options";
@ -278,6 +279,14 @@ const SettingsSubtitlesView: FunctionComponent = () => {
Hide embedded subtitles for languages that are not currently
desired.
</Message>
<Selector
settingKey="settings-general-embedded_subtitles_parser"
settingOptions={{
onSaved: (v) => (v === undefined ? "ffprobe" : v),
}}
options={embeddedSubtitlesParserOption}
></Selector>
<Message>Embedded subtitles video parser</Message>
</CollapseBox>
</Section>
<Section header="Post-Processing">

View File

@ -41,6 +41,18 @@ export const antiCaptchaOption: SelectorOption<string>[] = [
},
];
export const embeddedSubtitlesParserOption: SelectorOption<string>[] = [
{
label: "ffprobe (faster)",
value: "ffprobe",
},
{
label:
"mediainfo (slower but may give better results. Must be already installed)",
value: "mediainfo",
},
];
export const adaptiveSearchingDelayOption: SelectorOption<string>[] = [
{
label: "1 week",