python/elearning.py: retry on failure
This commit is contained in:
parent
3acadee72f
commit
2375f24870
@ -7,6 +7,7 @@
|
||||
import requests
|
||||
import subprocess
|
||||
import argparse
|
||||
import tempfile
|
||||
import pathlib
|
||||
import getpass
|
||||
import json
|
||||
@ -29,7 +30,7 @@ parser = argparse.ArgumentParser(
|
||||
Download all video lessons from an elearning course.
|
||||
|
||||
The videos are taken at the original quality and encoded
|
||||
using h.265 slow profile, 96kb/s opus for audio, via ffmpeg.
|
||||
using x265 slow profile, 96kb/s opus for audio, via ffmpeg.
|
||||
|
||||
You can run the program multiple times to keep the archive
|
||||
in sync with elearning: existing files won't be replaced or
|
||||
@ -282,23 +283,30 @@ def save_video(infos, files, args):
|
||||
printr('# skipping', end='\n\n')
|
||||
return
|
||||
|
||||
ffmpeg = [
|
||||
# where to save the stream
|
||||
tmp = pathlib.Path(tempfile.gettempdir())
|
||||
original = (tmp / filename).with_suffix('.mkv')
|
||||
|
||||
base = [
|
||||
'ffmpeg', '-hide_banner',
|
||||
'-loglevel', 'error',
|
||||
'-stats'
|
||||
] + inputs + maps + args.ffmpeg + [
|
||||
]
|
||||
download = base + inputs + maps + ['-y', original]
|
||||
|
||||
convert = base + args.ffmpeg + [
|
||||
# source
|
||||
'-i', original,
|
||||
'-map', '0',
|
||||
# video
|
||||
'-c:v', 'libx265', '-preset', 'slow', '-crf', '23',
|
||||
'-x265-params', 'log-level=error',
|
||||
# audio
|
||||
'-c:a', 'libopus', '-b:a', '96k',
|
||||
|
||||
# metadata
|
||||
'-metadata', 'title=' + info['description'],
|
||||
'-metadata', 'AUTHOR=' + info['userId'],
|
||||
'-metadata', 'DATE=' + info['createdAt'],
|
||||
'-metadata', 'IDS=' + ids,
|
||||
|
||||
# output
|
||||
(dir / filename).with_suffix('.mkv')
|
||||
]
|
||||
@ -307,8 +315,22 @@ def save_video(infos, files, args):
|
||||
printr('# downloading "{description}" '
|
||||
'- {duration:.1f}min'.format_map(info))
|
||||
printr('# by {userId}, {views} views'.format_map(info))
|
||||
subprocess.run(ffmpeg)
|
||||
printr()
|
||||
|
||||
# retry on failure
|
||||
for _ in range(3):
|
||||
try:
|
||||
print('# copying')
|
||||
subprocess.run(download, check=True)
|
||||
print('# converting')
|
||||
subprocess.run(convert, check=True)
|
||||
print()
|
||||
break
|
||||
except subprocess.CalledProcessError:
|
||||
if input('Conversion failed, retry? [Y/n]') == 'n':
|
||||
break
|
||||
|
||||
# remove original file
|
||||
original.unlink(missing_ok=True)
|
||||
|
||||
|
||||
def get_filenames(dir):
|
||||
@ -322,8 +344,11 @@ def get_filenames(dir):
|
||||
for file in dir.glob('*.mkv'):
|
||||
ffprobe = ['ffprobe', file, '-show_format', '-of', 'json']
|
||||
output = subprocess.run(ffprobe, capture_output=True).stdout
|
||||
metadata = json.loads(output)['format']
|
||||
files[metadata['tags']['IDS']] = file
|
||||
try:
|
||||
metadata = json.loads(output)['format']
|
||||
files[metadata['tags']['IDS']] = file
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return files
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user