def __init__(self, filename): if(filename[0] != '/'): Log.w(TAG, "Filename is not absolute, this may cause issues dispatching jobs.") ffprobe = subprocess.Popen(["ffprobe","-v", "quiet", "-print_format", "json", "-show_format", "-show_streams",filename], stdout=subprocess.PIPE) #Get everything from stdout once ffprobe exits, and try: ffprobe_string = ffprobe.communicate()[0] self.ffprobe_dict=json.loads(ffprobe_string) except ValueError: Log.e(TAG, "File could not be read, are you sure it exists?") ffmpeg_interlace = subprocess.Popen(["ffmpeg", "-filter:v", "idet", "-frames:v", "400", "-an", "-f", "null", "-", "-i", filename],stdout=subprocess.PIPE, stderr=subprocess.PIPE) interlaced_details = ffmpeg_interlace.communicate()[1] interlaced_lines = interlaced_details.split("\n") num_progressive = 0 for line in interlaced_lines: if line.find("idet") != -1 and line.find("Progressive") != -1: #find the number of progressive frames in this line. nframes = line.split("Progressive:")[1].split("Undetermined")[0] num_progressive = num_progressive + int(nframes) if num_progressive < 20: self.is_interlaced = True self.video_stream = self.parse_video(self.ffprobe_dict) self.audio_streams = self.parse_audio(self.ffprobe_dict) self.sub_streams = self.parse_subs(self.ffprobe_dict) self.file_format = self.ffprobe_dict["format"]["format_name"] self.duration = float(self.ffprobe_dict["format"]["duration"])
def _ping(self): """ Ping the Docker Daemon :return: """ try: return self._client.ping() except ConnectionError as e: Log.e(e) Log.i("Docker Daemon became unresponsive") self._change_status(ManagerStatus.DISCONNECTED) return False
def _connect(self): try: Log.i("Attempt to contact Docker Daemon") self._change_status(ManagerStatus.ATTEMPT_CONNECT) self._client = DockerClient.from_env(**self._kwargs) self._last_ping = datetime.now() Log.i("Connected to Docker Daemon") self._change_status(ManagerStatus.CONNECTED) self.refresh_all() except DockerException as e: Log.e(e) self._stop = True self._change_status(ManagerStatus.DISCONNECTED)
def init_env(self, timeout=120, version='auto', env=None): kwargs = {'timeout': timeout, 'version': version, 'environment': env} try: self._client = DockerClient.from_env(**kwargs) version = self._client.api.version() DebugConsole.println('Environment loaded for %s' % env['DOCKER_HOST']) Log.i( 'Initialized communication using Docker Engine API version %s' % version['ApiVersion']) self._change_status(ManagerStatus.CONNECTED) self.refresh_all() Log.i('Loaded environment') except DockerException as e: print("DockerManager :: %s" % e) self._change_status(ManagerStatus.DISCONNECTED) DebugConsole.println('Docker Client could not load environment') Log.e('Docker Client could not load environment')
def run(self): Log.i("Manager Started [%s]" % self._env.name) while self._stop is not True: if self._status == ManagerStatus.DISCONNECTED: self._connect() time.sleep(2) if self._status == ManagerStatus.CONNECTED: diff = (datetime.now() - self._last_ping).total_seconds() if diff > 30: try: if self._ping(): self._last_ping = datetime.now() Log.i("Docker Daemon is responsive") except APIError as e: Log.e(e) Log.i("Docker Daemon became unresponsive") self._change_status(ManagerStatus.DISCONNECTED) self._close() Log.i("Manager stopped")
def __init__(self, filename): if (filename[0] != '/'): Log.w( TAG, "Filename is not absolute, this may cause issues dispatching jobs." ) ffprobe = subprocess.Popen([ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filename ], stdout=subprocess.PIPE) #Get everything from stdout once ffprobe exits, and try: ffprobe_string = ffprobe.communicate()[0] self.ffprobe_dict = json.loads(ffprobe_string) except ValueError: Log.e(TAG, "File could not be read, are you sure it exists?") ffmpeg_interlace = subprocess.Popen([ "ffmpeg", "-filter:v", "idet", "-frames:v", "400", "-an", "-f", "null", "-", "-i", filename ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) interlaced_details = ffmpeg_interlace.communicate()[1] interlaced_lines = interlaced_details.split("\n") num_progressive = 0 for line in interlaced_lines: if line.find("idet") != -1 and line.find("Progressive") != -1: #find the number of progressive frames in this line. nframes = line.split("Progressive:")[1].split( "Undetermined")[0] num_progressive = num_progressive + int(nframes) if num_progressive < 20: self.is_interlaced = True self.video_stream = self.parse_video(self.ffprobe_dict) self.audio_streams = self.parse_audio(self.ffprobe_dict) self.sub_streams = self.parse_subs(self.ffprobe_dict) self.file_format = self.ffprobe_dict["format"]["format_name"] self.duration = float(self.ffprobe_dict["format"]["duration"])
def handle_sql_error(self, error: QSqlError = None): """ Types: ConnectionError = 1 NoError = 0 StatementError = 2 TransactionError = 3 UnknownError = 4 :param error: :return: """ if error is not None: if error.type() == QSqlError.NoError: pass elif error.type() == QSqlError.ConnectionError: Log.e("SQL Error [Connection Error] - %s" % error.text()) elif error.type() == QSqlError.StatementError: Log.e("SQL Error [Statement Error] - %s" % error.text()) elif error.type() == QSqlError.TransactionError: Log.e("SQL Error [Transaction Error] - %s" % error.text()) else: Log.e("SQL Error [Unknown Error] - %s" % error.text())
def ffmpeg_tasks_create(parser, options): streams = media_transform(parser, options) if streams["video"] == False and streams["audio"] == False and streams[ "remux"] == False: return None ffmpeg = [] astreamindex = 0 for stream in streams["tcodeData"][::-1]: #Map the stream into the output. Order will be video, stereo, surround based on media_transform function, and iterating the list backwards. #Note that if we're using custom downconverting, then we can't map the regular channel - we need to build a filtergraph. if stream["type"] == "audio" and stream["ffprocdown"] == True: ffmpeg.append("-filter_complex") ffmpeg.append( "[0:" + str(stream["index"]) + "]pan=stereo| FL < FL + 0.7*FC + 0.3*BL + 0.3*SL | FR < FR + 0.7*FC + 0.3*BR + 0.3*SR, dynaudnorm[a]" ) ffmpeg.append("-map") ffmpeg.append("[a]") else: ffmpeg.append("-map") ffmpeg.append("0:" + str(stream["index"])) if stream["type"] == "video": ffmpeg.append("-c:v") codec_to_ffmpeg = stream["codec"] if codec_to_ffmpeg == "copy": ffmpeg.append("copy") elif codec_to_ffmpeg == "h264": #Behold, the insane list of arguments needed to tune h.264 for decent compression even ffmpeg.append("libx264") ffmpeg.append("-crf") ffmpeg.append(options["video"]["quality"]) ffmpeg.append("-level:v") ffmpeg.append("4.1") ffmpeg.append("-preset") ffmpeg.append(options["video"]["encodepreset"]) ffmpeg.append("-bf") ffmpeg.append("16") ffmpeg.append("-b_strategy") ffmpeg.append("2") ffmpeg.append("-subq") ffmpeg.append("10") ffmpeg.append("-refs") ffmpeg.append("4") elif codec_to_ffmpeg == "hevc": ffmpeg.append("libx265") ffmpeg.append("-crf") ffmpeg.append(options["video"]["quality"]) ffmpeg.append("-preset") ffmpeg.append(options["video"]["encodepreset"]) # fix for #16. Allows Apple devices to play hevc result files. ffmpeg.append("-tag:v") ffmpeg.append("hvc1") else: Log.e(TAG, "Unknown codec selected, you're on your own!") ffmpeg.append(stream["codec"]) if stream['10bit']: ffmpeg.append("-pix_fmt") ffmpeg.append("yuv420p10le") if stream["scaleopts"] != False and stream["deinterlacing"] == True: #Scaling and deinterlacing ffmpeg.append("-vf") ffmpeg.append("yadif=0:-1:0,scale=-1:" + str(stream["scaleopts"])) ffmpeg.append("-sws_flags") ffmpeg.append("lanczos") elif stream["scaleopts"] == False and stream[ "deinterlacing"] == True: #Just deinterlacing ffmpeg.append("-vf") ffmpeg.append("yadif=0:-1:0") elif stream["scaleopts"] != False and stream[ "deinterlacing"] == False: #Just scaling ffmpeg.append("-vf") ffmpeg.append("scale=-1:" + str(stream["scaleopts"])) ffmpeg.append("-sws_flags") ffmpeg.append("lanczos") else: #Nothing pass elif stream["type"] == "audio": ffmpeg.append("-c:a:" + str(astreamindex)) codec_to_ffmpeg = stream["codec"] if codec_to_ffmpeg == "copy": ffmpeg.append("copy") elif codec_to_ffmpeg == "aac": ffmpeg.append("libfdk_aac") ffmpeg.append("-b:a:" + str(astreamindex)) ffmpeg.append(stream["bitrate"]) else: Log.e(TAG, "Unknown codec selected, you're on your own!") ffmpeg.append(stream["codec"]) if stream["ffprocdown"] == False and stream["downconvert"] == True: #Use stock downconverting, not our own pan & dynaudnorm filter. ffmpeg.append("-ac:a:" + str(astreamindex)) ffmpeg.append("2") astreamindex = astreamindex + 1 if options["format"]["filetype"] == "mp4": ffmpeg.append("-movflags") ffmpeg.append("+faststart") ffmpeg.append("-map_metadata") ffmpeg.append("-1") task_type = TaskTypes.REMUX if streams["video"] == True: task_type = TaskTypes.VIDEO elif streams["audio"] == True: task_type = TaskTypes.AUDIO return Task(tasktype=task_type, command="ffmpeg", arguments=ffmpeg)
import re from util import Log from parser import Parser from task import Task, TaskTypes TAG = "ffproc" useredis = True try: from rq import Connection, Queue from redis import Redis except: useredis = False Log.e(TAG, "rq and redis libraries not found. Disabling redis support...") parser = argparse.ArgumentParser(description='Enqueue media files for transcoding, using a variety of profiles.') parser.add_argument('--profile', help='Force a particular profile') parser.add_argument('--immediate', action='store_true',help="Don't use Redis, just run the transcode immediately") parser.add_argument('--redis', default="127.0.0.1",nargs=1,type=str,help="Redis IP address, if not localhost") parser.add_argument('--showcommand', action='store_true',help='(debug) Show the FFMPEG command used') parser.add_argument('--dryrun', action='store_true',help='(debug) Stop short of actually enqueing the file') parser.add_argument('file', metavar='file', type=str, help='The file to transcode') arguments = parser.parse_args() if arguments.immediate == True:
from util import Log from MediaParser import Parser from task import Task, TaskTypes TAG = "ffproc" useredis = True try: from rq import Connection, Queue from redis import Redis except: useredis = False Log.e(TAG, "rq and redis libraries not found. Disabling redis support...") parser = argparse.ArgumentParser(description='Enqueue media files for transcoding, using a variety of profiles.') parser.add_argument('--profile', help='Force a particular profile') parser.add_argument('--immediate', action='store_true',help="Don't use Redis, just run the transcode immediately") parser.add_argument('--redis', default="127.0.0.1",nargs=1,type=str,help="Redis IP address, if not localhost") parser.add_argument('--showcommand', action='store_true',help='(debug) Show the FFMPEG command used') parser.add_argument('--dryrun', action='store_true',help='(debug) Stop short of actually enqueing the file') parser.add_argument('file', metavar='file', type=str, help='The file to transcode') arguments = parser.parse_args() if arguments.immediate == True:
def ffmpeg_tasks_create(parser, options): streams = media_transform(parser,options) if streams["video"]==False and streams["audio"]==False and streams["remux"]==False: return None ffmpeg=[] astreamindex = 0 for stream in streams["tcodeData"][::-1]: #Map the stream into the output. Order will be video, stereo, surround based on media_transform function, and iterating the list backwards. #Note that if we're using custom downconverting, then we can't map the regular channel - we need to build a filtergraph. if stream["type"] == "audio" and stream["ffprocdown"] == True: ffmpeg.append("-filter_complex") ffmpeg.append("[0:"+str(stream["index"])+"]pan=stereo| FL < FL + 0.7*FC + 0.3*BL + 0.3*SL | FR < FR + 0.7*FC + 0.3*BR + 0.3*SR, dynaudnorm[a]") ffmpeg.append("-map") ffmpeg.append("[a]") else: ffmpeg.append("-map") ffmpeg.append("0:"+str(stream["index"])) if stream["type"] == "video": ffmpeg.append("-c:v") codec_to_ffmpeg = stream["codec"] if codec_to_ffmpeg == "copy": ffmpeg.append("copy") elif codec_to_ffmpeg == "h264": #Behold, the insane list of arguments needed to tune h.264 for decent compression even ffmpeg.append("libx264") ffmpeg.append("-crf") ffmpeg.append(options["video"]["quality"]) ffmpeg.append("-level:v") ffmpeg.append("4.1") ffmpeg.append("-preset") ffmpeg.append(options["video"]["encodepreset"]) ffmpeg.append("-bf") ffmpeg.append("16") ffmpeg.append("-b_strategy") ffmpeg.append("2") ffmpeg.append("-subq") ffmpeg.append("10") ffmpeg.append("-refs") ffmpeg.append("4") elif codec_to_ffmpeg == "hevc": ffmpeg.append("libx265") ffmpeg.append("-crf") ffmpeg.append(options["video"]["quality"]) else: Log.e(TAG, "Unknown codec selected, you're on your own!") ffmpeg.append(stream["codec"]) if stream["scaleopts"] != False and stream["deinterlacing"] == True: #Scaling and deinterlacing ffmpeg.append("-vf") ffmpeg.append("yadif=0:-1:0,scale=-1:"+str(stream["scaleopts"])) ffmpeg.append("-sws_flags") ffmpeg.append("lanczos") elif stream["scaleopts"] == False and stream["deinterlacing"] == True: #Just deinterlacing ffmpeg.append("-vf") ffmpeg.append("yadif=0:-1:0") elif stream["scaleopts"] != False and stream["deinterlacing"] == False: #Just scaling ffmpeg.append("-vf") ffmpeg.append("scale=-1:"+str(stream["scaleopts"])) ffmpeg.append("-sws_flags") ffmpeg.append("lanczos") else: #Nothing pass elif stream["type"] == "audio": ffmpeg.append("-c:a:"+str(astreamindex)) codec_to_ffmpeg = stream["codec"] if codec_to_ffmpeg == "copy": ffmpeg.append("copy") elif codec_to_ffmpeg == "aac": ffmpeg.append("libfdk_aac") ffmpeg.append("-b:a:"+str(astreamindex)) ffmpeg.append(stream["bitrate"]) else: Log.e(TAG, "Unknown codec selected, you're on your own!") ffmpeg.append(stream["codec"]) if stream["ffprocdown"] == False and stream["downconvert"] == True: #Use stock downconverting, not our own pan & dynaudnorm filter. ffmpeg.append("-ac:a:"+str(astreamindex)) ffmpeg.append("2") astreamindex=astreamindex+1 task_type = TaskTypes.REMUX if streams["video"] == True: task_type = TaskTypes.VIDEO elif streams["audio"] == True: task_type = TaskTypes.AUDIO return Task(tasktype=task_type, command="ffmpeg", arguments=ffmpeg)