#!/usr/bin/env python3 # Copyright 2014 (C) Raster Software Vigo (Sergio Costas) # # This file is part of DeVeDe-NG # # DeVeDe-NG is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # DeVeDe-NG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see import subprocess import devedeng.configuration_data import devedeng.executor import os import json class avprobe(devedeng.avbase.avbase): supports_analize = True supports_play = False supports_convert = False supports_menu = False supports_mkiso = False supports_burn = False display_name = "AVPROBE" @staticmethod def check_is_installed(): try: handle = subprocess.Popen( ["avprobe", "-h"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = handle.communicate() if 0 == handle.wait(): return True else: return False except: return False def __init__(self): devedeng.executor.executor.__init__(self) self.config = devedeng.configuration_data.configuration.get_config() def process_stdout(self, data): return def process_stderr(self, data): return def get_film_data(self, file_name): """ processes a file, refered by the FILE_MOVIE movie object, and fills its main data (resolution, FPS, length...) """ self.original_file_size = os.path.getsize(file_name) command_line = ["avprobe", file_name, "-of", "json", "-show_streams", "-loglevel", "quiet"] (stdout, stderr) = self.launch_process(command_line, False) try: stdout2 = stdout.decode("utf-8") except: stdout2 = stdout.decode("latin1") self.config.append_static_log("AVProbe JSON data: " + str(stdout2)) return self.process_json(stdout2, file_name) def process_json(self, stdout2, file_name): self.audio_list = [] self.audio_streams = 0 self.video_list = [] self.video_streams = 0 self.original_width = 0 self.original_height = 0 self.original_length = -1 self.original_videorate = 0 self.original_audiorate = 0 self.original_audiorate_uncompressed = 0 self.original_fps = 0 self.original_aspect_ratio = 0 self.config.append_static_log( "Getting data for {:s} with avprobe".format(file_name)) try: video_data = json.loads(stdout2) except: return True # There was an error reading the JSON data if not("streams" in video_data): return True # There are no streams!!!!! for element in video_data["streams"]: if (self.original_length == -1) and ("duration" in element): try: self.original_length = int(float(element["duration"])) except: self.original_length = -1 if (element["codec_type"] == "video"): self.video_streams += 1 self.video_list.append(element["index"]) if (self.video_streams == 1): self.original_width = int(float(element["width"])) self.original_height = int(float(element["height"])) if ("bit_rate" in element): self.original_videorate = int( float(element["bit_rate"])) / 1000 self.original_fps = self.get_division( element["avg_frame_rate"]) if ("display_aspect_ratio" in element): self.original_aspect_ratio = self.get_division( element["display_aspect_ratio"]) elif (element["codec_type"] == "audio"): self.audio_streams += 1 self.audio_list.append(element["index"]) if (self.audio_streams == 1): if ("bit_rate" in element): self.original_audiorate = int( float(element["bit_rate"])) / 1000 self.original_audiorate_uncompressed = int( float(element["sample_rate"])) self.original_size = str(self.original_width) + \ "x" + str(self.original_height) if (self.original_aspect_ratio is None) or (self.original_aspect_ratio <= 1.0): if (self.original_height != 0): self.original_aspect_ratio = ( float(self.original_width)) / (float(self.original_height)) if (self.original_aspect_ratio is not None): self.original_aspect_ratio = ( float(int(self.original_aspect_ratio * 1000.0))) / 1000.0 if (len(self.video_list) == 0): return True # the file is not a video file; maybe an audio-only file or another thing if self.original_length == -1: # if it was unable to detect the duration, try to use the human readable format command_line = ["avprobe", file_name] (stdout, stderr) = self.launch_process(command_line, False) try: stdout2 = stdout.decode("utf-8") + \ "\n" + stderr.decode("utf-8") except: stdout2 = stdout.decode("latin1") + \ "\n" + stderr.decode("latin1") self.config.append_static_log( "Using avprobe human readable format: " + str(stdout2)) for line in stdout2.split("\n"): line = line.strip() if line.startswith("Duration: "): self.original_length = self.get_time(line[10:]) break self.config.append_static_log("Estimated length: {:d}; Resolution: {:s}".format( self.original_length, self.original_size)) return False # no error