def ffprobe(buf, extension=None, flat=True): """ Returns a dict based on the json output of ffprobe. If ``flat`` is ``True``, the 'format' key-values are made top-level, as well as the first video stream in the file (the rest are discarded). Any 'stream' keys that have the same name as a key in 'format' are prefixed with ``stream_``. """ global FFPROBE_PATH if FFPROBE_PATH is None: FFPROBE_PATH = which('ffprobe') if FFPROBE_PATH is None: raise FFmpegError("Could not find ffprobe executable") with named_tmp_file(data=buf, extension=extension) as input_file: command = [ FFPROBE_PATH, '-hide_banner', '-loglevel', 'fatal', '-show_error', '-show_format', '-show_streams', '-print_format', 'json', '-i', input_file, ] proc = Popen(command, stdout=PIPE, stdin=PIPE, stderr=PIPE) stdout, stderr = proc.communicate() try: probe_data = json.loads(stdout) except ValueError: probe_data = None if not isinstance(probe_data, dict): raise FFmpegError("ffprobe returned invalid data") if 'error' in probe_data: raise FFmpegError("%(string)s (%(code)s)" % probe_data['error']) if 'format' not in probe_data or 'streams' not in probe_data: raise FFmpegError("ffprobe returned invalid data") if not flat: return probe_data try: video_stream = next(s for s in probe_data['streams'] if s['codec_type'] == 'video') except StopIteration: raise FFmpegError("File is missing a video stream") data = probe_data['format'] for k, v in six.iteritems(video_stream): if k in data: k = 'stream_%s' % k data[k] = v return data
def run_cmd(self, command): logger.debug("Running `%s`" % " ".join(command)) proc = Popen(command, stdout=PIPE, stdin=PIPE, stderr=PIPE) proc.command = command stdout, stderr = proc.communicate() logger.debug(stderr) if proc.returncode == 0: return stdout else: err_msg = "%s => %s" % (" ".join(command), proc.returncode) err_msg += "\n%s" % stderr if self.context.request: err_msg += "\n%s" % self.context.request.url raise FFmpegError(err_msg)
def transcode(self, extension): if getattr(self.context.request, 'format', None): out_format = self.context.request.format if out_format in ('hevc', 'h264', 'h265'): extension = '.mp4' self.context.request.format = 'mp4' else: out_format = FORMATS[extension] with self.make_src_file(extension) as src_file: if out_format == 'webp': return self.transcode_to_webp(src_file) elif out_format in ('webm', 'vp9'): return self.transcode_to_vp9(src_file) elif out_format in ('mp4', 'h264'): return self.transcode_to_h264(src_file) elif out_format in ('hevc', 'h265'): return self.transcode_to_h265(src_file) elif out_format == 'gif': return self.transcode_to_gif(src_file) else: raise FFmpegError("Invalid video format '%s' requested" % out_format)