def detect_imagemagick(path): a = Invocation('identify -verbose {0}') a(path) a.run() if a.returncode or a.exited: return None result = a.stdout[0].split('\n') # Check for an actual mimetype first mimetype = None for line in result: line = line.lstrip(' ') if line.startswith('Mime type: '): mimetype = line[11:] if mimetype in [ 'image/png', 'image/jpeg' ]: return { 'type': mimetype, 'extra': None, 'flags': None } # Check for SVG, it's special for line in result: line = line.lstrip(' ') if line == 'Format: SVG (Scalable Vector Graphics)': return { 'type': 'image/svg+xml', 'extra': None, 'flags': None } return { 'type': 'image', 'extra': None, 'flags': None }
def detect_interlacing(path): a = Invocation('ffmpeg -vf idet -vframes 100 -an -f rawvideo -y /dev/null -i {0}') a(path) a.run() if a.returncode or a.exited: return False result = a.stdout[1].split('\n') for line in result: print(line) if line.startswith('[Parsed_idet_'): match = re.search('TFF:([0-9]+) BFF:([0-9]+) Progressive:([0-9]+) Undetermined:([0-9]+)', line) if match == None: return False tff = float(match.group(1)) bff = float(match.group(2)) progressive = float(match.group(3)) undetermined = float(match.group(4)) total = tff + bff + progressive + undetermined if total == 0: return False tff = tff / total bff = bff / total progressive = progressive / total undetermined = undetermined / total if undetermined < 0.05 and progressive < 0.8: if tff >= 0.8 or bff >= 0.8: # It's probably interlaced. return True return False
def detect_interlacing(path): a = Invocation( 'ffmpeg -vf idet -vframes 100 -an -f rawvideo -y /dev/null -i {0}') a(path) a.run() if a.returncode or a.exited: return False result = a.stdout[1].split('\n') for line in result: if line.startswith('[Parsed_idet_'): match = re.search( 'TFF:([0-9]+) BFF:([0-9]+) Progressive:([0-9]+) Undetermined:([0-9]+)', line) if match == None: return False tff = float(match.group(1)) bff = float(match.group(2)) progressive = float(match.group(3)) undetermined = float(match.group(4)) total = tff + bff + progressive + undetermined if total == 0: return False tff = tff / total bff = bff / total progressive = progressive / total undetermined = undetermined / total if undetermined < 0.05 and progressive < 0.8: if tff >= 0.8 or bff >= 0.8: # It's probably interlaced. return True return False
def detect_ffprobe(path): # IMPORTANT: jdiez, this doesn't work when the path has spaces in it # I tried wrapping {0} in quotes to no avail a = Invocation('ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}') a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout[0]) if result["format"]["nb_streams"] == 1: return detect_stream(result["streams"][0]) # Try to guess what it is from the streams inside # I've done a little more detection than we really need to, for things like subtitles audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 for stream in result["streams"]: s = detect_stream(stream) t = s['type'] if not s or not t: unknown_streams += 1 else: if t.startswith('image'): image_streams += 1 elif t == 'video': video_streams += 1 elif t == 'audio': audio_streams += 1 elif t == 'subtitle': subtitle_streams += 1 elif t == 'font': font_streams += 1 else: unknown_streams += 1 if audio_streams == 1 and video_streams == 0: return { 'type': 'audio', 'extra': { 'has_audio': True, 'has_video': False }, 'flags': None } if video_streams > 0: return { 'type': 'video', 'extra': { 'has_audio': audio_streams > 0, 'has_video': True }, 'flags': { 'autoplay': False, 'loop': False, 'mute': False, } } return None
def detect_plaintext(path): a = Invocation('file -b -e elf -e tar -e compress -e cdf -e apptype -i {0}') a(path) a.run() if a.returncode or a.exited: return None, None result = a.stdout[0] if result.startswith('text/x-') or result == 'text/plain': return result[:result.find(';')] return None, None
def _execute(self, command, ignoreNonZero = False): ext = extension(self.f.original) tlc = Invocation(command)(self.path, self.output, extension=ext) tlc.run(self.time if not self.ignore_limit else None) if tlc.exited and self.important: raise TimeoutException if tlc.returncode != 0 and self.important and not ignoreNonZero: raise ProcessingException
def _execute(self, command): ext = extension(self.f.original) tlc = Invocation(command)(self.path, self.output, extension=ext) tlc.run(self.time) if tlc.exited and self.important: raise TimeoutException if tlc.returncode != 0 and self.important: raise ProcessingException
def _execute(self, command, ignoreNonZero=False): ext = extension(self.f.original) tlc = Invocation(command)(self.path, self.output, extension=ext) tlc.run(self.time if not self.ignore_limit else None) if tlc.exited and self.important: raise TimeoutException if tlc.returncode != 0 and self.important and not ignoreNonZero: raise ProcessingException
def detect_plaintext(path): a = Invocation('file -b -e elf -e tar -e compress -e cdf -e apptype -i {0}') a(path) a.run() if a.returncode or a.exited: return None result = a.stdout[0] if result.startswith('text/x-') or result == 'text/plain': return { 'type': result[:result.find(';')], 'metadata': None, 'processor_state': None, 'flags': None } return None
def detect_plaintext(path): a = Invocation("file -b -e elf -e tar -e compress -e cdf -e apptype -i {0}") a(path) a.run() if a.returncode or a.exited: return None result = a.stdout if result.startswith("text/x-") or result == "text/plain": return { "type": result[: result.find(";")], "metadata": None, "processor_state": None, "flags": None, } return None
def detect_imagemagick(path): a = Invocation('identify -verbose {0}') a(path) a.run() try: result = a.stdout[0].split('\n') # Get mime type and dimensions mimetype = None metadata = None for line in result: line = line.lstrip(' ') if line.startswith('Mime type: '): mimetype = line[11:] match = re.search('(\d+)x(\d+)', line) if line.startswith('Geometry: '): metadata = { 'dimensions': { 'width': int(match.group(1)), 'height': int(match.group(2)) } } if mimetype in ['image/png', 'image/jpeg', 'image/svg+xml']: return { 'type': mimetype, 'metadata': metadata, 'processor_state': None, 'flags': None } # Check for other formats for line in result: line = line.lstrip(' ') if line == 'Format: XCF (GIMP image)': return { 'type': 'image/x-gimp-xcf', 'metadata': metadata, 'processor_state': None, 'flags': None } return { 'type': 'image', 'metadata': metadata, 'processor_state': None, 'flags': None } except Exception as e: print("ImageMagick failed detection", e) return None
def detect_imagemagick(path): a = Invocation("identify -verbose {0}") a(path) a.run() try: result = a.stdout.split("\n") # Get mime type and dimensions mimetype = None metadata = None for line in result: line = line.lstrip(" ") if line.startswith("Mime type: "): mimetype = line[11:] match = re.search("(\d+)x(\d+)", line) if line.startswith("Geometry: "): metadata = { "dimensions": { "width": int(match.group(1)), "height": int(match.group(2)), } } if mimetype in ["image/png", "image/jpeg", "image/svg+xml"]: return { "type": mimetype, "metadata": metadata, "processor_state": None, "flags": None, } # Check for other formats for line in result: line = line.lstrip(" ") if line == "Format: XCF (GIMP image)": return { "type": "image/x-gimp-xcf", "metadata": metadata, "processor_state": None, "flags": None, } return { "type": "image", "metadata": metadata, "processor_state": None, "flags": None, } except: return None
def detect_imagemagick(path): a = Invocation('identify -verbose {0}') a(path) a.run() if a.returncode or a.exited: return None result = a.stdout[0].split('\n') # Check for an actual mimetype first mimetype = None for line in result: line = line.lstrip(' ') if line.startswith('Mime type: '): mimetype = line[11:] if mimetype in ['image/png', 'image/jpeg']: return { 'type': mimetype, 'metadata': None, 'processor_state': None, 'flags': None } # Check for other formats for line in result: line = line.lstrip(' ') if line == 'Format: SVG (Scalable Vector Graphics)': return { 'type': 'image/svg+xml', 'metadata': None, 'processor_state': None, 'flags': None } if line == 'Format: XCF (GIMP image)': return { 'type': 'image/x-gimp-xcf', 'metadata': None, 'processor_state': None, 'flags': None } return { 'type': 'image', 'metadata': None, 'processor_state': None, 'flags': None }
def detect_imagemagick(path): a = Invocation('identify -verbose {0}') a(path) a.run() if a.returncode or a.exited: return None result = a.stdout[0].split('\n') # Check for an actual mimetype first mimetype = None for line in result: line = line.lstrip(' ') if line.startswith('Mime type: '): mimetype = line[11:] if mimetype in [ 'image/png', 'image/jpeg' ]: return { 'type': mimetype, 'metadata': None, 'processor_state': None, 'flags': None } # Check for other formats for line in result: line = line.lstrip(' ') if line == 'Format: SVG (Scalable Vector Graphics)': return { 'type': 'image/svg+xml', 'metadata': None, 'processor_state': None, 'flags': None } if line == 'Format: XCF (GIMP image)': return { 'type': 'image/x-gimp-xcf', 'metadata': None, 'processor_state': None, 'flags': None } return { 'type': 'image', 'metadata': None, 'processor_state': None, 'flags': None }
def detect_imagemagick(path): a = Invocation('identify -verbose {0}') a(path) a.run() try: result = a.stdout[0].split('\n') # Get mime type and dimensions mimetype = None metadata = None for line in result: line = line.lstrip(' ') if line.startswith('Mime type: '): mimetype = line[11:] match = re.search('(\d+)x(\d+)', line) if line.startswith('Geometry: '): metadata = { 'dimensions': { 'width': int(match.group(1)), 'height': int(match.group(2)) } } if mimetype in [ 'image/png', 'image/jpeg', 'image/svg+xml' ]: return { 'type': mimetype, 'metadata': metadata, 'processor_state': None, 'flags': None } # Check for other formats for line in result: line = line.lstrip(' ') if line == 'Format: XCF (GIMP image)': return { 'type': 'image/x-gimp-xcf', 'metadata': metadata, 'processor_state': None, 'flags': None } return { 'type': 'image', 'metadata': metadata, 'processor_state': None, 'flags': None } except: return None
def sync(self): self._execute(copy) map_string = '' filter_string = 'scale=trunc(in_w/2)*2:trunc(in_h/2)*2' if self.processor_state['has_video']: self._execute("ffmpeg -y -i {0} -vframes 1 -map 0:v:0 {1}.jpg") map_string += ' -map 0:v:0' if self.processor_state['has_audio']: map_string += ' -map 0:a:0' if 'interlaced' in self.processor_state: print("WARNING: Detected interlacing on " + self.output) filter_string = 'yadif,' + filter_string self._execute( "ffmpeg -y -i {0} -vcodec libx264 -acodec libfdk_aac -movflags faststart -pix_fmt yuv420p -profile:v baseline -level 3.0 -preset slower -crf 18 -vf " + filter_string + map_string + " {1}.mp4") skip_webm = False for s in self.processor_state['streams']: if 'info' in s: if 'video_codec' in s['info'] and s['info'][ 'video_codec'] == 'vp8': skip_webm = True if not skip_webm: self._execute( "ffmpeg -y -i {0} -c:v libvpx -c:a libvorbis -pix_fmt yuv420p -quality good -b:v 5M -crf 5 -vf " + filter_string + map_string + " {1}.webm") # Extract extra streams if present fonts = [] extract_fonts = False if 'has_fonts' in self.processor_state and 'has_subtitles' in self.processor_state: if self.processor_state['has_fonts'] or self.processor_state[ 'has_subtitles']: for stream in self.processor_state['streams']: if stream['type'] == 'font': ext = _extension(stream["info"]) if ext in ['ttf', 'otf']: # Note that ffmpeg returns a nonzero exit code when dumping attachments because there's technically no output file # -dump_attachment is a mechanism completely removed from the rest of the ffmpeg workflow self._execute( "ffmpeg -y -dump_attachment:" + str(stream["index"]) + ' {1}_attachment_' + str(len(fonts)) + '.' + ext + ' -i {0}', ignoreNonZero=True) fonts.append(stream) elif stream['type'] == 'subtitle' and 'info' in stream: extension = None if stream['info']['codec_name'] == 'ssa': extension = '.ass' extract_fonts = True elif stream['info']['codec_name'] == 'srt': extension = '.srt' elif stream['info']['codec_name'] == 'vtt': extension = '.vtt' if extension != None: self._execute("ffmpeg -y -i {0} -map 0:s:0 {1}" + extension) if extension == '.srt': # convert to vtt vtt = convert_to_vtt( os.path.join(_cfg("storage_folder"), '%s.srt' % self.f.hash)) with open( os.path.join(_cfg("storage_folder"), '%s.vtt' % self.f.hash), 'w') as f: f.write(vtt) os.remove( os.path.join(_cfg("storage_folder"), '%s.srt' % self.f.hash)) if extract_fonts: # Examine font files and construct some CSS to import them css = '' i = 0 for font in fonts: ext = _extension(font['info']) if not ext in ['ttf', 'otf']: continue command = Invocation('otfinfo --info {0}') command( os.path.join( _cfg("storage_folder"), '%s_attachment_%s.%s' % (self.f.hash, i, _extension(font['info'])))) command.run() output = command.stdout[0].split('\n') family = None subfamily = None for line in output: if line.startswith('Family:'): family = line[7:].strip(' \t') if line.startswith('Subfamily:'): subfamily = line[10:].strip(' \t') css += '@font-face{font-family: "%s";' % family css += 'src:url("/%s_attachment_%s.%s");' % ( self.f.hash, i, _extension(font['info'])) if subfamily == 'SemiBold': css += 'font-weight: 600;' elif subfamily == 'Bold': css += 'font-weight: bold;' elif subfamily == 'Italic': css += 'font-style: italic;' css += '}' i += 1 css_file = open( os.path.join(_cfg("storage_folder"), '%s_fonts.css' % self.f.hash), 'w') css_file.write(css) css_file.close()
def sync(self): self._execute(copy) map_string = '' filter_string = 'scale=trunc(in_w/2)*2:trunc(in_h/2)*2' if self.processor_state['has_video']: self._execute("ffmpeg -y -i {0} -vframes 1 -map 0:v:0 {1}.jpg") map_string += ' -map 0:v:0' if self.processor_state['has_audio']: map_string += ' -map 0:a:0' if 'interlaced' in self.processor_state: print("WARNING: Detected interlacing on " + self.output) filter_string = 'yadif,' + filter_string self._execute("ffmpeg -y -i {0} -vcodec libx264 -acodec libfdk_aac -pix_fmt yuv420p -profile:v baseline -preset slower -crf 18 -vf " + filter_string + map_string + " {1}.mp4") skip_webm = False for s in self.processor_state['streams']: if 'info' in s: if 'video_codec' in s['info'] and s['info']['video_codec'] == 'vp8': skip_webm = True if not skip_webm: self._execute("ffmpeg -y -i {0} -c:v libvpx -c:a libvorbis -pix_fmt yuv420p -quality good -b:v 5M -crf 5 -vf " + filter_string + map_string + " {1}.webm") # Extract extra streams if present fonts = [] extract_fonts = False if 'has_fonts' in self.processor_state and 'has_subtitles' in self.processor_state: if self.processor_state['has_fonts'] or self.processor_state['has_subtitles']: for stream in self.processor_state['streams']: if stream['type'] == 'font': ext = _extension(stream["info"]) if ext in ['ttf', 'otf']: # Note that ffmpeg returns a nonzero exit code when dumping attachments because there's technically no output file # -dump_attachment is a mechanism completely removed from the rest of the ffmpeg workflow self._execute("ffmpeg -y -dump_attachment:" + str(stream["index"]) + ' {1}_attachment_' + str(len(fonts)) + '.' + ext + ' -i {0}', ignoreNonZero=True) fonts.append(stream) elif stream['type'] == 'subtitle' and 'info' in stream: extension = None if stream['info']['codec_name'] == 'ssa': extension = '.ass' extract_fonts = True elif stream['info']['codec_name'] == 'srt': extension = '.srt' elif stream['info']['codec_name'] == 'vtt': extension = '.vtt' if extension != None: self._execute("ffmpeg -y -i {0} -map 0:s:0 {1}" + extension) if extension == '.srt': # convert to vtt vtt = convert_to_vtt(os.path.join(_cfg("storage_folder"), '%s.srt' % self.f.hash)) with open(os.path.join(_cfg("storage_folder"), '%s.vtt' % self.f.hash), 'w') as f: f.write(vtt) os.remove(os.path.join(_cfg("storage_folder"), '%s.srt' % self.f.hash)) if extract_fonts: # Examine font files and construct some CSS to import them css = '' i = 0 for font in fonts: ext = _extension(font['info']) if not ext in ['ttf', 'otf']: continue command = Invocation('otfinfo --info {0}') command(os.path.join(_cfg("storage_folder"), '%s_attachment_%s.%s' % (self.f.hash, i, _extension(font['info'])))) command.run() output = command.stdout[0].split('\n') family = None subfamily = None for line in output: if line.startswith('Family:'): family = line[7:].strip(' \t') if line.startswith('Subfamily:'): subfamily = line[10:].strip(' \t') css += '@font-face{font-family: "%s";' % family css += 'src:url("/%s_attachment_%s.%s");' % (self.f.hash, i, _extension(font['info'])) if subfamily == 'SemiBold': css += 'font-weight: 600;' elif subfamily == 'Bold': css += 'font-weight: bold;' elif subfamily == 'Italic': css += 'font-style: italic;' css += '}' i += 1 css_file = open(os.path.join(_cfg("storage_folder"), '%s_fonts.css' % self.f.hash), 'w') css_file.write(css) css_file.close()
def detect_ffprobe(path): a = Invocation( 'ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}' ) a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout[0]) audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 metadata = dict() state = dict() flags = dict() state['streams'] = list() index = 0 for stream in result["streams"]: s = detect_stream(stream) if s == None: continue # Set up some metadata if s['metadata'] != None: if 'duration' in s['metadata']: metadata['duration'] = s['metadata']['duration'] if 'dimensions' in s['metadata']: metadata['dimensions'] = s['metadata']['dimensions'] t = s['type'] if not s or not t: unknown_streams += 1 else: state['streams'].append({ 'type': t, 'info': s['processor_state'], 'index': index }) if t.startswith('image'): image_streams += 1 elif t == 'video': video_streams += 1 flags = s['flags'] elif t == 'audio': audio_streams += 1 elif t == 'subtitle': subtitle_streams += 1 elif t == 'font': font_streams += 1 else: unknown_streams += 1 index += 1 metadata = ffprobe_addExtraMetadata(metadata, result) if audio_streams == 1 and video_streams == 0: metadata['has_audio'] = True metadata['has_video'] = False state['has_audio'] = True state['has_video'] = False return { 'type': 'audio', 'processor_state': state, 'metadata': metadata, 'flags': None } if video_streams > 0: metadata['has_audio'] = audio_streams > 0 metadata['has_video'] = True metadata['has_subtitles'] = subtitle_streams > 0 state['has_audio'] = audio_streams > 0 state['has_video'] = True state['has_fonts'] = font_streams > 0 state['has_subtitles'] = subtitle_streams > 0 if subtitle_streams > 0: metadata = addSubtitleInfo(metadata, state) if detect_interlacing(path): state['interlaced'] = True return { 'type': 'video', 'processor_state': state, 'metadata': metadata, 'flags': flags } return None
def detect_ffprobe(path): a = Invocation('ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}') a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout[0]) audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 metadata = dict() state = dict() flags = dict() state['streams'] = list() index = 0 for stream in result["streams"]: s = detect_stream(stream) # Set up some metadata if s['metadata'] != None: if 'duration' in s['metadata']: metadata['duration'] = s['metadata']['duration'] if 'dimensions' in s['metadata']: metadata['dimensions'] = s['metadata']['dimensions'] t = s['type'] if not s or not t: unknown_streams += 1 else: state['streams'].append({ 'type': t, 'info': s['processor_state'], 'index': index }) if t.startswith('image'): image_streams += 1 elif t == 'video': video_streams += 1 flags = s['flags'] elif t == 'audio': audio_streams += 1 elif t == 'subtitle': subtitle_streams += 1 elif t == 'font': font_streams += 1 else: unknown_streams += 1 index += 1 metadata = ffprobe_addExtraMetadata(metadata, result) if audio_streams == 1 and video_streams == 0: metadata['has_audio'] = True metadata['has_video'] = False state['has_audio'] = True state['has_video'] = False return { 'type': 'audio', 'processor_state': state, 'metadata': metadata, 'flags': None } if video_streams > 0: metadata['has_audio'] = audio_streams > 0 metadata['has_video'] = True metadata['has_subtitles'] = subtitle_streams > 0 state['has_audio'] = audio_streams > 0 state['has_video'] = True state['has_fonts'] = font_streams > 0 state['has_subtitles'] = subtitle_streams > 0 if subtitle_streams > 0: metadata = addSubtitleInfo(metadata, state) if detect_interlacing(path): state['interlaced'] = True return { 'type': 'video', 'processor_state': state, 'metadata': metadata, 'flags': flags } return None
def sync(self): self._execute(copy) map_string = "" filter_string = "scale=trunc(in_w/2)*2:trunc(in_h/2)*2" if self.processor_state["has_video"]: self._execute("ffmpeg -y -i {0} -vframes 1 -map 0:v:0 {1}.jpg") map_string += " -map 0:v:0" if self.processor_state["has_audio"]: map_string += " -map 0:a:0" if "interlaced" in self.processor_state: print(("WARNING: Detected interlacing on " + self.output)) filter_string = "yadif," + filter_string self._execute( "ffmpeg -y -i {0} -vcodec libx264 -acodec libfdk_aac -movflags faststart -pix_fmt yuv420p -profile:v baseline -level 3.0 -preset slower -crf 18 -vf " + filter_string + map_string + " {1}.mp4" ) skip_webm = False for s in self.processor_state["streams"]: if "info" in s: if "video_codec" in s["info"] and s["info"]["video_codec"] == "vp8": skip_webm = True if not skip_webm: self._execute( "ffmpeg -y -i {0} -c:v libvpx -c:a libvorbis -q:a 5 -pix_fmt yuv420p -quality good -b:v 5M -crf 5 -vf " + filter_string + map_string + " {1}.webm" ) # Extract extra streams if present fonts = [] extract_fonts = False if ( "has_fonts" in self.processor_state and "has_subtitles" in self.processor_state ): if ( self.processor_state["has_fonts"] or self.processor_state["has_subtitles"] ): for stream in self.processor_state["streams"]: if stream["type"] == "font": ext = _extension(stream["info"]) if ext in ["ttf", "otf"]: # Note that ffmpeg returns a nonzero exit code when dumping attachments because there's technically no output file # -dump_attachment is a mechanism completely removed from the rest of the ffmpeg workflow self._execute( "ffmpeg -y -dump_attachment:" + str(stream["index"]) + " {1}_attachment_" + str(len(fonts)) + "." + ext + " -i {0}", ignoreNonZero=True, ) fonts.append(stream) elif stream["type"] == "subtitle" and "info" in stream: extension = None if stream["info"]["codec_name"] == "ssa": extension = ".ass" extract_fonts = True elif stream["info"]["codec_name"] == "srt": extension = ".srt" elif stream["info"]["codec_name"] == "vtt": extension = ".vtt" if extension != None: self._execute("ffmpeg -y -i {0} -map 0:s:0 {1}" + extension) if extension == ".srt": # convert to vtt vtt = convert_to_vtt( os.path.join( _cfg("storage_folder"), "%s.srt" % self.f.hash ) ) with open( os.path.join( _cfg("storage_folder"), "%s.vtt" % self.f.hash ), "w", ) as f: f.write(vtt) os.remove( os.path.join( _cfg("storage_folder"), "%s.srt" % self.f.hash ) ) if extract_fonts: # Examine font files and construct some CSS to import them css = "" i = 0 for font in fonts: ext = _extension(font["info"]) if not ext in ["ttf", "otf"]: continue command = Invocation("otfinfo --info {0}") command( os.path.join( _cfg("storage_folder"), "%s_attachment_%s.%s" % (self.f.hash, i, _extension(font["info"])), ) ) command.run() output = command.stdout[0].split("\n") family = None subfamily = None for line in output: if line.startswith("Family:"): family = line[7:].strip(" \t") if line.startswith("Subfamily:"): subfamily = line[10:].strip(" \t") css += '@font-face{font-family: "%s";' % family css += 'src:url("/%s_attachment_%s.%s");' % ( self.f.hash, i, _extension(font["info"]), ) if subfamily == "SemiBold": css += "font-weight: 600;" elif subfamily == "Bold": css += "font-weight: bold;" elif subfamily == "Italic": css += "font-style: italic;" css += "}" i += 1 css_file = open( os.path.join(_cfg("storage_folder"), "%s_fonts.css" % self.f.hash), "w", ) css_file.write(css) css_file.close()
def detect_ffprobe(path): a = Invocation( 'ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}' ) a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout[0]) if result["format"]["nb_streams"] == 1: detected = detect_stream(result["streams"][0]) if detected != None: detected['metadata'] = ffprobe_addExtraMetadata( detected['metadata'], result) return detected audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 metadata = dict() for stream in result["streams"]: s = detect_stream(stream) # Set up some metadata if s['metadata'] != None: if 'duration' in s['metadata']: metadata['duration'] = s['metadata']['duration'] if 'dimensions' in s['metadata']: metadata['dimensions'] = s['metadata']['dimensions'] t = s['type'] if not s or not t: unknown_streams += 1 else: if t.startswith('image'): image_streams += 1 elif t == 'video': video_streams += 1 elif t == 'audio': audio_streams += 1 elif t == 'subtitle': subtitle_streams += 1 elif t == 'font': font_streams += 1 else: unknown_streams += 1 metadata = ffprobe_addExtraMetadata(metadata, result) if audio_streams == 1 and video_streams == 0: metadata['has_audio'] = True metadata['has_video'] = False return { 'type': 'audio', 'processor_state': { 'has_audio': True, 'has_video': False }, 'metadata': metadata, 'flags': None } if video_streams > 0: metadata['has_audio'] = audio_streams > 0 metadata['has_video'] = True return { 'type': 'video', 'processor_state': { 'has_audio': audio_streams > 0, 'has_video': True }, 'metadata': metadata, 'flags': { 'autoplay': False, 'loop': False, 'mute': False, } } return None
def detect_ffprobe(path): a = Invocation('ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}') a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout[0]) if result["format"]["nb_streams"] == 1: detected = detect_stream(result["streams"][0]) if detected != None: detected['metadata'] = ffprobe_addExtraMetadata(detected['metadata'], result) return detected audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 metadata = dict() for stream in result["streams"]: s = detect_stream(stream) # Set up some metadata if s['metadata'] != None: if 'duration' in s['metadata']: metadata['duration'] = s['metadata']['duration'] if 'dimensions' in s['metadata']: metadata['dimensions'] = s['metadata']['dimensions'] t = s['type'] if not s or not t: unknown_streams += 1 else: if t.startswith('image'): image_streams += 1 elif t == 'video': video_streams += 1 elif t == 'audio': audio_streams += 1 elif t == 'subtitle': subtitle_streams += 1 elif t == 'font': font_streams += 1 else: unknown_streams += 1 metadata = ffprobe_addExtraMetadata(metadata, result) if audio_streams == 1 and video_streams == 0: metadata['has_audio'] = True metadata['has_video'] = False return { 'type': 'audio', 'processor_state': { 'has_audio': True, 'has_video': False }, 'metadata': metadata, 'flags': None } if video_streams > 0: metadata['has_audio'] = audio_streams > 0 metadata['has_video'] = True return { 'type': 'video', 'processor_state': { 'has_audio': audio_streams > 0, 'has_video': True }, 'metadata': metadata, 'flags': { 'autoplay': False, 'loop': False, 'mute': False, } } return None
def detect_ffprobe(path): a = Invocation( "ffprobe -print_format json -loglevel quiet -show_format -show_streams {0}" ) a(path) a.run() if a.returncode or a.exited: return None result = json.loads(a.stdout) audio_streams = 0 video_streams = 0 image_streams = 0 subtitle_streams = 0 font_streams = 0 # We shouldn't penalize people for unknown streams, I just figured we could make a note of it unknown_streams = 0 metadata = dict() state = dict() flags = dict() state["streams"] = list() index = 0 for stream in result["streams"]: s = detect_stream(stream) if s == None: continue # Set up some metadata if s["metadata"] != None: if "duration" in s["metadata"]: metadata["duration"] = s["metadata"]["duration"] if "dimensions" in s["metadata"]: metadata["dimensions"] = s["metadata"]["dimensions"] t = s["type"] if not s or not t: unknown_streams += 1 else: state["streams"].append( {"type": t, "info": s["processor_state"], "index": index} ) if t.startswith("image"): image_streams += 1 elif t == "video": video_streams += 1 flags = s["flags"] elif t == "audio": audio_streams += 1 elif t == "subtitle": subtitle_streams += 1 elif t == "font": font_streams += 1 else: unknown_streams += 1 index += 1 metadata = ffprobe_addExtraMetadata(metadata, result) if audio_streams == 1 and video_streams == 0: metadata["has_audio"] = True metadata["has_video"] = False state["has_audio"] = True state["has_video"] = False return { "type": "audio", "processor_state": state, "metadata": metadata, "flags": None, } if video_streams > 0: metadata["has_audio"] = audio_streams > 0 metadata["has_video"] = True metadata["has_subtitles"] = subtitle_streams > 0 state["has_audio"] = audio_streams > 0 state["has_video"] = True state["has_fonts"] = font_streams > 0 state["has_subtitles"] = subtitle_streams > 0 if subtitle_streams > 0: metadata = addSubtitleInfo(metadata, state) if detect_interlacing(path): state["interlaced"] = True return { "type": "video", "processor_state": state, "metadata": metadata, "flags": flags, } return None