Skip to content

Commit 83e99f2

Browse files
committed
ffmpeg_editlist: Add --show-schedule option
Shows timestamps translated into a real time.
1 parent 052b7bc commit 83e99f2

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

ffmpeg_editlist.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import bisect
1010
import contextlib
1111
import copy
12+
import datetime
1213
from datetime import timedelta
1314
import itertools
1415
import logging
@@ -215,8 +216,12 @@ def main(argv=sys.argv[1:]):
215216
help="Don't encode or generate output files, just check consistency of the YAML file. This *will* override the .info.txt output file.")
216217
parser.add_argument('--force', '-f', action='store_true',
217218
help='Overwrite existing output files without prompting')
219+
parser.add_argument('--dry-run', action='store_true',
220+
help="Dry run, don't make any new files or changes (command not fully developed yet)")
218221
parser.add_argument('--verbose', '-v', action='store_true',
219222
help='Verbose (put ffmpeg in normal mode, otherwise ffmpeg is quiet.)')
223+
parser.add_argument('--quiet', '-q', action='store_true',
224+
help="Don't output as much")
220225

221226
parser.add_argument('--reencode', action='store_true',
222227
help='Re-encode all segments of the video. See --preset and --crf to adjust parameters.'
@@ -242,7 +247,8 @@ def main(argv=sys.argv[1:]):
242247
help="Don't try to encode extra properties into the mkv file. This requires mkvtoolnix to be installed")
243248
parser.add_argument('--list', action='store_true',
244249
help="Don't do anything, just list all outputs that would be processed (and nothing else)")
245-
250+
parser.add_argument('--show-schedule',
251+
help="Translate timestamps to real schedule time. EDITLIST_TIMESTAMP=SCHEDULED_TIME.")
246252
parser.add_argument('--template-single', action='store_true',
247253
help="Print out template for a single video, don't do anything else.")
248254
parser.add_argument('--template-workshop', action='store_true',
@@ -281,11 +287,17 @@ def main(argv=sys.argv[1:]):
281287
#print(data)
282288
data = yaml.safe_load(data)
283289

290+
if args.show_schedule:
291+
schedule_start = seconds(args.show_schedule.split('=')[0])
292+
schedule_ts = seconds(args.show_schedule.split('=')[1])
293+
schedule_delta = schedule_ts - schedule_start
284294

285295
PWD = Path(os.getcwd())
286296
LOGLEVEL = 31
287297
if args.verbose:
288298
LOGLEVEL = 40
299+
if args.quiet:
300+
LOG.setLevel(40)
289301
workshop_title = None
290302
workshop_description = None
291303
options_ffmpeg_global = [ ]
@@ -340,6 +352,14 @@ def main(argv=sys.argv[1:]):
340352
segment_type = 'video'
341353
segment_number = 0
342354
for i, command in enumerate(editlist):
355+
# Backwards compatibility with old 'begin' and 'end' commands
356+
if 'begin' in command:
357+
command['start'] = command['begin']
358+
del command['begin']
359+
if 'end' in command:
360+
command['stop'] = command['end']
361+
del command['end']
362+
#
343363

344364
# Is this a command to cover a part of the video?
345365
if isinstance(command, dict) and 'cover' in command:
@@ -360,19 +380,19 @@ def main(argv=sys.argv[1:]):
360380
continue
361381
# Start command: start a segment
362382
elif isinstance(command, dict) and 'start' in command:
363-
segment_number += 1
364383
start = command['start']
365-
continue
366-
elif isinstance(command, dict) and 'begin' in command:
384+
if args.show_schedule:
385+
if segment_number == 0:
386+
print(f"{humantime(seconds(start) + schedule_delta)} START **{segment['title']}**")
387+
else:
388+
print(f"{humantime(seconds(start) + schedule_delta)} START")
367389
segment_number += 1
368-
start = command['begin']
369390
continue
370391
# End command: process this segment and all queued commands
371392
elif isinstance(command, dict) and 'stop' in command:
372393
stop = command['stop']
373-
# Continue below to process this segment
374-
elif isinstance(command, dict) and 'end' in command:
375-
stop = command['end']
394+
if args.show_schedule:
395+
print(f"{humantime(seconds(stop) + schedule_delta)} STOP")
376396
# Continue below to process this segment
377397
# Is this a TOC entry?
378398
# If it's a dict, it is a table of contents entry that will be
@@ -388,6 +408,11 @@ def main(argv=sys.argv[1:]):
388408
#print(start, title)
389409
#print('TOC', start, title, segment)
390410
TOC.append((segment_number, seconds(time), title))
411+
if args.show_schedule:
412+
if title.startswith('§'):
413+
print(f"{humantime(seconds(time) + schedule_delta)} . **{title}**")
414+
else:
415+
print(f"{humantime(seconds(time) + schedule_delta)} .. {title}")
391416
continue
392417

393418

@@ -408,6 +433,10 @@ def main(argv=sys.argv[1:]):
408433
# Print status
409434
LOG.info("\n\nBeginning %s (line %d)", segment.get('title') if 'title' in segment else '[no title]', i)
410435

436+
# TODO: should continue further down to actually test other code.
437+
if args.dry_run:
438+
continue
439+
411440
# Find input file
412441
if not os.path.exists(input1):
413442
input1 = args.input / input1
@@ -485,6 +514,10 @@ def main(argv=sys.argv[1:]):
485514

486515
output = args.output / segment['output']
487516

517+
# TODO: should continue further down to actually test other code.
518+
if args.dry_run:
519+
continue
520+
488521
# Subtitles
489522
if args.srt:
490523
srt_output = os.path.splitext(output)[0] + '.srt'

0 commit comments

Comments
 (0)