def getEmbeddedLanguages(video_path): embedded_subtitle_languages = set() try: with io.open(video_path, 'rb') as f: mkv = MKV(f) if mkv.subtitle_tracks: for st in mkv.subtitle_tracks: if st.language: try: embedded_subtitle_languages.add(babelfish.Language.fromalpha3b(st.language)) except babelfish.Error: sickrage.LOGGER.debug('Embedded subtitle track is not a valid language') embedded_subtitle_languages.add(babelfish.Language('und')) elif st.name: try: embedded_subtitle_languages.add(babelfish.Language.fromname(st.name)) except babelfish.Error: sickrage.LOGGER.debug('Embedded subtitle track is not a valid language') embedded_subtitle_languages.add(babelfish.Language('und')) else: embedded_subtitle_languages.add(babelfish.Language('und')) else: sickrage.LOGGER.debug('MKV has no subtitle track') except MalformedMKVError: sickrage.LOGGER.info('MKV seems to be malformed ( %s ), ignoring embedded subtitles' % video_path) return embedded_subtitle_languages
def qualified_files(self): if self._qualified_files: return self._qualified_files pattern = re.compile(r'.*\.(mkv|mp4|avi)$', re.IGNORECASE) language = Language(self.language) for root, dirnames, filenames in os.walk(self.search_folder, topdown=True): dirnames[:] = [d for d in dirnames if d != "Plex Versions" and not d.startswith('.')] for filename in (filename for filename in filenames if self.verify_file(root, filename, pattern, language)): full_filename = os.path.join(root, filename) embedded_match = False if self.embedded: try: extension = os.path.splitext(filename)[1].lower() if extension == '.mkv': with open(full_filename, 'rb') as f: mkv = MKV(f) if mkv is not None: if mkv.audio_tracks and len(mkv.audio_tracks) == 1: embedded_match = self.verify_embedded(mkv.audio_tracks, language) if not embedded_match: embedded_match = self.verify_embedded(mkv.subtitle_tracks, language) if embedded_match: self.logger.info(f'Internal subtitle found for {full_filename}') else: self.logger.info(f'Internal audio found for {full_filename}') except: pass if not embedded_match: self._qualified_files.append(full_filename) if self._qualified_files: self.logger.info(f'{len(self._qualified_files)} file(s) to be processed') return self._qualified_files
def getEmbeddedLanguages(video_path): embedded_subtitle_languages = set() try: with io.open(video_path, 'rb') as f: mkv = MKV(f) if mkv.subtitle_tracks: for st in mkv.subtitle_tracks: if st.language: try: embedded_subtitle_languages.add( Language.fromalpha3b(st.language)) except BabelfishError: logger.log( 'Embedded subtitle track is not a valid language', logger.DEBUG) embedded_subtitle_languages.add(Language('und')) elif st.name: try: embedded_subtitle_languages.add( Language.fromname(st.name)) except BabelfishError: logger.log( 'Embedded subtitle track is not a valid language', logger.DEBUG) embedded_subtitle_languages.add(Language('und')) else: embedded_subtitle_languages.add(Language('und')) else: logger.log('MKV has no subtitle track', logger.DEBUG) except MalformedMKVError: logger.log( 'MKV seems to be malformed ( %s ), ignoring embedded subtitles' % video_path, logger.INFO) return embedded_subtitle_languages
def meta_load_hexsignature(in_file): with open(in_file, 'rb') as f: vid_meta = MKV(f) str_tags = str(vid_meta.tags[0]) start = str_tags.find("ACERT_HASH")+47 hex_sig = "" # wprint("deat") while str_tags[start] != ']': hex_sig += str_tags[start] start += 1 # print(hex_sig) return hex_sig
def _mkv_screen_size(filename): """ Parses mkv file for width and height :param filename: full path and filename to a video file :type: str :returns tuple: (width, height) """ try: if filename.endswith('.mkv'): with open(filename, 'rb') as f: mkv = MKV(f) return mkv.video_tracks[0].width, mkv.video_tracks[0].height except Exception: pass return None, None
def create_video(msg, video, dest, subtitles, fonts_dir, chapters=None): mkv = MKV(open(video, 'rb')) if len(mkv.video_tracks) > 1: msg.send_warning('More than one attached video.') # Detect audios in japanese if len(mkv.audio_tracks) > 1: audios = [ audio for audio in mkv.audio_tracks if audio.language == settings.MASTER_LANG ] if len(audios): raise PrintableException('Too audios in Japanese') if not len(audios): raise PrintableException('Too audios. None in Japanese') audio = audios[0] else: audio = mkv.audio_tracks[0] source = MkvSource(video) # Copiar solo el audio en japonés o el único que hay source.copy_audios(audio.number - 1) source.copy_videos('all') # Copiar todos los vídeos mkvmerge = MkvMerge(dest) mkvmerge.add_source( source) # Añadimos a nuestro archivo los datos copiados del original if len(subtitles) > 1: subtitles = settings.SUBTITLES_SORTED(subtitles) for i, subtitle in enumerate(subtitles): if hasattr(settings.SUBTITLES_DESCRIPTION, '__call__'): subtitle_description = settings.SUBTITLES_DESCRIPTION( video, dest, subtitle) else: subtitle_description = settings.SUBTITLES_DESCRIPTION mkvmerge.add_subtitle(subtitle, subtitle_description, settings.SUBTITLES_LANG, True if i is 0 else False) # Añadimos los subtítulos desde el directorio mkvmerge.add_attachments_from_dir(fonts_dir) if chapters is not None: mkvmerge.add_chapters(chapters, settings.SUBTITLES_LANG) mkvmerge.create()
def refine(video, embedded_subtitles=True, **kwargs): """Refine a video by searching its metadata. patch: remove embedded subtitle detection Several :class:`~subliminal.video.Video` attributes can be found: * :attr:`~subliminal.video.Video.resolution` * :attr:`~subliminal.video.Video.video_codec` * :attr:`~subliminal.video.Video.audio_codec` * :attr:`~subliminal.video.Video.subtitle_languages` :param bool embedded_subtitles: search for embedded subtitles. """ # skip non existing videos if not video.exists: return # check extensions extension = os.path.splitext(video.name)[1] if extension == '.mkv': with open(video.name, 'rb') as f: mkv = MKV(f) # main video track if mkv.video_tracks: video_track = mkv.video_tracks[0] # resolution if video_track.height in (480, 720, 1080): if video_track.interlaced: video.resolution = '%di' % video_track.height else: video.resolution = '%dp' % video_track.height logger.debug('Found resolution %s', video.resolution) # video codec if video_track.codec_id == 'V_MPEG4/ISO/AVC': video.video_codec = 'h264' logger.debug('Found video_codec %s', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/SP': video.video_codec = 'DivX' logger.debug('Found video_codec %s', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/ASP': video.video_codec = 'XviD' logger.debug('Found video_codec %s', video.video_codec) else: logger.warning('MKV has no video track') # main audio track if mkv.audio_tracks: audio_track = mkv.audio_tracks[0] # audio codec if audio_track.codec_id == 'A_AC3': video.audio_codec = 'AC3' logger.debug('Found audio_codec %s', video.audio_codec) elif audio_track.codec_id == 'A_DTS': video.audio_codec = 'DTS' logger.debug('Found audio_codec %s', video.audio_codec) elif audio_track.codec_id == 'A_AAC': video.audio_codec = 'AAC' logger.debug('Found audio_codec %s', video.audio_codec) else: logger.warning('MKV has no audio track') else: logger.debug('Unsupported video extension %s', extension)
def scan_video(path, subtitles=True, embedded_subtitles=True): """Scan a video and its subtitle languages from a video `path`. :param str path: existing path to the video. :param bool subtitles: scan for subtitles with the same name. :param bool embedded_subtitles: scan for embedded subtitles. :return: the scanned video. :rtype: :class:`Video` """ # check for non-existing path if not os.path.exists(path): raise ValueError('Path does not exist') # check video extension if not path.endswith(VIDEO_EXTENSIONS): raise ValueError('%s is not a valid video extension' % os.path.splitext(path)[1]) dirpath, filename = os.path.split(path) logger.info('Scanning video %r in %r', filename, dirpath) # guess video = Video.fromguess(path, guess_file_info(path)) # size and hashes video.size = os.path.getsize(path) if video.size > 10485760: logger.debug('Size is %d', video.size) video.hashes['opensubtitles'] = hash_opensubtitles(path) video.hashes['thesubdb'] = hash_thesubdb(path) logger.debug('Computed hashes %r', video.hashes) else: logger.warning('Size is lower than 10MB: hashes not computed') # external subtitles if subtitles: video.subtitle_languages |= set(search_external_subtitles(path).values()) # video metadata with enzyme try: if filename.endswith('.mkv'): with open(path, 'rb') as f: mkv = MKV(f) # main video track if mkv.video_tracks: video_track = mkv.video_tracks[0] # resolution if video_track.height in (480, 720, 1080): if video_track.interlaced: video.resolution = '%di' % video_track.height else: video.resolution = '%dp' % video_track.height logger.debug('Found resolution %s with enzyme', video.resolution) # video codec if video_track.codec_id == 'V_MPEG4/ISO/AVC': video.video_codec = 'h264' logger.debug('Found video_codec %s with enzyme', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/SP': video.video_codec = 'DivX' logger.debug('Found video_codec %s with enzyme', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/ASP': video.video_codec = 'XviD' logger.debug('Found video_codec %s with enzyme', video.video_codec) else: logger.warning('MKV has no video track') # main audio track if mkv.audio_tracks: audio_track = mkv.audio_tracks[0] # audio codec if audio_track.codec_id == 'A_AC3': video.audio_codec = 'AC3' logger.debug('Found audio_codec %s with enzyme', video.audio_codec) elif audio_track.codec_id == 'A_DTS': video.audio_codec = 'DTS' logger.debug('Found audio_codec %s with enzyme', video.audio_codec) elif audio_track.codec_id == 'A_AAC': video.audio_codec = 'AAC' logger.debug('Found audio_codec %s with enzyme', video.audio_codec) else: logger.warning('MKV has no audio track') # subtitle tracks if mkv.subtitle_tracks: if embedded_subtitles: embedded_subtitle_languages = set() for st in mkv.subtitle_tracks: if st.language: try: embedded_subtitle_languages.add(Language.fromalpha3b(st.language)) except BabelfishError: logger.error('Embedded subtitle track language %r is not a valid language', st.language) embedded_subtitle_languages.add(Language('und')) elif st.name: try: embedded_subtitle_languages.add(Language.fromname(st.name)) except BabelfishError: logger.debug('Embedded subtitle track name %r is not a valid language', st.name) embedded_subtitle_languages.add(Language('und')) else: embedded_subtitle_languages.add(Language('und')) logger.debug('Found embedded subtitle %r with enzyme', embedded_subtitle_languages) video.subtitle_languages |= embedded_subtitle_languages else: logger.debug('MKV has no subtitle track') except EnzymeError: logger.exception('Parsing video metadata with enzyme failed') return video
def refine(video, embedded_subtitles=True, **kwargs): """Refine a video by searching its metadata. Several :class:`~subliminal.video.Video` attributes can be found: * :attr:`~subliminal.video.Video.resolution` * :attr:`~subliminal.video.Video.video_codec` * :attr:`~subliminal.video.Video.audio_codec` * :attr:`~subliminal.video.Video.subtitle_languages` :param bool embedded_subtitles: search for embedded subtitles. """ # skip non existing videos if not video.exists: return # check extensions extension = os.path.splitext(video.name)[1] if extension == '.mkv': with open(video.name, 'rb') as f: mkv = MKV(f) # main video track if mkv.video_tracks: video_track = mkv.video_tracks[0] # resolution if video_track.height in (480, 720, 1080): if video_track.interlaced: video.resolution = '%di' % video_track.height else: video.resolution = '%dp' % video_track.height logger.debug('Found resolution %s', video.resolution) # video codec if video_track.codec_id == 'V_MPEG4/ISO/AVC': video.video_codec = 'H.264' logger.debug('Found video_codec %s', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/SP': video.video_codec = 'DivX' logger.debug('Found video_codec %s', video.video_codec) elif video_track.codec_id == 'V_MPEG4/ISO/ASP': video.video_codec = 'Xvid' logger.debug('Found video_codec %s', video.video_codec) else: logger.warning('MKV has no video track') # main audio track if mkv.audio_tracks: audio_track = mkv.audio_tracks[0] # audio codec if audio_track.codec_id == 'A_AC3': video.audio_codec = 'Dolby Digital' logger.debug('Found audio_codec %s', video.audio_codec) elif audio_track.codec_id == 'A_DTS': video.audio_codec = 'DTS' logger.debug('Found audio_codec %s', video.audio_codec) elif audio_track.codec_id == 'A_AAC': video.audio_codec = 'AAC' logger.debug('Found audio_codec %s', video.audio_codec) else: logger.warning('MKV has no audio track') # subtitle tracks if mkv.subtitle_tracks: if embedded_subtitles: embedded_subtitle_languages = set() for st in mkv.subtitle_tracks: if st.language: try: embedded_subtitle_languages.add( Language.fromalpha3b(st.language)) except BabelfishError: logger.error( 'Embedded subtitle track language %r is not a valid language', st.language) embedded_subtitle_languages.add(Language('und')) elif st.name: try: embedded_subtitle_languages.add( Language.fromname(st.name)) except BabelfishError: logger.debug( 'Embedded subtitle track name %r is not a valid language', st.name) embedded_subtitle_languages.add(Language('und')) else: embedded_subtitle_languages.add(Language('und')) logger.debug('Found embedded subtitle %r', embedded_subtitle_languages) video.subtitle_languages |= embedded_subtitle_languages else: logger.debug('MKV has no subtitle track') else: logger.debug('Unsupported video extension %s', extension)
def get_video_title(path): mkv = MKV(open(path, 'rb')) return mkv.info.title
def subtitlesLanguages(video_path): """Return a list detected subtitles for the given video file""" resultList = [] embedded_subtitle_languages = set() # Serch for embedded subtitles if not sickbeard.EMBEDDED_SUBTITLES_ALL: if video_path.endswith('mkv'): try: with open(video_path.encode(sickbeard.SYS_ENCODING), 'rb') as f: mkv = MKV(f) if mkv.subtitle_tracks: for st in mkv.subtitle_tracks: if st.language: try: embedded_subtitle_languages.add( Language.fromalpha3b(st.language)) except BabelfishError: logger.log( 'Embedded subtitle track is not a valid language', logger.DEBUG) embedded_subtitle_languages.add( Language('und')) elif st.name: try: embedded_subtitle_languages.add( Language.fromname(st.name)) except BabelfishError: logger.log( 'Embedded subtitle track is not a valid language', logger.DEBUG) embedded_subtitle_languages.add( Language('und')) else: embedded_subtitle_languages.add(Language('und')) else: logger.log('MKV has no subtitle track', logger.DEBUG) except MalformedMKVError: logger.log( 'MKV seems to be malformed, ignoring embedded subtitles', logger.WARNING) # Search subtitles in the absolute path if sickbeard.SUBTITLES_DIR and ek(os.path.exists, sickbeard.SUBTITLES_DIR): video_path = ek(os.path.join, sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path)) # Search subtitles in the relative path elif sickbeard.SUBTITLES_DIR: video_path = ek(os.path.join, ek(os.path.dirname, video_path), sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path)) external_subtitle_languages = subliminal.video.scan_subtitle_languages( video_path) subtitle_languages = external_subtitle_languages.union( embedded_subtitle_languages) if (len(subtitle_languages) is 1 and len(wantedLanguages()) is 1 ) and Language('und') in subtitle_languages: subtitle_languages.remove(Language('und')) subtitle_languages.add(fromietf(wantedLanguages()[0])) for language in subtitle_languages: if hasattr(language, 'opensubtitles') and language.opensubtitles: resultList.append(language.opensubtitles) elif hasattr(language, 'alpha3') and language.alpha3: resultList.append(language.alpha3) elif hasattr(language, 'alpha2') and language.alpha2: resultList.append(language.alpha2) defaultLang = wantedLanguages() if ('pob' in defaultLang or 'pb' in defaultLang) and ('pt' not in defaultLang and 'por' not in defaultLang): resultList = [ x if not x in ['por', 'pt'] else u'pob' for x in resultList ] return sorted(resultList)