diff --git a/src/devede/avprobe.py b/src/devede/avprobe.py new file mode 100644 index 0000000..edc9e2c --- /dev/null +++ b/src/devede/avprobe.py @@ -0,0 +1,137 @@ +#!/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 devede.configuration_data +import devede.executor +import os +import json + +class avprobe(devede.executor.executor): + + 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): + + devede.executor.executor.__init__(self) + self.config = devede.configuration_data.configuration.get_config() + + def process_stdout(self,data): + return + + def process_stderr(self,data): + return + + def get_division(self,data): + pos = data.find("/") + pos2 = data.find(":") + + if (pos == -1): + pos = pos2 + + if (pos == -1): + return float(data) + else: + data1 = float(data[:pos]) + data2 = float(data[pos+1:]) + if (data2 == 0): + return 0 + else: + return data1 / data2 + + 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.audio_list=[] + self.audio_streams = 0 + self.video_list=[] + self.video_streams = 0 + self.original_width = 0 + self.original_height = 0 + self.original_length = 0 + self.original_videorate = 0 + self.original_audiorate = 0 + self.original_audiorate_uncompressed = 0 + self.original_fps = 0 + self.original_aspect_ratio = 0 + + self.original_file_size = os.path.getsize(file_name) + + command_line = ["avprobe",file_name,"-print_format","json","-show_streams", "-loglevel", "quiet"] + + (stdout, stderr) = self.launch_process(command_line, False) + try: + stdout2 = stdout.decode("utf-8") + except: + stdout2 = stdout.decode("latin1") + + try: + video_data = json.loads(stdout2) + except: + return True # There was an error reading the JSON data + + for element in video_data["streams"]: + 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"])) + self.original_length = int(float(element["duration"])) + self.original_videorate = int(float(element["bit_rate"]))/1000 + self.original_fps = self.get_division(element["avg_frame_rate"]) + 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): + 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 == 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 != 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 + + return False # no error diff --git a/src/devede/converter.py b/src/devede/converter.py index f77c5b8..b6b0420 100644 --- a/src/devede/converter.py +++ b/src/devede/converter.py @@ -18,7 +18,9 @@ import devede.configuration_data import devede.mplayer import devede.avconv +import devede.avprobe import devede.ffmpeg +import devede.ffprobe import devede.vlc import devede.brasero import devede.k3b @@ -41,7 +43,7 @@ class converter: self.config = devede.configuration_data.configuration.get_config() # List of classes with conversion capabilities, in order of preference - self.c = [devede.vlc.vlc, devede.mpv.mpv, devede.ffmpeg.ffmpeg, devede.avconv.avconv, + self.c = [devede.vlc.vlc, devede.mpv.mpv, devede.ffmpeg.ffmpeg, devede.ffprobe.ffprobe, devede.avconv.avconv, devede.avprobe.avprobe, devede.brasero.brasero, devede.k3b.k3b, devede.mkisofs.mkisofs, devede.genisoimage.genisoimage, devede.mplayer.mplayer] self.analizers = {} diff --git a/src/devede/ffprobe.py b/src/devede/ffprobe.py new file mode 100644 index 0000000..e07dade --- /dev/null +++ b/src/devede/ffprobe.py @@ -0,0 +1,137 @@ +#!/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 devede.configuration_data +import devede.executor +import os +import json + +class ffprobe(devede.executor.executor): + + supports_analize = True + supports_play = False + supports_convert = False + supports_menu = False + supports_mkiso = False + supports_burn = False + display_name = "FFPROBE" + + @staticmethod + def check_is_installed(): + try: + handle = subprocess.Popen(["ffprobe","-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): + + devede.executor.executor.__init__(self) + self.config = devede.configuration_data.configuration.get_config() + + def process_stdout(self,data): + return + + def process_stderr(self,data): + return + + def get_division(self,data): + pos = data.find("/") + pos2 = data.find(":") + + if (pos == -1): + pos = pos2 + + if (pos == -1): + return float(data) + else: + data1 = float(data[:pos]) + data2 = float(data[pos+1:]) + if (data2 == 0): + return 0 + else: + return (float(int((data1 / data2)*1000.0)))/1000.0 + + 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.audio_list=[] + self.audio_streams = 0 + self.video_list=[] + self.video_streams = 0 + self.original_width = 0 + self.original_height = 0 + self.original_length = 0 + self.original_videorate = 0 + self.original_audiorate = 0 + self.original_audiorate_uncompressed = 0 + self.original_fps = 0 + self.original_aspect_ratio = 0 + + self.original_file_size = os.path.getsize(file_name) + + command_line = ["ffprobe",file_name,"-print_format","json","-show_streams", "-loglevel", "quiet"] + + (stdout, stderr) = self.launch_process(command_line, False) + try: + stdout2 = stdout.decode("utf-8") + except: + stdout2 = stdout.decode("latin1") + + try: + video_data = json.loads(stdout2) + except: + return True # There was an error reading the JSON data + + for element in video_data["streams"]: + 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"])) + self.original_length = int(float(element["duration"])) + self.original_videorate = int(float(element["bit_rate"]))/1000 + self.original_fps = self.get_division(element["avg_frame_rate"]) + 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): + 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 == 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 != 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 + + return False # no error diff --git a/src/devede/file_movie.py b/src/devede/file_movie.py index 234ea6a..3c50b58 100644 --- a/src/devede/file_movie.py +++ b/src/devede/file_movie.py @@ -142,6 +142,7 @@ class file_movie(devede.interface_manager.interface_manager): if (film_analizer.get_film_data(self.file_name)): self.error = True else: + self.error = False self.audio_list = film_analizer.audio_list self.video_list = film_analizer.video_list self.audio_streams = film_analizer.audio_streams @@ -176,8 +177,6 @@ class file_movie(devede.interface_manager.interface_manager): self.aspect_ratio_final = None self.converted_filename = None - self.error = False - def set_title(self,new_title): self.title_name = new_title