示例#1
0
    def QTFS(self, inputfile):
        input_dir, filename, input_extension = self.parseFile(inputfile)
        temp_ext = '.QTFS'
        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if self.parseFile(
                inputfile)[2] in valid_output_extensions and os.path.isfile(
                    inputfile) and self.relocate_moov:
            print "Relocating MOOV atom to start of file"
            outputfile = inputfile + temp_ext

            # Clear out the temp file if it exists
            self.removeFile(outputfile, 0, 0)

            try:
                processor.process(inputfile, outputfile)
                os.chmod(outputfile, 0777)
                # Cleanup
                if self.removeFile(inputfile, replacement=outputfile):
                    print 'Temporary file %s deleted' % (inputfile)
                    return outputfile
                else:
                    print "Error cleaning up QTFS temp files"
                    return False
            except exceptions.FastStartException:
                print "QT FastStart did not run - perhaps moov atom was at the start already"
                return inputfile
示例#2
0
    def process(cls, inputfile):
        pathelements = helpers.breakdown(inputfile)
        temp_ext = '.QTFS'

        if not os.path.exists(inputfile):
            raise IOError(f'{inputfile} does not exist')

        if pathelements['extension'] in cls.supported_extensions:
            from qtfaststart import processor, exceptions

            log.info("Relocating MOOV atom to start of file.")

            outputfile = inputfile + temp_ext

            if os.path.exists(outputfile):
                os.remove(outputfile)

            try:
                processor.process(inputfile, outputfile)
            except exceptions.FastStartException:
                log.warning("QT FastStart did not run - perhaps moov atom was at the start already.")

            if outputfile:
                os.remove(inputfile)
                os.rename(outputfile, inputfile)
示例#3
0
def download(url):
    global ydl
    global active_urls
    if url in active_urls:
        print("Double download attempt. Blocking.")
        return
    active_urls.append(url)
    print(url)
    try:
        info_dict = ydl.extract_info(url, download=False)
        filename = ydl.prepare_filename(info_dict)
        filename = filename.encode('UTF-8')

        if os.path.isfile(filename):
            print("File already downloaded")
            return ""
        ydl.download([url])

        tmp, outfile = tempfile.mkstemp(dir=TMP_PATH)
        os.close(tmp)

        try:
            processor.process(VID_PATH + filename, outfile)
            shutil.move(outfile, VID_PATH + filename)
        except exceptions.FastStartException:
            # stupid library throws exception if file is already setup properly
            print("Ignoring moov failure for already setup file")
        log("Downloaded " + url + '\n')

    except Exception as e:
        log("FAILED " + url + '. Reason: ' + str(e) + '\n')
        log(traceback.format_exc())

    active_urls.remove(url)
示例#4
0
    def QTFS(self, inputfile):
        input_dir, filename, input_extension = self.parseFile(inputfile)
        temp_ext = '.QTFS'
        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if self.parseFile(inputfile)[2] in valid_output_extensions and os.path.isfile(inputfile) and self.relocate_moov:
            from qtfaststart import processor, exceptions

            self.log.info("Relocating MOOV atom to start of file.")

            try:
                outputfile = inputfile.decode(sys.getfilesystemencoding()) + temp_ext
            except:
                outputfile = inputfile + temp_ext

            # Clear out the temp file if it exists
            if os.path.exists(outputfile):
                self.removeFile(outputfile, 0, 0)

            try:
                processor.process(inputfile, outputfile)
                try:
                    os.chmod(outputfile, self.permissions)
                except:
                    self.log.exception("Unable to set file permissions.")
                # Cleanup
                if self.removeFile(inputfile, replacement=outputfile):
                    return outputfile
                else:
                    self.log.error("Error cleaning up QTFS temp files.")
                    return False
            except exceptions.FastStartException:
                self.log.warning("QT FastStart did not run - perhaps moov atom was at the start already.")
                return inputfile
    def QTFS(self, inputfile):
        input_dir, filename, input_extension = self.parseFile(inputfile)
        temp_ext = ".QTFS"
        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if self.parseFile(inputfile)[2] in valid_output_extensions and os.path.isfile(inputfile) and self.relocate_moov:
            from qtfaststart import processor, exceptions

            self.log.info("Relocating MOOV atom to start of file.")

            try:
                outputfile = inputfile.decode(sys.getfilesystemencoding()) + temp_ext
            except:
                outputfile = inputfile + temp_ext

            # Clear out the temp file if it exists
            if os.path.exists(outputfile):
                self.removeFile(outputfile, 0, 0)

            try:
                processor.process(inputfile, outputfile)
                try:
                    os.chmod(outputfile, self.permissions)
                except:
                    self.log.exception("Unable to set file permissions.")
                # Cleanup
                if self.removeFile(inputfile, replacement=outputfile):
                    return outputfile
                else:
                    self.log.error("Error cleaning up QTFS temp files.")
                    return False
            except exceptions.FastStartException:
                self.log.warning("QT FastStart did not run - perhaps moov atom was at the start already.")
                return inputfile
