modify ffmpeg commands

This commit is contained in:
q
2025-01-16 16:45:07 +02:00
parent 65649a079e
commit 0932a6190d
2 changed files with 41 additions and 10 deletions

View File

@@ -2,7 +2,7 @@ import argparse
from tsmark.video_annotator import Marker from tsmark.video_annotator import Marker
VERSION = "0.5.1" VERSION = "0.6.0"
def get_options(): def get_options():
@@ -42,6 +42,21 @@ def get_options():
type=str, type=str,
help="predefined crop. Syntax: 'w:h:x:y' example: 1280:720:30:20", help="predefined crop. Syntax: 'w:h:x:y' example: 1280:720:30:20",
) )
parser.add_argument(
"--ffmpeg-copy",
action="store_true",
default=False,
required=False,
help="Print FFMPEG commands: Copy instead of recompress. If video is cropped, it must be recompressed",
)
parser.add_argument(
"--ffmpeg-an",
action="store_true",
default=False,
required=False,
help="Print FFMPEG commands: Discard audio track",
)
parser.add_argument("--version", action="version", version=VERSION) parser.add_argument("--version", action="version", version=VERSION)
parser.add_argument(action="store", dest="video") parser.add_argument(action="store", dest="video")
return parser.parse_args() return parser.parse_args()

View File

@@ -4,6 +4,13 @@ import time
import cv2 import cv2
AUDIO_COMPRESS = "-c:a libmp3lame -ar 44100 -b:a 192k"
AUDIO_COPY = "-c:a copy"
AUDIO_DISCARD = "-an"
VIDEO_COMPRESS = "-c:v mpeg2video -q:v 3 -g 1"
VIDEO_COPY = "-c:v copy"
EXT_COMPRESS = ".mpeg"
class Marker: class Marker:
def __init__(self, opts): def __init__(self, opts):
@@ -314,8 +321,9 @@ 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), 0) return int(self.fps * (int(hours, 10) * 3600 + int(mins, 10) * 60 + sec))
raise ValueError("Cannot parse time definition {}".format(timestr)) raise ValueError("Cannot parse time definition {}".format(timestr))
raise TypeError("Cannot parse time definition {}".format(timestr))
def parse_timestamps(self): def parse_timestamps(self):
self.stamps = [] self.stamps = []
@@ -326,7 +334,7 @@ class Marker:
# if row has 3 cols, pick the frame number directly # if row has 3 cols, pick the frame number directly
splitted = row.split(",") splitted = row.split(",")
if len(splitted) == 3: if len(splitted) == 3:
self.stamps.append(int(splitted[2])) self.stamps.append(int(splitted[2], 10))
if len(splitted) < 3: if len(splitted) < 3:
self.opts.timestamps.append(splitted[0]) self.opts.timestamps.append(splitted[0])
else: else:
@@ -350,6 +358,7 @@ class Marker:
if self.crop[2] is None: if self.crop[2] is None:
cropstr = "" cropstr = ""
else: else:
self.opts.ffmpeg_copy = False
x, y = [ x, y = [
int(self.video_res_original[0] * self.crop[0][0] / self.video_res[0]), int(self.video_res_original[0] * self.crop[0][0] / self.video_res[0]),
int(self.video_res_original[1] * self.crop[0][1] / self.video_res[1]), int(self.video_res_original[1] * self.crop[0][1] / self.video_res[1]),
@@ -367,6 +376,10 @@ class Marker:
cropstr = f"-filter:v crop={w}:{h}:{x}:{y} " cropstr = f"-filter:v crop={w}:{h}:{x}:{y} "
self.stamps.sort() self.stamps.sort()
print("# Timestamps:") print("# Timestamps:")
audio_str = AUDIO_COPY if self.opts.ffmpeg_copy else AUDIO_COMPRESS
video_str = VIDEO_COPY if self.opts.ffmpeg_copy else VIDEO_COMPRESS
audio_str = AUDIO_DISCARD if self.opts.ffmpeg_an else audio_str
for i, ts in enumerate(self.stamps): for i, ts in enumerate(self.stamps):
print("# {}: {} / {}".format(i + 1, self.format_time(ts), ts)) print("# {}: {} / {}".format(i + 1, self.format_time(ts), ts))
if len(self.stamps) == 0: if len(self.stamps) == 0:
@@ -375,15 +388,18 @@ class Marker:
padlen = len(str(self.frames)) padlen = len(str(self.frames))
src_name = self.opts.video.replace('"', '\\"') src_name = self.opts.video.replace('"', '\\"')
tgt_name = os.path.splitext(self.opts.video)[0].replace('"', '\\"') tgt_name = os.path.splitext(self.opts.video)[0].replace('"', '\\"')
for i in range(1,len(self.stamps),2): tgt_ext = os.path.splitext(self.opts.video)[1] if self.opts.ffmpeg_copy else EXT_COMPRESS
from_ts = self.stamps[i-1]
to_ts = self.stamps[i] for i in range(1, len(self.stamps), 2):
from_ts = self.stamps[i - 1]
to_ts = self.stamps[i]
from_ft = self.format_time(from_ts) from_ft = self.format_time(from_ts)
to_ft = self.format_time(to_ts) to_ft = self.format_time(to_ts)
from_str=str(from_ts).zfill(padlen) from_str = str(from_ts).zfill(padlen)
to_str=str(to_ts).zfill(padlen) to_str = str(to_ts).zfill(padlen)
print(f'ffmpeg -i "{src_name}" {cropstr}-c:v mpeg2video -q:v 3 -g 1 -c:a libmp3lame -ar 44100 -b:a 192k -ss {from_ft} -to {to_ft} "{tgt_name}.trim.{from_str}-{to_str}.mpeg"') print(
f'ffmpeg -i "{src_name}" {cropstr}{video_str} {audio_str} -ss {from_ft} -to {to_ft} "{tgt_name}.trim.{from_str}-{to_str}{tgt_ext}"'
)
def save_timestamps(self): def save_timestamps(self):