コード例 #1
0
    def process(self, dc, astr=''):
        set_title = self.set_title2

        input_list = dc["list"]
        output_dir = dc["output_dir"] + os.sep
        utils.make_dir(output_dir)
        temp_dir = output_dir + 'tempDir' + os.sep
        utils.make_dir(temp_dir)
        utils.hide_file(temp_dir)
        keep_parent_select = dc["keep_parent_select"]

        final_png = ""

        total = len(input_list)
        count = 0
        msg_str = " {0}/{1} {2}"
        for i in range(total):
            count = count + 1
            input_file = input_list[i]
            p = Path(input_file)

            # 保留上层目录结构
            # 排除根目录
            path_root = "{0}{1}".format(p.drive, os.sep)
            path_parent = str(Path(p.parent).name)
            if keep_parent_select and not path_root == path_parent:
                output_sub_dir = "{0}{1}{2}".format(output_dir, path_parent,
                                                    os.sep)
                utils.make_dir(output_sub_dir)
                output_file = "{0}{1}{2}".format(output_sub_dir, p.stem,
                                                 ".jpg")
            else:
                output_file = "{0}{1}{2}".format(output_dir, p.stem, ".jpg")

            # 任务信息
            mstr = msg_str.format(count, total, p.name)
            set_title(mstr)

            # 拼接 ffmpeg 参数
            arr = [
                "ffmpeg -y -i", '"{}"'.format(input_file), '-hide_banner',
                '"{}"'.format(output_file)
            ]
            ff.execute(" ".join(arr))
            final_png = output_file

        set_title("操作结束!")

        # 自动打开目录
        if final_png:
            utils.open_dir(output_dir)

        self.t1 = ""
        self.lock_btn(False)
コード例 #2
0
    def processConcat(self, dc, astr=''):
        setTitle = self.setTitle2

        list1 = dc["list1"]
        list2 = dc["list2"]
        fast_mode_select = dc["fast_mode_select"]
        outputDir = dc["output_dir"] + os.sep

        tempDir = outputDir + 'tempDir' + os.sep

        # 保持长度一致
        minLen = min(len(list1), len(list2))
        list1 = list1[0:minLen]
        list2 = list2[0:minLen]

        finalMP4 = ""
        pStr = ""

        # set param=-c:v libx264 -s 1920x1080 -r 24 -b:v 6144k -b:a 128k -ar 44100 -ac 2 -preset slower -threads 8
        FFStr = '''ffmpeg -y -i "{input}" -c:v libx264 -s {v_size} -crf 18 -r {fps} -b:a 128k -ar 44100 -ac 2 -threads 8 "{output}"'''
        FFConcat = '''ffmpeg -y -f concat -safe 0 -i "{0}" -c copy "{1}"'''
        seq = ('input', 'output', 'v_size', 'fps')

        utils.make_dir(tempDir)
        utils.hide_file(tempDir)
        total = len(list1)
        count = 0
        msgStr = " ({0}/{1}) {2}"
        print(list1)
        status = []
        for i in range(len(list1)):
            count = count + 1
            status.append('')

            fileA = list1[i]
            fileB = list2[i]

            arr = utils.get_file_names(fileA)
            fnameA = arr[1]
            # ftypeA = arr[2]
            ftempA = tempDir + "-" + fnameA + ".mp4"

            arr = utils.get_file_names(fileB)
            fnameB = arr[1]
            # ftypeB = arr[2]
            ftempB = tempDir + "-" + fnameB + ".mp4"

            fullName = fnameA + '__' + fnameB
            finalMP4 = outputDir + fullName + ".mp4"
            subTxt = tempDir + "concat_" + fullName + ".txt"

            # 任务信息
            mstr = msgStr.format(count, total, fullName)
            setTitle(mstr)

            # 读取第一个视频的 尺寸和帧频作为基准
            # !!!所有的视频都会进行一次转码
            dc = dict.fromkeys(seq, "")
            dcinfo = ff.get_video_info(fileA, False)
            dc['fps'] = dcinfo['fps'] if dcinfo['fps'] else '24'
            dc['v_size'] = dcinfo['v_size'] if dcinfo['v_size'] else '1920x1080'

            # 检查视频参数是否相同
            isSame = False
            if fast_mode_select:
                isSame = ff.compare_video(fileA, fileB)
            # 生成concat.txt, 并转换片头/片尾
            subs = []
            sub = "file '{0}'\n"
            if not isSame:
                # 转第一个视频
                mstr = msgStr.format(count, total, "转换 第一个视频……")
                setTitle(mstr)
                status[i] = '10%'
                self.updateCenter(status)

                dc['input'] = fileA
                dc['output'] = ftempA
                pStr = FFStr.format(**dc)
                ff.execute(pStr)

                # 转第二个视频
                mstr = msgStr.format(count, total, "转换 第二个视频……")
                setTitle(mstr)
                status[i] = '50%'
                self.updateCenter(status)

                dc['input'] = fileB
                dc['output'] = ftempB
                pStr = FFStr.format(**dc)
                ff.execute(pStr)

                subs.append(sub.format(ftempA))
                subs.append(sub.format(ftempB))
            else:
                mstr = msgStr.format(count, total, "参数相同,跳过转换,直接拼接!")
                setTitle(mstr)

                subs.append(sub.format(fileA))
                subs.append(sub.format(fileB))

            # 写入concat文件
            utils.write_txt(subTxt, subs)

            # 拼接视频
            mstr = msgStr.format(count, total, "拼接中……")
            setTitle(mstr)
            status[i] = '90%'
            self.updateCenter(status)

            pStr = FFConcat.format(subTxt, finalMP4)
            ff.execute(pStr)
            # print(pStr)

            sstr = '成功' if os.path.exists(finalMP4) else '失败'
            status[i] = sstr
            self.updateCenter(status)

            # 移除 concat.txt 和 mp4
            utils.remove_file(subTxt)
            utils.remove_file(ftempA)
            utils.remove_file(ftempB)

        setTitle("操作结束!")
        setTitle("")

        # 自动打开目录
        if finalMP4:
            utils.open_dir(outputDir)

        self.t1 = ""
        self.lockBtn(False)