示例#6
0
    def trancodeRawVideo(self, source_path, target_path, video_params,
                         video_target_size):
        sourceAspect = float(video_params['width']) / float(
            video_params['height'])
        targetAspect = float(video_target_size[0]) / float(
            video_target_size[1])

        if sourceAspect > targetAspect:
            output_width = video_target_size[0]
            output_height = (float(video_target_size[0]) / float(
                video_params['width'])) * float(video_params['height'])
        else:
            output_height = video_target_size[1]
            output_width = (float(video_target_size[1]) / float(
                video_params['height'])) * float(video_params['width'])

        output_width = int(math.floor(float(output_width) / 2.0) * 2.0)
        output_height = int(math.floor(float(output_height) / 2.0) * 2.0)

        # 1 = clockwise 90, 2 = counter clockwise 90
        # if filename contains r90 then transpose=1
        # if filename contains r270 then transpose=2
        extraargs = []
        if source_path.find("r90") != -1:
            extraargs = ["-vf", "transpose=1"]
        elif source_path.find("r270") != -1:
            extraargs = ["-vf", "transpose=2"]

        print output_width, output_height
        print "aspects:", sourceAspect, targetAspect

        path, filename = os.path.split(target_path)
        tmpfile = os.path.join(path, "tmp_%s" % filename)
        transcodeArgs = [
            self.getFFMpeg(), "-y", "-i", source_path, "-s",
            "%sx%s" % (output_width, output_height), "-r", "25", "-b", "2M",
            "-bt", "4M", "-acodec", "libfaac", "-ar", "44100", "-ab", "96k",
            "-vcodec", "libx264", "-preset", "medium", "-sameq"
        ]
        transcodeArgs.extend(extraargs)
        transcodeArgs.append(tmpfile)

        process = subprocess.Popen(transcodeArgs,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT)

        while True:
            out = process.stdout.read(1)
            if out == '' and process.poll() is not None:
                break
            if out != '':
                sys.stdout.write(out)
                sys.stdout.flush()

        processor.process(tmpfile, target_path)
        os.remove(tmpfile)
示例#7
0
    def optimize(self, file=False):

        if not file:
            file = self.config['temp'] if "temp" in self.config else self.config['file']
            file = os.path.join(file['path'], file['name'])
        try:
            processor.process(file, file)
        except FastStartException:
            # A log message was printed, so exit with an error code
            raise SystemExit(1)
示例#8
0
    def process(self):
        if not self.savepath:
            raise Exception('video file not saved')
        fname, ext = os.path.splitext(self.savepath)
        newmp4path = '%s_%s%s'%(fname, ''.join([choice(string.digits) for i in range(3)]), '.mp4')
        self.newmp4path = newmp4path

        self.convert_tomp4()
        if not self.finalpath:
            finalpath = self.get_final_path()
            self.finalpath = finalpath
        # self.newmp4path
        # self.finalpath
        processor.process(self.newmp4path, self.finalpath, limit = 32*(1024**2))

        self.get_thumbnail()
