78 lines
2.3 KiB
Python
Executable File
78 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os.path
|
|
|
|
from argparse import ArgumentParser
|
|
from datetime import datetime, timedelta
|
|
|
|
DATETIME_FORMAT = '%Y-%m-%d-%H.%M.%S'
|
|
|
|
|
|
def chunks(lst, n):
|
|
for i in range(0, len(lst), n):
|
|
yield lst[i:i + n]
|
|
|
|
|
|
def time2seconds(time: str) -> int:
|
|
time, frac = time.split('.')
|
|
frac = int(frac)
|
|
|
|
h, m, s = [int(i) for i in time.split(':')]
|
|
|
|
return round(s + m*60 + h*3600 + frac/1000)
|
|
|
|
|
|
def filename_to_datetime(filename: str) -> datetime:
|
|
filename = os.path.basename(filename).replace('record_', '').replace('.mp4', '')
|
|
return datetime.strptime(filename, DATETIME_FORMAT)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
parser = ArgumentParser()
|
|
parser.add_argument('--source-filename', type=str, required=True,
|
|
help='recording filename')
|
|
parser.add_argument('--timecodes', type=str, required=True,
|
|
help='timecodes')
|
|
parser.add_argument('--padding', type=int, default=2,
|
|
help='amount of seconds to add before and after each fragment')
|
|
arg = parser.parse_args()
|
|
|
|
if arg.padding < 0:
|
|
raise ValueError('invalid padding')
|
|
|
|
timecodes = arg.timecodes.split(',')
|
|
if len(timecodes) % 2 != 0:
|
|
raise ValueError('invalid number of timecodes')
|
|
|
|
timecodes = list(map(time2seconds, timecodes))
|
|
timecodes = list(chunks(timecodes, 2))
|
|
|
|
# sort out invalid fragments (dvr-scan returns them sometimes, idk why...)
|
|
timecodes = list(filter(lambda f: f[0] < f[1], timecodes))
|
|
|
|
file_dt = filename_to_datetime(arg.source_filename)
|
|
|
|
# https://stackoverflow.com/a/43600953
|
|
timecodes.sort(key=lambda interval: interval[0])
|
|
merged = [timecodes[0]]
|
|
for current in timecodes:
|
|
previous = merged[-1]
|
|
if current[0] <= previous[1]:
|
|
previous[1] = max(previous[1], current[1])
|
|
else:
|
|
merged.append(current)
|
|
|
|
for fragment in merged:
|
|
start, end = fragment
|
|
|
|
start -= arg.padding
|
|
end += arg.padding
|
|
|
|
if start < 0:
|
|
start = 0
|
|
|
|
dt1 = (file_dt + timedelta(seconds=start)).strftime(DATETIME_FORMAT)
|
|
dt2 = (file_dt + timedelta(seconds=end)).strftime(DATETIME_FORMAT)
|
|
filename = f'{dt1}__{dt2}.mp4'
|
|
|
|
print(f'{start} {end} {filename}')
|