onlyou13

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ffmpeg命令

::2倍速度
ffmpeg -y -i 1.mp4 -filter:a "atempo=2" -filter:v "setpts=0.5*PTS" out-2-audio.mkv
::0.5倍速度
ffmpeg -y -i 1.mp4 -filter:a "atempo=0.5" -filter:v "setpts=2*PTS" out-half-audio.mkv
::0.25倍速度
ffmpeg -y -i 1.mp4 -filter:a "atempo=0.5,atempo=0.5" -filter:v "setpts=4*PTS" out-half2-audio.mkv

 

ffmpeg-python调用

        self.srcFile= r"C:\Users\Administrator\Desktop\3a.mp4"
        self.fullOutputVideoFile= r"C:\Users\Administrator\Desktop\xxx5.mp4"
        self.speed = 4
        self.output = '3gp'
        self.disableAudio = 1

        is3gp = self.output.lower() == '3gp'

        ext = self.fullOutputVideoFile.split('.')[-1]
        if ext.lower() != self.output:
            self.fullOutputVideoFile = self.fullOutputVideoFile.replace('.' + ext, '.' + self.output)

        #是否需要两次转换
        audioTwoTimes = False
        
        vspeed = 1.0 / self.speed
        aspeed = self.speed
        # 如果调速 <0.5 或 >2需要进行两次转换,因为 (0.5 <= atempo <= 2)
        if aspeed < 0.5 or aspeed > 2:
            aspeed = aspeed ** 0.5
            audioTwoTimes = True
        
        input = ffmpeg.input(self.srcFile)

        if is3gp:
            #3gp, 音频调速设置
            audio = input.audio.filter("atempo", aspeed)
            if audioTwoTimes:
                audio = audio.filter("atempo", aspeed)            
            #视频调速设置
            video = input.video.filter("setpts", "{}*PTS".format(vspeed)).filter("scale", r"320x240")

            #音视频混合输出
            if self.disableAudio == 0:
                output = ffmpeg.output(audio, video, self.fullOutputVideoFile, vcodec='libxvid', vb='1200k', acodec='amr_nb', ar=8000, ac=1)
            else:
                output = ffmpeg.output(video, self.fullOutputVideoFile, vcodec='libxvid', vb='1200k')
            
            print(output.compile())
        else:
            #非3gp, 音频调速设置
            audio = input.audio.filter("atempo", aspeed)
            if audioTwoTimes:
                audio = audio.filter("atempo", aspeed)     
            #视频调速设置       
            video = input.video.filter("setpts", "{}*PTS".format(vspeed))

            #音视频混合输出
            if self.disableAudio == 0:
                output = ffmpeg.output(audio, video, self.fullOutputVideoFile)
            else:
                output = ffmpeg.output(video, self.fullOutputVideoFile)
            print(output.compile())
        
        #异步执行
        proc = output.run_async(pipe_stderr=True, overwrite_output=True)
        self.totalTime = 0
        self.converted = False

        def callback(line):
            try:
                if self.totalTime == 0: 
                    mobj = re.search(r'Duration\:\s*((?:\d\d[.:]){3}\d\d)', line)
                    if not mobj: return
                    self.totalTime += parse_dfxp_time_expr(mobj.group(1)) / self.speed
                else:
                    mobj = re.search(r'time=(.+)\s*bitrate=', line)

                    if not mobj: return 
                    self.converted = True
                    convertedDuration = parse_dfxp_time_expr(mobj.group(1))
                    self.progress = convertedDuration / self.totalTime * 100
                    print(self.progress)
                    #updateInfo(self.progressFile, self.shortOutputFile, self.progress, 'working')
            except Exception as ex:
                self.converted = False
                print(ex)
        return runProc(proc, proc.stderr, callback, timeOut=300)

 

#  增加自动缩进换行
def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

def parse_dfxp_time_expr(time_expr):
    if not time_expr:
        return
    time_expr = time_expr.strip()
    mobj = re.match(r'^(?P<time_offset>\d+(?:\.\d+)?)s?$', time_expr)
    if mobj:
        return float(mobj.group('time_offset'))

    mobj = re.match(r'^(\d+):(\d\d):(\d\d(?:(?:\.|:)\d+)?)$', time_expr)
    if mobj:
        return 3600 * int(mobj.group(1)) + 60 * int(mobj.group(2)) + float(mobj.group(3).replace(':', '.'))

def runProc(proc, out, callback, timeOut = 30):
    try:    
        proc_out_closed = False
        start = time.time()
        while not proc_out_closed:
            if (time.time() - start > timeOut):
                raise KeyboardInterrupt()
            line = ''
            while True:
                char = out.read(1)
                if not char:
                    proc_out_closed = True
                    break
                if char in [b'\r', b'\n']:
                    break
                try:
                    line += char.decode('ascii', 'replace')
                except Exception as ex:
                    continue
                
            if not line:
                continue
            if isinstance(line, bytes):
                line = line.decode('utf-8')
            #print(line)  #print可能會有特殊字符而引起的異常
            callback(line)
        return proc.wait() == 0
    except KeyboardInterrupt:            
        try:
            if sys.platform != 'win32':
                proc.communicate(b'q')
            else:
                proc.terminate()
        except:
            print('except...........')
            
        return False

def updateInfo(fileName, outputFileName, progress, resultState = 'working', error=None):
    if os.path.exists(fileName):
        Tree = ET.parse(fileName)
        ProgressInfoNode = Tree.getroot()
    #创建根节点
    else:
        ProgressInfoNode = ET.Element('ProgressInfo')    
        
    #创建子节点,并添加属性
    GetNode = lambda child: ProgressInfoNode.find(child) if ProgressInfoNode.find(child)!=None else ET.SubElement(ProgressInfoNode, child)    
    Node = GetNode('OutputFileName')#ET.SubElement(ProgressInfoNode,'OutputFileName')
    Node.text = outputFileName

    Node = GetNode('ResultState')#ET.SubElement(ProgressInfoNode, 'ResultState')
    Node.text = resultState

    Node = GetNode('Progress')#ET.SubElement(ProgressInfoNode, 'Progress')
    Node.text = str(progress)

    if error:
        Node = GetNode('error')#ET.SubElement(ProgressInfoNode, 'Progress')
        Node.text = str(error)        

    #创建elementtree对象,写文件
    indent(ProgressInfoNode,0)
    tree = ET.ElementTree(ProgressInfoNode)
    tree.write(fileName, encoding="utf-8")    

 

posted on 2020-04-29 15:07  onlyou13  阅读(1097)  评论(0编辑  收藏  举报