コード例 #3
0
ファイル: tap_app.py プロジェクト: hufang360/fftool
    def encode_china_mobile_ts(self,
                               input_file,
                               output_dir,
                               tune_str='animation',
                               png_select=False,
                               png_path='',
                               size='1920x1080',
                               t=15,
                               keep_ratio=False,
                               double_fix_select=False):
        format_str = 'ffmpeg -hide_banner -y -i "{in_file}" {param} "{out_ts}"'

        param = "-c:v libx264 " \
                "-b:v 3.8m " \
                "-minrate 2.5m " \
                "-maxrate 4m " \
                "-profile:v high -level 4.1 " \
                "-s 1280x720 " \
                "-r 25 " \
                "-coder cabac " \
                "-refs:v 3 " \
                "-x264opts b-pyramid=0 " \
                "-c:a aac " \
                "-profile:a aac_low " \
                "-b:a 128k " \
                "-ar 48000 " \
                "-ac 2 " \
                "-map_metadata -1 " \
                "-preset slower"

        # 创建输出目录
        p = Path(input_file)
        # save_dir = output_dir + str(p.stem)
        # save_dir += os.sep
        # utils.remove_file(save_dir, False)
        # utils.make_dir(save_dir)

        # 双倍时长修正
        if double_fix_select:
            tdc = ff.get_video_info(input_file, False)  # 匹配 尺寸和fps
            duration = tdc['duration'] if tdc["duration"] else '0'
            duration = float(duration)
            if duration:
                ss = duration
                if isinstance(ss, int) or isinstance(ss, float):
                    ss = ss * 1000
                    ss = int(ss)
                    ss = ff.millisecond_to_str(ss)
                    param += ' -to {}'.format(ss)

                    set_title = self.start_btn.update_query
                    duration_string = ff.millisecond_to_str(
                        int(duration * 1000))
                    set_title("*[双倍时长修正]该视频时长:" + duration_string)

        # 输出文件名
        save_dir = output_dir + "移动/"
        ts_file = save_dir + p.stem + ".ts"
        utils.make_dir(save_dir)

        if keep_ratio:
            w = 1280
            h = 720
            # 获取当前视频的分辨率和缩放比
            v_dc = ff.get_video_info(input_file)
            v_size = v_dc['v_size']
            v_arr = v_size.split("x")
            vw = int(v_arr[0])
            vh = int(v_arr[1])
            scale = min(w / vw, h / vh)
            w_real = round(vw * scale)
            h_real = round(vh * scale)
            x = round((w - w_real) / 2)
            y = round((h - h_real) / 2)
            con_vf = 'scale={w_real}:{h_real},pad={w}:{h}:{x}:{y}:black'
            con_vf = con_vf.format(w=w,
                                   h=h,
                                   x=x,
                                   y=y,
                                   w_real=w_real,
                                   h_real=h_real)
        else:
            con_vf = ''

        # 拼接参数
        param_final = '{param} -tune {tune}'.format(param=param, tune=tune_str)

        # 添加水印参数 水印图片作为输入管道 需参数之前 pngs = ['/Users/qinbaomac-mini/Library/Mobile
        # Documents/com~apple~CloudDocs/Dev/python/py_pack/res/备案号-爱奇艺.png'] sizes = ["1920x1080"] times = [15]
        if png_select:
            if os.path.exists(png_path):
                param_final = ' -i "{0}" {1}'.format(png_path, param_final)
                param_overlay = ff.get_overlay([png_path], [size], [t], [],
                                               True)
                if con_vf:
                    param_overlay = param_overlay.replace(
                        '-filter_complex "',
                        '-filter_complex "' + con_vf + ',')
                    con_vf = ''
                param_final = '{0} {1} '.format(param_final, param_overlay)
            else:
                if png_path:
                    print('水印图片地址不正确 "{}"'.format(png_path))
        # 黑边视频参数
        if con_vf:
            con_vf = '-filter_complex "{}"'.format(con_vf)
            param_final = '{0} {1} '.format(param_final, con_vf)

        final_str = format_str.format(in_file=input_file,
                                      param=param_final,
                                      out_ts=ts_file)
        print(final_str)
        ff.execute(final_str)

        return ts_file
