From 18d2e661d8fb5b2df98260563b637b6f89b95c6f Mon Sep 17 00:00:00 2001 From: clinton-hall Date: Thu, 26 Jun 2014 11:32:13 +0930 Subject: [PATCH] more definitive testing of isVideoGood. --- nzbtomedia/__init__.py | 20 +++---- nzbtomedia/autoProcess/autoProcessMovie.py | 2 +- nzbtomedia/autoProcess/autoProcessTV.py | 6 +-- nzbtomedia/transcoder/transcoder.py | 62 ++++++++++++---------- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/nzbtomedia/__init__.py b/nzbtomedia/__init__.py index a13959a8..a912b7cd 100644 --- a/nzbtomedia/__init__.py +++ b/nzbtomedia/__init__.py @@ -371,7 +371,7 @@ def initialize(section=None): transcode_defaults = { 'iPad':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':None, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -379,7 +379,7 @@ def initialize(section=None): }, 'iPad-1080p':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':'1920:1080','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':'1920:1080','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':None, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -387,7 +387,7 @@ def initialize(section=None): }, 'iPad-720p':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':None, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -395,7 +395,7 @@ def initialize(section=None): }, 'Apple-TV':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'ac3','ACODEC_ALLOW':['ac3'],'ABITRATE':None, 'ACODEC2':'libfaac','ACODEC2_ALLOW':['libfaac'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -403,7 +403,7 @@ def initialize(section=None): }, 'iPod':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':'1280:720','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':128000, 'ACODEC2':None,'ACODEC2_ALLOW':[],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -411,7 +411,7 @@ def initialize(section=None): }, 'iPhone':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':'460:320','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':'460:320','VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':128000, 'ACODEC2':None,'ACODEC2_ALLOW':[],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -419,7 +419,7 @@ def initialize(section=None): }, 'PS3':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'ac3','ACODEC_ALLOW':['ac3'],'ABITRATE':None, 'ACODEC2':'libfaac','ACODEC2_ALLOW':['libfaac'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -427,7 +427,7 @@ def initialize(section=None): }, 'Roku-480p':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':128000, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -435,7 +435,7 @@ def initialize(section=None): }, 'Roku-720p':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':128000, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, @@ -443,7 +443,7 @@ def initialize(section=None): }, 'Roku-1080p':{ 'VEXTENSION':'.mp4','VCODEC':'libx264','VPRESET':None,'VFRAMERATE':None,'VBITRATE':None, - 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'MPEG-4'], + 'VRESOLUTION':None,'VCODEC_ALLOW':['libx264', 'h264', 'h.264', 'AVC', 'avc', 'mpeg4', 'msmpeg4', 'MPEG-4'], 'ACODEC':'libfaac','ACODEC_ALLOW':['libfaac'],'ABITRATE':160000, 'ACODEC2':'ac3','ACODEC2_ALLOW':['ac3'],'ABITRATE2':None, 'ACODEC3':None,'ACODEC3_ALLOW2':[],'ABITRATE3':None, diff --git a/nzbtomedia/autoProcess/autoProcessMovie.py b/nzbtomedia/autoProcess/autoProcessMovie.py index 9b5958ca..53bb92ea 100644 --- a/nzbtomedia/autoProcess/autoProcessMovie.py +++ b/nzbtomedia/autoProcess/autoProcessMovie.py @@ -161,7 +161,7 @@ class autoProcessMovie: status = int(status) for video in listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False): num_files += 1 - if transcoder.isVideoGood(video): + if transcoder.isVideoGood(video, status): good_files += 1 if not release and not ".cp(tt" in video and imdbid: videoName, videoExt = os.path.splitext(video) diff --git a/nzbtomedia/autoProcess/autoProcessTV.py b/nzbtomedia/autoProcess/autoProcessTV.py index f23a6f16..f6f24fbb 100644 --- a/nzbtomedia/autoProcess/autoProcessTV.py +++ b/nzbtomedia/autoProcess/autoProcessTV.py @@ -91,7 +91,7 @@ class autoProcessTV: num_files = 0 for video in listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False): num_files += 1 - if transcoder.isVideoGood(video): + if transcoder.isVideoGood(video, status): good_files += 1 if num_files > 0: if good_files == num_files and not status == 0: @@ -108,7 +108,7 @@ class autoProcessTV: process_all_exceptions(inputName.lower(), dirName) inputName, dirName = convert_to_ascii(inputName, dirName) - # Now check if tv files exist in destination. Eventually extraction may be done here if nzbExtractionBy == TorrentToMedia + # Now check if tv files exist in destination. if listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False): # Check that a video exists. if not, assume failed. flatten(dirName) # to make sure SickBeard can find the video (not in sub-folder) elif listMediaFiles(dirName, media=False, audio=False, meta=False, archives=True): @@ -119,7 +119,7 @@ class autoProcessTV: num_files = 0 for video in listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False): num_files += 1 - if transcoder.isVideoGood(video): + if transcoder.isVideoGood(video, status): good_files += 1 if num_files > 0 and good_files == num_files: logger.info('Found Valid Videos. Setting status Success') diff --git a/nzbtomedia/transcoder/transcoder.py b/nzbtomedia/transcoder/transcoder.py index f06e4ff3..3a4a3cb5 100644 --- a/nzbtomedia/transcoder/transcoder.py +++ b/nzbtomedia/transcoder/transcoder.py @@ -10,47 +10,51 @@ from subprocess import call from nzbtomedia import logger from nzbtomedia.nzbToMediaUtil import makeDir -def isVideoGood(videofile): +def isVideoGood(videofile, status): fileNameExt = os.path.basename(videofile) fileName, fileExt = os.path.splitext(fileNameExt) - if fileExt not in nzbtomedia.MEDIACONTAINER: - return True + if fileExt not in nzbtomedia.MEDIACONTAINER or not nzbtomedia.FFPROBE: + if status: # if the download was "failed", assume bad. If it was successful, assume good. + return False + else: + return True - if platform.system() == 'Windows': - bitbucket = open('NUL') - else: - bitbucket = open('/dev/null') + logger.info('Checking [%s] for corruption, please stand by ...' % (fileNameExt), 'TRANSCODER') + video_details, result = getVideoDetails(videofile) - if not nzbtomedia.FFPROBE: - return True - - command = [nzbtomedia.FFPROBE, videofile] - try: - logger.info('Checking [%s] for corruption, please stand by ...' % (fileNameExt), 'TRANSCODER') - result = call(command, stdout=bitbucket, stderr=bitbucket) - except: - logger.error("Checking [%s] for corruption has failed" % (fileNameExt), 'TRANSCODER') - return False - - if result == 0: - logger.info("SUCCESS: [%s] has no corruption." % (fileNameExt), 'TRANSCODER') - return True - else: + if result != 0: logger.error("FAILED: [%s] is corrupted!" % (fileNameExt), 'TRANSCODER') return False + if video_details.get("error"): + logger.info("FAILED: [%s] returned error [%s]." % (fileNameExt, str(video_details.get("error"))), 'TRANSCODER') + return False + if video_details.get("streams"): + videoStreams = [item for item in video_details["streams"] if item["codec_type"] == "video"] + audioStreams = [item for item in video_details["streams"] if item["codec_type"] == "audio"] + if len(videoStreams) > 0 and len(audioStreams) > 0: + logger.info("SUCCESS: [%s] has no corruption." % (fileNameExt), 'TRANSCODER') + return True + else: + logger.info("FAILED: [%s] has %s video streams and %s audio streams. Assume corruption." % (fileNameExt, str(len(videoStreams)), str(len(audioStreams))), 'TRANSCODER') + return False + def getVideoDetails(videofile): video_details = {} + result = 1 if not nzbtomedia.FFPROBE: return video_details - command = [nzbtomedia.FFPROBE, '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', videofile] - proc = subprocess.Popen(command, stdout=subprocess.PIPE) - proc.wait() - video_details = json.loads(proc.stdout.read()) - return video_details + command = [nzbtomedia.FFPROBE, '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', '-show_error', videofile] + try: + proc = subprocess.Popen(command, stdout=subprocess.PIPE) + result = proc.wait() + video_details = json.loads(proc.stdout.read()) + except: + logger.error("Checking [%s] has failed" % (fileNameExt), 'TRANSCODER') + return video_details, result def buildCommands(file, newDir): - video_details = getVideoDetails(file) + video_details, result = getVideoDetails(file) dir, name = os.path.split(file) name, ext = os.path.splitext(name) if ext == nzbtomedia.VEXTENSION and newDir == dir: # we need to change the name to prevent overwriting itself. @@ -64,7 +68,7 @@ def buildCommands(file, newDir): sub_cmd = [] other_cmd = [] - if not video_details: # we couldn't read streams with ffprobe. Set defaults to try transcoding. + if not video_details or not video_details.get("streams"): # we couldn't read streams with ffprobe. Set defaults to try transcoding. videoStreams = [] audioStreams = [] subStreams = []