Skip to content

Instantly share code, notes, and snippets.

@ipid
Created March 1, 2023 04:25
Show Gist options
  • Save ipid/0577465a079a1e369a2839fb7516ba92 to your computer and use it in GitHub Desktop.
Save ipid/0577465a079a1e369a2839fb7516ba92 to your computer and use it in GitHub Desktop.
处理从 niconico 抓包获取的 .ts 分片文件。
from pathlib import Path
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--root', type=Path, default='.')
parser.add_argument('--ext', type=str, default='.ts')
parser.add_argument('--record', '--archive', '--recording', action='store_true', default=False)
parser.add_argument('--out-m3u8', type=Path, default=Path('./list.m3u8'))
args = parser.parse_args()
ROOT = Path(r'.')
M3U8_TEMPLATE = '''#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:1.500
{fragments}
#EXT-X-ENDLIST'''
def main():
fragments = []
divable_by_5000 = 0
for path in ROOT.glob(f'**/*{args.ext}'):
try:
num = int(path.stem)
except ValueError:
continue
if num % 5000 == 0:
divable_by_5000 += 1
fragments.append(num)
if divable_by_5000 > len(fragments) * 0.9 and not args.record:
print(f'检测到 {divable_by_5000} 个文件名为 5000 的倍数,这可能是录播文件。')
print(f'如果是录播文件,请使用 --record 参数。\n')
exit(1)
fragments.sort()
if len(fragments) == 0:
print('找不到任何文件名为数字的 ts 文件,退出。\n')
exit(1)
lack_fragments = []
diff = 5000 if args.record else 1
for i in range(1, len(fragments)):
if fragments[i] != fragments[i - 1] + diff:
for lacked_index in range(fragments[i - 1] + diff, fragments[i], diff):
lack_fragments.append(lacked_index)
m3u8_fragments = '\n'.join(
f'#EXTINF:1.500,\n{num}{args.ext}' for num in fragments)
with (ROOT / 'list.m3u8').open('w', encoding='utf-8') as f:
f.write(M3U8_TEMPLATE.format(fragments=m3u8_fragments))
print(f'已生成 m3u8 分片列表文件。')
print(f'最小值:{min(fragments)},最大值:{max(fragments)},缺失分片个数:{len(lack_fragments)}')
print(f'\n')
if len(lack_fragments) > 0:
print(f'缺失分片列表:\n{", ".join(str(x) for x in lack_fragments)}\n')
else:
print(f'没有缺失分片。\n')
print(f'使用如下命令合成 ts:')
print(f' ffmpeg {"-allowed_extensions ALL " if args.ext != ".ts" else ""}-i list.m3u8 -c copy output.mp4\n')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment