read frame numbers directly if input file has them. use 0 indexed frames

This commit is contained in:
Q
2024-03-17 17:39:00 +02:00
parent 740b614290
commit d210e72704
2 changed files with 26 additions and 29 deletions

View File

@@ -1,7 +1,8 @@
from tsmark.video_annotator import Marker
import argparse import argparse
VERSION = "0.4.6" from tsmark.video_annotator import Marker
VERSION = "0.4.7"
def get_options(): def get_options():

View File

@@ -1,8 +1,9 @@
import sys
import os import os
import cv2 import sys
import time import time
import cv2
class Marker: class Marker:
def __init__(self, opts): def __init__(self, opts):
@@ -104,9 +105,7 @@ class Marker:
) )
for ts in self.stamps: for ts in self.stamps:
ts_pos = int( ts_pos = int(self.bar_start + ts / self.frames * (self.bar_end - self.bar_start))
self.bar_start + ts / self.frames * (self.bar_end - self.bar_start)
)
cv2.line( cv2.line(
frame, frame,
(ts_pos, self.bar_top), (ts_pos, self.bar_top),
@@ -138,9 +137,7 @@ class Marker:
(255, 255, 255), (255, 255, 255),
) )
end_frame = self.format_time(self.frames - 1) end_frame = self.format_time(self.frames - 1)
(text_width, text_height) = cv2.getTextSize( (text_width, text_height) = cv2.getTextSize(end_frame, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)[0]
end_frame, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2
)[0]
self.shadow_text( self.shadow_text(
frame, frame,
end_frame, end_frame,
@@ -163,7 +160,7 @@ class Marker:
if not self.nr in self.stamps: if not self.nr in self.stamps:
return return
text = "{} #{}".format(self.nr + 1, self.stamps.index(self.nr) + 1) text = "{} #{}".format(self.nr, self.stamps.index(self.nr) + 1)
bottom = 60 bottom = 60
left = 10 left = 10
self.shadow_text(frame, text, (left, bottom), 1, 2, (63, 84, 255)) self.shadow_text(frame, text, (left, bottom), 1, 2, (63, 84, 255))
@@ -242,25 +239,28 @@ class Marker:
if colon_count == 2: if colon_count == 2:
hours, mins, secstr = timestr.split(":", 2) hours, mins, secstr = timestr.split(":", 2)
sec = float(secstr) sec = float(secstr)
return int(self.fps * (int(hours) * 3600 + int(mins) * 60 + sec)) return int(self.fps * (int(hours) * 3600 + int(mins) * 60 + sec), 0)
raise ValueError("Cannot parse time definition {}".format(timestr)) raise ValueError("Cannot parse time definition {}".format(timestr))
def parse_timestamps(self): def parse_timestamps(self):
self.stamps = []
if self.opts.timestamps: if self.opts.timestamps:
if os.path.exists(self.opts.timestamps): if os.path.exists(self.opts.timestamps):
with open(self.opts.timestamps,'rt') as fp: with open(self.opts.timestamps, "rt") as fp:
for row in fp.readlines():
self.opts.timestamps = [x.split(",")[0] for x in fp.readlines()] # if row has 3 cols, pick the frame number directly
splitted = row.split(",")
if len(splitted) == 3:
self.stamps.append(int(splitted[2]))
if len(splitted) < 3:
self.opts.timestamps.append(splitted[0])
else: else:
self.opts.timestamps = self.opts.timestamps.split(",") self.opts.timestamps = self.opts.timestamps.split(",")
self.stamps = sorted( if len(self.stamps) > 0:
[ self.stamps.sort()
self.parse_time(ts.strip()) else:
for ts in self.opts.timestamps self.stamps = sorted([self.parse_time(ts.strip()) for ts in self.opts.timestamps if ts.strip() != ""])
if ts.strip() != ""
]
)
self.stamps = [x for x in self.stamps if 0 <= x < self.frames] self.stamps = [x for x in self.stamps if 0 <= x < self.frames]
self.nr = self.stamps[0] self.nr = self.stamps[0]
else: else:
@@ -274,7 +274,7 @@ class Marker:
self.stamps.sort() self.stamps.sort()
print("# Timestamps:") print("# Timestamps:")
for i, ts in enumerate(self.stamps): for i, ts in enumerate(self.stamps):
print("# {}: {} / {}".format(i + 1, self.format_time(ts), ts + 1)) print("# {}: {} / {}".format(i + 1, self.format_time(ts), ts))
if len(self.stamps) > 0: if len(self.stamps) > 0:
print( print(
'ffmpeg -ss {} -to {} -i "{}" -c copy "{}.trimmed.mp4"'.format( 'ffmpeg -ss {} -to {} -i "{}" -c copy "{}.trimmed.mp4"'.format(
@@ -291,7 +291,7 @@ class Marker:
return return
with open(self.opts.output, "wt") as fp: with open(self.opts.output, "wt") as fp:
for i, ts in enumerate(self.stamps): for i, ts in enumerate(self.stamps):
fp.write("{},{},{}\n".format(self.format_time(ts), i + 1, ts + 1)) fp.write("{},{},{}\n".format(self.format_time(ts), i + 1, ts))
def shadow_text(self, frame, text, pos, size, thicc, color): def shadow_text(self, frame, text, pos, size, thicc, color):
@@ -456,11 +456,7 @@ class Marker:
if self.read_next: if self.read_next:
self.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.nr) self.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.nr)
time_to_wait = ( time_to_wait = FPS_modifiers[FPS_modifier] * self.viewer_spf - time.time() + show_time
FPS_modifiers[FPS_modifier] * self.viewer_spf
- time.time()
+ show_time
)
if time_to_wait > 0: if time_to_wait > 0:
time.sleep(time_to_wait) time.sleep(time_to_wait)