コード例 #4
0
    def process(self, dc, a_str=''):
        set_title = self.start.update_query

        input_list = dc["list"]
        output_dir = dc["output_dir"] + os.sep
        temp_dir = output_dir + 'tempDir' + os.sep
        utils.make_dir(temp_dir)
        utils.hide_file(temp_dir)

        s2bool = utils.str_to_bool
        keep_parent_select = s2bool(dc["keep_parent_select"])
        keep_meta_select = s2bool(dc["keep_meta_select"])

        # format1_select = s2bool(dc["format1_select"])
        format2_select = s2bool(dc["format2_select"])
        format3_select = s2bool(dc["format3_select"])

        pt_select = dc["pt_select"]
        pw_select = dc["pw_select"]
        pt_second = dc["pt_second"] / 1000
        pw_second = dc["pw_second"] / 1000
        need_remain = dc["need_remain"]

        if format2_select:
            ext = ".m4a"
            param_a = ""
        elif format3_select:
            ext = ".wav"
            param_a = ""
        else:
            ext = ".mp3"
            param_a = " -acodec libmp3lame -ac 2 -ar 44100 -b:a 128k"

        final_mp4 = ""

        total = len(input_list)
        count = 0
        msg_str = " {0}/{1} {2}"
        for i in range(total):
            count = count + 1
            input_file = input_list[i]
            p = Path(input_file)

            # 保留上层目录结构
            # 排除根目录
            path_root = "{0}{1}".format(p.drive, os.sep)
            path_parent = str(Path(p.parent).name)
            if keep_parent_select and not path_root == path_parent:
                output_sub_dir = "{0}{1}{2}".format(output_dir, path_parent, os.sep)
                utils.make_dir(output_sub_dir)
                output_file = "{0}{1}{2}".format(output_sub_dir, p.stem, ext)
            else:
                output_file = "{0}{1}{2}".format(output_dir, p.stem, ext)

            # 任务信息
            set_title(msg_str.format(count, total, p.name))

            # 读取视频参数
            tdc = ff.get_video_info(input_file, False)
            # v_size = tdc["v_size"] if tdc["v_size"] else "1920x1080"
            # fps = tdc["fps"] if tdc["fps"] else "24"
            # tdc["fps"] = fps

            duration = float(tdc['duration']) if tdc["duration"] else 0
            duration = float(duration)
            second = duration

            if not duration:
                set_title('读取视频参数失败,不处理该视频')
                continue

            need_execute = False
            time_start = 0
            time_to = 0
            if pt_select and pt_second != 0:
                if pt_second < second:
                    time_start = pt_second
                    need_execute = True
                else:
                    set_title('片头时长超过视频时长,不进行片头修剪!!!')

            if pw_select and pw_second != 0:
                if need_remain:
                    time_to = second - pw_second
                else:
                    time_to = pw_second

                if time_to > time_start:
                    need_execute = True
                else:
                    time_to = 0
                    set_title('片尾时长在起始时间之前,不进行片尾修剪!!!')

            if need_execute:
                set_title('正在转换 修剪部分……')

            if time_start != 0:
                ss = ' -ss {}'.format(time_start)
            else:
                ss = ''

            if time_to != 0:
                to = ' -to {}'.format(time_to)
            else:
                to = ''

            # 拼接 ffmpeg 参数
            if keep_meta_select:
                param = 'ffmpeg -y -i "{in_file}"{param_a}{ss}{to} ' \
                        '-vn -hide_banner "{out_file}"'
            else:
                param = 'ffmpeg -y -i "{in_file}"{param_a}{ss}{to} -map_metadata -1 ' \
                        '-vn -hide_banner "{out_file}"'
            param = param.format(in_file=input_file, out_file=output_file, param_a=param_a, ss=ss, to=to)
            ff.execute(param)
            final_mp4 = output_file

        set_title("操作结束!")

        # 自动打开目录
        if final_mp4:
            utils.open_dir(output_dir)

        self.t1 = ""
        self.lock_btn(False)
