def replaceSubFileWith(input_file: Path, sub_file: Path, output_folder: Path): output_tmp1 = output_folder.joinpath(input_file.append_stem('_fxd_sub_tmp1').name) cmd = [ 'ffmpeg', '-y', '-i', F'{input_file}', '-map_metadata', '0', '-sn', '-c', 'copy', F'{output_tmp1}' ] common.run_process(cmd, silent=True) output_tmp = output_folder.joinpath(input_file.append_stem('_fxd_sub').name) cmd = [ 'ffmpeg', '-y', '-i', F'{output_tmp1}', '-i', F'{sub_file}', '-map_metadata', '0', '-c', 'copy', F'{output_tmp}' ] common.run_process(cmd, silent=True) output_tmp1.unlink() return output_tmp
def extract_chapter(input_file: Path, output_folder: Path = Path(".")) -> Path: cmd = ['mkvextract.exe'] cmd.append(str(input_file)) cmd.append('chapters') full_output_path = output_folder.joinpath(input_file.with_suffix(".xml").name) cmd.append(str(full_output_path)) common.run_process(cmd, silent=True) return full_output_path
def extract_first_subtitle(input_file: Path, output_folder: Path = None): output = input_file.change_suffix(".ass") if output_folder: output = output_folder.joinpath(input_file.change_suffix(".ass").name) cmd = [ 'ffmpeg', '-y', '-i', F'{input_file}', '-vn', '-an', F'{output}' ] common.run_process(cmd, silent=True) return output
def reEncodeFile(file: Path, outputFolder): cmd = [ "ffmpeg", "-y" ] cmd.append("-i") cmd.append(F"{file}") cmd.append('-map') cmd.append('0') cmd.append('-g') cmd.append('1') cmd.append('-pix_fmt') cmd.append('yuv420p') cmd.append('-c:v') cmd.append('h264_nvenc') cmd.append('-c:a') cmd.append('pcm_s16le') cmd.append('-b:v') cmd.append('2M') cmd.append('-s') cmd.append('1280x720') _output_file = outputFolder.joinpath(F"{file.stem}_re_encoded{file.suffix}") cmd.append(_output_file) common.run_process(cmd, silent=True) return _output_file
def ext_all_fonts_to_dir(p: Path, output_folder) -> Path: ats = mkvstuff.get_attachment_list(p) if len(ats) <= 0: return None for a in ats: id = a['id'] out_name = a['name'] cmd = ['mkvextract.exe'] cmd.append('{vid_file}') cmd.append('attachments') cmd.append('{id}:{output_folder}\\{out_name}') for ind, c in enumerate(cmd): cmd[ind] = c.format( vid_file=str(p), out_name=out_name, id=id, output_folder=output_folder ) common.run_process(cmd, silent=True) return output_folder
def mkvJson(input_file: Path): cmd = ['mkvmerge.exe'] cmd.append('-J') cmd.append(str(input_file)) rJson = common.run_process(cmd, silent=True) return json.loads(rJson)
def splitFilesByTimeCodes(input_file: Path, split_times: list, output_file: Path, viaFfmpeg=True, reEncode=False) -> List[Path]: print([x for x in split_times]) if viaFfmpeg: ffmpegTimeStamps = [] ffmpegStartTime = "" parts = {} for x in split_times: if not len(ffmpegTimeStamps): ffmpegStartTime = "" ffmpegTimeStamps ffmpegTimeStamps.append((x[0], ffmpegStartTime, x[1])) ffmpegStartTime = x[1] print(F"Splitting {input_file.name} into parts...") output_file.parent.mkdir(exist_ok=True, parents=True) for fts in ffmpegTimeStamps: partId = fts[0] cmd = [ "ffmpeg", "-y" ] cmd.append("-i") cmd.append(F"{input_file}") if fts[1] != "": cmd.append("-ss") cmd.append(fts[1]) cmd.append("-to") cmd.append(fts[2]) if not reEncode: cmd.append('-c') cmd.append('copy') else: cmd.append('-map') cmd.append('0') cmd.append('-g') cmd.append('1') cmd.append('-pix_fmt') cmd.append('yuv420p') cmd.append('-c:v') cmd.append('h264_nvenc') cmd.append('-c:a') cmd.append('pcm_s16le') cmd.append('-b:v') cmd.append('2M') cmd.append('-s') cmd.append('1280x720') _output_file = output_file.parent.joinpath(F"{output_file.stem}_{partId}{output_file.suffix}") cmd.append(_output_file) print(F"\rSplitting{' and re-encoding' if reEncode else ''} Part ID#{partId}...", end="") common.run_process(cmd, silent=True) print(F"\rSplitting{' and re-encoding' if reEncode else ''} Part ID#{partId}, DONE!", end="\n") parts[fts[0]] = _output_file return parts else: ids = [x[0] for x in split_times] timeCodes = ",".join(x[1] for x in split_times) # print(timeCodes) cmd = [ "mkvmerge", "--ui-language", "en", "--output", F"{output_file}", "(", F"{input_file}", ")", "--split", F"timestamps:{timeCodes}", ] print(F"Splitting {input_file} into parts...") common.run_process(cmd, silent=True) assumed_files = {} for x in range(1, len(ids) + 1): _af = output_file.parent.joinpath(output_file.append_stem(F"-{x:03}").name) if not _af.is_file(): raise Exception(F"Assumed split part:' {_af} does not exist. Good luck.") assumed_files[ids[x-1]] = _af print(assumed_files) return assumed_files
def buildMkvFromSegments(self, segmentList, output_file: Path, tmpDir: Path, chapter=None): concat_file = Path("concat.txt") font_dir = tmpDir.joinpath("fonts") font_dir.mkdir(exist_ok=True) style_list = {} for i in sorted(segmentList.keys()): seg = segmentList[i] if 'file_path' not in seg: continue mkvstuff.ext_all_fonts_to_dir(seg['file_path'], font_dir) sub_file = mkvstuff.extract_first_subtitle(seg['file_path'], tmpDir) sub_file = mkvstuff.suffixStyleNaming( sub_file, F"partid_{i}") # silly double up for styleStr in mkvstuff.getStylesFromAssFile(sub_file): styleDict = mkvstuff.style_to_dict(styleStr) style_list[styleDict["name"]] = styleDict sub_file.unlink() for i in sorted(segmentList.keys()): seg = segmentList[i] if 'file_path' not in seg: continue _fixed_sub = mkvstuff.extract_first_subtitle( seg["file_path"], tmpDir) _fixed_sub = mkvstuff.suffixStyleNaming( _fixed_sub, F"partid_{i}" ) # silly double up, but too lazy to save in memory _fixed_sub = mkvstuff.replaceAssStylesWithList( _fixed_sub, style_list) _fixed_sub_mkv = mkvstuff.replaceSubFileWith( seg["file_path"], _fixed_sub, tmpDir) segmentList[i]["file_path"] = _fixed_sub_mkv with concat_file.open("w", encoding="utf-8") as f: for i in sorted(segmentList.keys()): seg = segmentList[i] if 'file_path' not in seg: continue f.write(F"file '{seg['file_path']}'\n") _fixed_sub.unlink() output_file_tmp = output_file.append_stem('_tmp') cmd = [ 'ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', F'{concat_file}', ] if self.args.re_encode: cmd.append('-map') cmd.append('0') cmd.append('-g') cmd.append('1') cmd.append('-pix_fmt') cmd.append('yuv420p') cmd.append('-c:v') cmd.append('h264_nvenc') cmd.append('-c:a') cmd.append('pcm_s16le') cmd.append('-b:v') cmd.append('2M') cmd.append('-s') cmd.append('1280x720') else: cmd.append('-c') cmd.append('copy') cmd.append(F'{output_file_tmp}') fonts_list = mkvstuff.build_font_list(font_dir) print( F"Merging into{' (with re-encode)' if self.args.re_encode else ''}: {output_file_tmp}" ) common.run_process(cmd, silent=True) concat_file.unlink() output_file = output_file.parent.joinpath( common.strip_crc(output_file.stem) + output_file.suffix) print(F"Merging (with chapter & fonts) into: {output_file}") cmd = [ "mkvmerge", "--ui-language", "en", "--output", F"{output_file}", "(", F"{output_file_tmp}", ")", ] if chapter: cmd.extend([ "--chapter-language", "eng", "--chapters", F"{chapter}", ]) for font in fonts_list: cmd.extend([ "--attachment-name", F"{font.name}", "--attachment-mime-type", F"{font.mime}", "--attach-file", F"{font.resolve()}" ]) common.run_process(cmd, silent=True) output_file_tmp.unlink() print("\rCalculating and appending CRC-Sum...", end='') csum = common.crc32f(output_file) output_file.move(output_file.append_stem(F' [{csum}]')) print(F"\rCalculating and appending CRC-Sum, OK: {csum}")