示例#9
0
    def trancodeRawVideo(self,source_path,target_path,video_params,video_target_size):
        sourceAspect=float(video_params['width'])/float(video_params['height'])
        targetAspect=float(video_target_size[0])/float(video_target_size[1])

        if sourceAspect>targetAspect:
            output_width=video_target_size[0]
            output_height=(float(video_target_size[0])/float(video_params['width']))*float(video_params['height'])
        else:
            output_height=video_target_size[1]
            output_width=(float(video_target_size[1])/float(video_params['height']))*float(video_params['width'])

        output_width=int(math.floor(float(output_width)/2.0)*2.0)
        output_height=int(math.floor(float(output_height)/2.0)*2.0)

        # 1 = clockwise 90, 2 = counter clockwise 90
        # if filename contains r90 then transpose=1
        # if filename contains r270 then transpose=2
        extraargs=[]
        if source_path.find("r90")!=-1:
            extraargs=["-vf","transpose=1"]
        elif source_path.find("r270")!=-1:
            extraargs=["-vf","transpose=2"]


        print output_width,output_height
        print "aspects:",sourceAspect,targetAspect

        path,filename=os.path.split(target_path)
        tmpfile=os.path.join(path,"tmp_%s"%filename)
        transcodeArgs=[self.getFFMpeg(),"-y","-i",source_path,"-s","%sx%s"%(output_width,output_height),"-r","25","-b","2M","-bt","4M","-acodec","libfaac","-ar","44100","-ab","96k","-vcodec","libx264","-preset","medium","-sameq"]
        transcodeArgs.extend(extraargs)
        transcodeArgs.append(tmpfile)
        
        process = subprocess.Popen(transcodeArgs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        while True:
            out = process.stdout.read(1)
            if out == '' and process.poll() != None:
                break
            if out != '':
                sys.stdout.write(out)
                sys.stdout.flush()

        processor.process(tmpfile,target_path)
        os.remove(tmpfile)
示例#10
0
    def process(self):
        if not self.savepath:
            raise Exception('video file not saved')
        fname, ext = os.path.splitext(self.savepath)
        newmp4path = '%s_%s%s' % (fname, ''.join(
            [choice(string.digits) for i in range(3)]), '.mp4')
        self.newmp4path = newmp4path

        self.convert_tomp4()
        if not self.finalpath:
            finalpath = self.get_final_path()
            self.finalpath = finalpath
        # self.newmp4path
        # self.finalpath
        processor.process(self.newmp4path,
                          self.finalpath,
                          limit=32 * (1024**2))

        self.get_thumbnail()
示例#11
0
文件: transcode.py 项目: dsully/trax
def transcode(dst_file, dst_codec, src_file, src_codec=None):
    """ Transcode one audio file to another. """

    if dst_codec not in TRANSCODE_MAP:
        raise ValueError("Couldn't find the %s codec in the transcode map!")

    if src_codec and src_codec == dst_codec:
        dst_codec = 'copy'

    # ffmpeg can do the decode & encode in one shot
    command = [
        'ffmpeg', '-y', '-loglevel', 'quiet', '-i', src_file, '-map', '0:0',
        '-ac', '2', '-acodec', TRANSCODE_MAP[dst_codec], dst_file
    ]

    path = os.path.dirname(dst_file)

    if not os.path.exists(path):
        os.makedirs(path)

    popen = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
    popen.communicate()

    # Set the MP4 to be optimized for streaming.
    if dst_codec in ('alac', 'aac'):

        try:
            temp_file = dst_file + '.tmp'
            processor.process(dst_file, temp_file, limit=0)

            if os.path.exists(temp_file):
                shutil.move(temp_file, dst_file)
            else:
                log.error("Couldn't mark [%s] as streaming/fast start.",
                          dst_file)

        except FastStartException:
            log.error("Couldn't mark [%s] as streaming/fast start.", dst_file)

    return popen.returncode
示例#12
0
 def getExtensionMessage(self, extension):
     message = ""
     fileCanStream = False
     filename = os.path.join(plugin.get_setting("dlpath"), self.display_name)
     isFile = os.path.isfile(filename)
     if isFile:
         fileCanStream = processor.process(filename, filename);
         if (extension == ".mp4" or extension == ".m4v") and isFile and fileCanStream:
             message = ""                   
         elif (extension == ".mp4" or extension == ".m4v") and isFile and fileCanStream == False:
             message = "File can not fast start. The whole file must download."
     return message
示例#13
0
def download(url):
    f = open(os.path.join(original_path, "log.txt"), "a")
    try:
        info_dict = ydl.extract_info(url, download=False)
        filename = ydl.prepare_filename(info_dict)
        if os.path.isfile(filename):
            print "File already downloaded"
            return ""
        ydl.download([url])
        tmp, outfile = tempfile.mkstemp(dir=TMP_PATH)
        os.close(tmp)
        try:
            processor.process(VID_PATH + filename, outfile)
            shutil.move(outfile, VID_PATH + filename)
        except exceptions.FastStartException:
            # stupid library throws exception if file is already setup properly
            print "Ignoring moov failure for already setup file"
        f.write("Downloaded " + url + '\n')
    except Exception as e:
        f.write("FAILED " + url + ' . because ' + e.message + '\n')
    f.close()
    def QTFS(self, inputfile):
        input_dir, filename, input_extension = self.parseFile(inputfile)
        temp_ext = '.QTFS'
        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if self.parseFile(inputfile)[2] in valid_output_extensions and os.path.isfile(inputfile) and self.relocate_moov:
            print "Relocating MOOV atom to start of file"
            outputfile = inputfile.decode(sys.getfilesystemencoding()) + temp_ext

            # Clear out the temp file if it exists
            self.removeFile(outputfile, 0, 0)

            try:
                processor.process(inputfile, outputfile)
                os.chmod(outputfile, 0777)
                # Cleanup
                if self.removeFile(inputfile, replacement=outputfile):
                    return outputfile
                else:
                    print "Error cleaning up QTFS temp files"
                    return False
            except exceptions.FastStartException:
                print "QT FastStart did not run - perhaps moov atom was at the start already"
                return inputfile
示例#15
0
 def getExtensionMessage(self, extension):
     dlpath = plugin.get_setting("dlpath")
     if dlpath == "":
         dlpath = torrent2http.get_binary_dir() #default download path
     message = ""
     fileCanStream = False
     filename = (os.path.join(dlpath, self.display_name)).encode("utf-8")
     isFile = os.path.isfile(filename)
     if isFile:
         fileCanStream = processor.process(filename, filename);
         if (extension == ".mp4" or extension == ".m4v") and isFile and fileCanStream:
             message = ""                   
         elif (extension == ".mp4" or extension == ".m4v") and isFile and fileCanStream == False:
             message = "File can not fast start. The whole file must download."
     return message
示例#16
0
文件: transcode.py 项目: dsully/trax
def transcode(dst_file, dst_codec, src_file, src_codec=None):
  """ Transcode one audio file to another. """

  if dst_codec not in TRANSCODE_MAP:
    raise ValueError("Couldn't find the %s codec in the transcode map!")

  if src_codec and src_codec == dst_codec:
    dst_codec = 'copy'

  # ffmpeg can do the decode & encode in one shot
  command = ['ffmpeg', '-y', '-loglevel', 'quiet', '-i', src_file, '-map', '0:0', '-ac', '2', '-acodec', TRANSCODE_MAP[dst_codec], dst_file]

  path = os.path.dirname(dst_file)

  if not os.path.exists(path):
    os.makedirs(path)

  popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  popen.communicate()

  # Set the MP4 to be optimized for streaming.
  if dst_codec in ('alac', 'aac'):

    try:
      temp_file = dst_file + '.tmp'
      processor.process(dst_file, temp_file, limit=0)

      if os.path.exists(temp_file):
        shutil.move(temp_file, dst_file)
      else:
        log.error("Couldn't mark [%s] as streaming/fast start.", dst_file)

    except FastStartException:
      log.error("Couldn't mark [%s] as streaming/fast start.", dst_file)

  return popen.returncode
示例#17
0
def run():
    logging.basicConfig(level=logging.INFO,
                        stream=sys.stdout,
                        format="%(message)s")

    parser = OptionParser(usage="%prog [options] infile [outfile]",
                          version="%prog " + VERSION)

    parser.add_option("-d",
                      "--debug",
                      dest="debug",
                      default=False,
                      action="store_true",
                      help="Enable debug output")
    parser.add_option("-l",
                      "--list",
                      dest="list",
                      default=False,
                      action="store_true",
                      help="List top level atoms")
    parser.add_option("-e",
                      "--to_end",
                      dest="to_end",
                      default=False,
                      action="store_true",
                      help="Move moov atom to the end of file")
    parser.add_option("-s",
                      "--sample",
                      dest="sample",
                      default=False,
                      action="store_true",
                      help="Create a small sample of the input file")

    options, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        raise SystemExit(1)

    if options.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    if options.list:
        index = processor.get_index(open(args[0], "rb"))

        for atom, pos, size in index:
            if atom == "\x00\x00\x00\x00":
                # Strange zero atom... display with dashes rather than
                # an empty string
                atom = "----"

            print(atom, "(" + str(size) + " bytes)")

        raise SystemExit

    if len(args) == 1:
        # Replace the original file!
        if options.sample:
            print("Please pass an output filename when used with --sample!")
            raise SystemExit(1)

        tmp, outfile = tempfile.mkstemp()
        os.close(tmp)
    else:
        outfile = args[1]

    limit = 0
    if options.sample:
        # Create a small sample (4 MiB)
        limit = 4 * (1024**2)

    try:
        processor.process(args[0], outfile, limit=limit, to_end=options.to_end)
    except FastStartException:
        # A log message was printed, so exit with an error code
        raise SystemExit(1)

    if len(args) == 1:
        # Move temp file to replace original
        shutil.move(outfile, args[0])
示例#18
0
def run():
    logging.basicConfig(level = logging.INFO, stream = sys.stdout,
                        format = "%(message)s")

    parser = OptionParser(usage="%prog [options] infile [outfile]",
                          version="%prog " + VERSION)

    parser.add_option("-d", "--debug", dest="debug", default=False,
                      action="store_true",
                      help="Enable debug output")
    parser.add_option("-l", "--list", dest="list", default=False,
                      action="store_true",
                      help="List top level atoms")
    parser.add_option("-s", "--sample", dest="sample", default=False,
                      action="store_true",
                      help="Create a small sample of the input file")

    options, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        raise SystemExit(1)

    if options.debug:
        logging.getLogger().setLevel(logging.DEBUG)

    if options.list:
        index = processor.get_index(open(args[0], "rb"))

        for atom, pos, size in index:
            if atom == "\x00\x00\x00\x00":
                # Strange zero atom... display with dashes rather than
                # an empty string
                atom = "----"

            print(atom, "(" + str(size) + " bytes)")

        raise SystemExit

    if len(args) == 1:
        # Replace the original file!
        if options.sample:
            print("Please pass an output filename when used with --sample!")
            raise SystemExit(1)

        tmp, outfile = tempfile.mkstemp()
        os.close(tmp)
    else:
        outfile = args[1]

    limit = 0
    if options.sample:
        # Create a small sample (4 MiB)
        limit = 4 * (1024 ** 2)

    try:
        processor.process(args[0], outfile, limit = limit)
    except FastStartException:
        # A log message was printed, so exit with an error code
        raise SystemExit(1)

    if len(args) == 1:
        # Move temp file to replace original
        shutil.move(outfile, args[0])
示例#19
0
    def __init__(self,
                 file,
                 FFMPEG_PATH="FFMPEG.exe",
                 FFPROBE_PATH="FFPROBE.exe",
                 delete=True,
                 output_extension='mp4',
                 relocate_moov=True,
                 video_codec='h264',
                 audio_codec='aac',
                 audio_bitrate=None,
                 iOS=False,
                 awl=None,
                 swl=None,
                 adl=None,
                 sdl=None):
        #Get path information from the input file
        output_dir, filename = os.path.split(file)
        filename, input_extension = os.path.splitext(filename)
        input_extension = input_extension[1:]

        c = Converter(FFMPEG_PATH, FFPROBE_PATH)
        # Get values for width and height to be passed to the tagging classes for proper HD tags
        info = c.probe(file)
        self.height = info.video.video_height
        self.width = info.video.video_width
        # Make sure input and output extensions are compatible
        if input_extension in valid_input_extensions and output_extension in valid_output_extensions:
            #Video stream
            print "Video codec detected: " + info.video.codec
            vcodec = 'copy' if info.video.codec == video_codec else video_codec

            #Audio streams
            audio_settings = {}
            l = 0
            for a in info.audio:
                print "Audio stream detected: " + a.codec + " " + a.language + " [Stream " + str(
                    a.index) + "]"
                # Set undefined language to default language if specified
                if adl is not None and a.language == 'und':
                    print "Undefined language detected, defaulting to " + adl
                    a.language = adl
                # Proceed if no whitelist is set, or if the language is in the whitelist
                if awl is None or a.language in awl:
                    # Create iOS friendly audio stream if the default audio stream has too many channels (iOS only likes AAC stereo)
                    if iOS and a.audio_channels > 2:
                        print "Creating dual audio channels for iOS compatability for this stream"
                        audio_settings.update({
                            l: {
                                'map': a.index,
                                'codec': 'aac',
                                'channels': 2,
                                'bitrate': 512,
                                'language': a.language,
                            }
                        })
                        l += 1
                    acodec = 'copy' if a.codec == audio_codec else audio_codec

                    # Bitrate calculations/overrides
                    if audio_bitrate is None or audio_bitrate > (
                            a.audio_channels * 256):
                        abitrate = 256 * a.audio_channels
                    else:
                        abitrate = audio_bitrate

                    audio_settings.update({
                        l: {
                            'map': a.index,
                            'codec': acodec,
                            'channels': a.audio_channels,
                            'bitrate': abitrate,
                            'language': a.language,
                        }
                    })
                    l = l + 1

            # Subtitle streams
            subtitle_settings = {}
            l = 0
            for s in info.subtitle:
                print "Subtitle stream detected: " + s.codec + " " + s.language + " [Stream " + str(
                    s.index) + "]"

                # Make sure its not an image based codec
                if s.codec not in bad_subtitle_codecs:
                    # Set undefined language to default language if specified
                    if sdl is not None and s.language == 'und':
                        s.language = sdl
                    # Proceed if no whitelist is set, or if the language is in the whitelist
                    if swl is None or s.language in swl:
                        subtitle_settings.update({
                            l: {
                                'map': s.index,
                                'codec': 'mov_text',
                                'language': s.language,
                                'forced': s.sub_forced,
                                'default': s.sub_default
                            }
                        })
                        l = l + 1

            # Collect all options
            options = {
                'format': 'mp4',
                'video': {
                    'codec': vcodec,
                    'map': info.video.index,
                    'bitrate': info.format.bitrate
                },
                'audio': audio_settings,
                'subtitle': subtitle_settings,
            }

            print options
            self.output = os.path.join(output_dir,
                                       filename + "." + output_extension)
            conv = c.convert(file, self.output, options)

            for timecode in conv:
                pass
                #print '[{0}] {1}%'.format('#' * (timecode / 10) + ' ' * (10 - (timecode / 10)), timecode, end='\r')
            print "Conversion complete"

            # Attempt to delete the input source file
            if delete:
                if self.removeFile(file):
                    print file + " deleted"
                else:
                    print "Couldn't delete the original file"

        # If file is already in the correct format:
        elif input_extension in valid_output_extensions:
            self.output = file

        # If all else fails
        else:
            print file + " - file not in the correct format"
            sys.exit()

        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if (relocate_moov):
            print "Relocating MOOV atom to start of file"
            tmp = self.output + ".tmp"
            # Clear out the temp file if it exists
            self.removeFile(tmp, 0, 0)

            try:
                processor.process(self.output, tmp)
                # Cleanup
                if self.removeFile(self.output, replacement=tmp):
                    print "Cleanup successful"
                else:
                    print "Error cleaning up temp files and renaming"
            except exceptions.FastStartException:
                print "QT FastStart did not run - perhaps moov atom was at the start already"
    def __init__(self, file, FFMPEG_PATH="FFMPEG.exe", FFPROBE_PATH="FFPROBE.exe", delete=True, output_extension='mp4', relocate_moov=True, video_codec='h264', audio_codec='aac', audio_bitrate=None, iOS=False, awl=None, swl=None, adl=None, sdl=None):
        #Get path information from the input file
        output_dir, filename = os.path.split(file)
        filename, input_extension = os.path.splitext(filename)
        input_extension = input_extension[1:]

        c = Converter(FFMPEG_PATH, FFPROBE_PATH)
        # Get values for width and height to be passed to the tagging classes for proper HD tags
        info = c.probe(file)
        self.height = info.video.video_height
        self.width = info.video.video_width
        # Make sure input and output extensions are compatible
        if input_extension in valid_input_extensions and output_extension in valid_output_extensions:
            #Video stream
            print "Video codec detected: " + info.video.codec
            vcodec = 'copy' if info.video.codec == video_codec else video_codec

            #Audio streams
            audio_settings = {}
            l = 0
            for a in info.audio:
                print "Audio stream detected: " + a.codec + " " + a.language + " [Stream " + str(a.index) + "]"
                # Set undefined language to default language if specified
                if adl is not None and a.language == 'und':
                    print "Undefined language detected, defaulting to " + adl
                    a.language = adl
                # Proceed if no whitelist is set, or if the language is in the whitelist
                if awl is None or a.language in awl:
                    # Create iOS friendly audio stream if the default audio stream has too many channels (iOS only likes AAC stereo)
                    if iOS and a.audio_channels > 2:
                        print "Creating dual audio channels for iOS compatability for this stream"
                        audio_settings.update({l: {
                            'map': a.index,
                            'codec': 'aac',
                            'channels': 2,
                            'bitrate': 512,
                            'language': a.language,
                        }})
                        l += 1
                    acodec = 'copy' if a.codec == audio_codec else audio_codec

                    # Bitrate calculations/overrides
                    if audio_bitrate is None or audio_bitrate > (a.audio_channels * 256):
                        abitrate = 256 * a.audio_channels
                    else:
                        abitrate = audio_bitrate

                    audio_settings.update({l: {
                        'map': a.index,
                        'codec': acodec,
                        'channels': a.audio_channels,
                        'bitrate': abitrate,
                        'language': a.language,
                    }})
                    l = l + 1

            # Subtitle streams
            subtitle_settings = {}
            l = 0
            for s in info.subtitle:
                print "Subtitle stream detected: " + s.codec + " " + s.language + " [Stream " + str(s.index) + "]"

                # Make sure its not an image based codec
                if s.codec not in bad_subtitle_codecs:
                    # Set undefined language to default language if specified
                    if sdl is not None and s.language == 'und':
                        s.language = sdl
                    # Proceed if no whitelist is set, or if the language is in the whitelist
                    if swl is None or s.language in swl:
                        subtitle_settings.update({l: {
                            'map': s.index,
                            'codec': 'mov_text',
                            'language': s.language,
                            'forced': s.sub_forced,
                            'default': s.sub_default
                        }})
                        l = l + 1

            # Collect all options
            options = {
                'format': 'mp4',
                'video': {
                    'codec': vcodec,
                    'map': info.video.index,
                    'bitrate': info.format.bitrate
                },
                'audio': audio_settings,
                'subtitle': subtitle_settings,
            }

            print options
            self.output = os.path.join(output_dir, filename + "." + output_extension)
            conv = c.convert(file, self.output, options)

            for timecode in conv:
                pass
                #print '[{0}] {1}%'.format('#' * (timecode / 10) + ' ' * (10 - (timecode / 10)), timecode, end='\r')
            print "Conversion complete"

            # Attempt to delete the input source file
            if delete:
                if self.removeFile(file):
                    print file + " deleted"
                else:
                    print "Couldn't delete the original file"

        # If file is already in the correct format:
        elif input_extension in valid_output_extensions:
            self.output = file

        # If all else fails
        else:
            print file + " - file not in the correct format"
            sys.exit()

        # Relocate MOOV atom to the very beginning. Can double the time it takes to convert a file but makes streaming faster
        if (relocate_moov):
            print "Relocating MOOV atom to start of file"
            tmp = self.output + ".tmp"
            # Clear out the temp file if it exists
            self.removeFile(tmp, 0, 0)

            try:
                processor.process(self.output, tmp)
                # Cleanup
                if self.removeFile(self.output, replacement=tmp):
                    print "Cleanup successful"
                else:
                    print "Error cleaning up temp files and renaming"
            except exceptions.FastStartException:
                print "QT FastStart did not run - perhaps moov atom was at the start already"
示例#21
0
            print atom, "(" + str(size) + " bytes)"
            
        raise SystemExit
    
    if len(args) == 1:
        # Replace the original file!
        if options.sample:
            print "Please pass an output filename when used with --sample!"
            raise SystemExit(1)
            
        tmp, outfile = tempfile.mkstemp()
        os.close(tmp)
    else:
        outfile = args[1]
    
    limit = 0
    if options.sample:
        # Create a small sample (4 MiB)
        limit = 4 * (1024 ** 2)
    
    try:
        processor.process(args[0], outfile, limit = limit)
    except FastStartException:
        # A log message was printed, so exit with an error code
        raise SystemExit(1)
    
    if len(args) == 1:
        # Move temp file to replace original
        shutil.move(outfile, args[0])