コード例 #5
0
ファイル: tap_app.py プロジェクト: hufang360/fftool
    def encode_m3u8(input_file,
                    output_dir,
                    is_640=False,
                    tune_str='animation'):
        s = 'ffmpeg -hide_banner -re -y -i "{in_file}" {param} "{out_ts}" "{out_m3u8}"'

        param_640 = "-c:v libx264 " \
                    "-s 640x360 " \
                    "-crf 28 " \
                    "-r 15 " \
                    "-g 60 " \
                    "-b:a 96k " \
                    "-ar 44100 " \
                    "-ac 2 " \
                    "-preset slower " \
                    "-threads 8"

        param_1280 = "-c:v libx264 " \
                     "-s 1280x720 " \
                     "-crf 26 " \
                     "-r 24 " \
                     "-g 48 " \
                     "-b:a 128k " \
                     "-ar 44100 " \
                     "-ac 2 " \
                     "-preset slower " \
                     "-threads 8"

        # param_hls = "-map 0 -f hls -hls_time 10 -hls_list_size 0 -use_localtime_mkdir 1 -hls_segment_filename"
        param_segment = '-map 0 ' \
                        '-f hls ' \
                        '-bsf:v h264_mp4toannexb ' \
                        '-hls_time 10 ' \
                        '-hls_flags split_by_time ' \
                        '-hls_list_size 0 ' \
                        '-hls_allow_cache 1 ' \
                        '-hls_segment_filename'

        # 创建输出目录
        p = Path(input_file)
        save_dir = output_dir + str(p.stem)
        save_dir += '_640' if is_640 else '_1280'
        save_dir += '_m3u8' + os.sep
        utils.remove_file(save_dir, False)
        utils.make_dir(save_dir)

        # 输出文件名
        m3u8_file = save_dir + 'playlist.m3u8'
        ts_file = save_dir + '%06d.ts'

        # 拼接参数
        param_video = param_640 if is_640 else param_1280
        param_final = '{param_video} -tune {tune} {param_segment}'
        param_final = param_final.format(param_video=param_video,
                                         tune=tune_str,
                                         param_segment=param_segment)
        s = s.format(in_file=input_file,
                     param=param_final,
                     out_m3u8=m3u8_file,
                     out_ts=ts_file)
        ff.execute(s)

        return save_dir