Skip to content

Commit

Permalink
Parse expected video duration based on captured *.mkv file name, WiP #96
Browse files Browse the repository at this point in the history
  • Loading branch information
vmdocua committed Jun 27, 2024
1 parent aa07fda commit 0782d8c
Showing 1 changed file with 71 additions and 7 deletions.
78 changes: 71 additions & 7 deletions Parsing/parse_wQR.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import json
import logging
import os
import re
from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Field
from pyzbar.pyzbar import decode, ZBarSymbol
Expand All @@ -16,14 +18,19 @@
# initialize the logger
logger = logging.getLogger(__name__)
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
logger.setLevel(logging.INFO)
stm_error = logging.StreamHandler(sys.stderr)
stm_error.setLevel(logging.ERROR)
logging.getLogger().addHandler(stm_error)
logger.debug(f"name={__name__}")


# Define class for video time info
class VideoTimeInfo(BaseModel):
start_time: datetime = Field(..., description="Start time of the video")
end_time: datetime = Field(..., description="End time of the video")
success: bool = Field(..., description="Success flag")
error: Optional[str] = Field(None, description="Error message if any")
start_time: Optional[datetime] = Field(None, description="Start time of the video")
end_time: Optional[datetime] = Field(None, description="End time of the video")
duration_sec: Optional[float] = Field(None, description="Duration of the video in seconds")


# Define the data model for the QR record
Expand All @@ -41,6 +48,47 @@ def __str__(self):
)


def get_video_time_info(path_video: str) -> VideoTimeInfo:
res: VideoTimeInfo = VideoTimeInfo(success=False, error=None,
start_time=None, end_time=None)
# Define the regex pattern for the timestamp and file extension (either .mkv or .mp4)
pattern = (r'^(\d{4}\.\d{2}\.\d{2}\.\d{2}\.\d{2}\.\d{2}\.\d{3})'
r'_(\d{4}\.\d{2}\.\d{2}\.\d{2}\.\d{2}\.\d{2}\.\d{3})\.(mkv|mp4)$')

file_name: str = os.path.basename(path_video)
logger.debug(f"Video file name : {file_name}")

match = re.match(pattern, file_name)
if not match:
res.error = "Filename does not match the required pattern."
return res

start_ts, end_ts, extension = match.groups()

# Define the format for datetime parsing
ts_format = "%Y.%m.%d.%H.%M.%S.%f"

try:
# Parse the timestamps
res.start_time = datetime.strptime(start_ts, ts_format)
res.end_time = datetime.strptime(end_ts, ts_format)
except ValueError as e:
res.error = f"Timestamp parsing error: {e}"
return res

# Validate the chronological order
if res.start_time >= res.end_time:
res.error = "Start timestamp is not earlier than end timestamp."
return res

# calculate the duration in seconds
dt: float = (res.end_time - res.start_time).total_seconds()
res.duration_sec = dt

res.success = True
return res


def finalize_record(record: QrRecord, iframe: int) -> QrRecord:
record.frame_end = iframe
record.time_end = 'TODO'
Expand All @@ -49,6 +97,15 @@ def finalize_record(record: QrRecord, iframe: int) -> QrRecord:


def do_parse(path_video: str) -> int:
vti: VideoTimeInfo = get_video_time_info(path_video)
if not vti.success:
logger.error(f"Failed parse file name time patter, error: {vti.error}")
return 1

logger.debug(f"Video start time : {vti.start_time}")
logger.debug(f"Video end time : {vti.end_time}")
logger.debug(f"Video duration : {vti.duration_sec} sec")

starttime = time.time()
cap = cv2.VideoCapture(path_video)

Expand All @@ -63,8 +120,15 @@ def do_parse(path_video: str) -> int:
frame_width: int = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height: int = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
duration_sec: float = frame_count / fps if fps > 0 else -1.0
logger.info(f"Video information: resolution={frame_width}x{frame_height}, fps={str(fps)}, "
f"frames count={str(frame_count)}, duration={str(duration_sec)} sec")
logger.info(f"Video media info : ")
logger.info(f" - resolution : {frame_width}x{frame_height}")
logger.info(f" - frame rate : {str(fps)} FPS")
logger.info(f" - duration : {str(duration_sec)} sec")
logger.info(f" - frame count: {str(frame_count)}")

if abs(duration_sec - vti.duration_sec) > 120.0:
logger.error(f"Video duration significant mismatch (real/file name):"
f" {duration_sec} sec vs {vti.duration_sec} sec")

clips = []
qrData = {}
Expand Down Expand Up @@ -134,8 +198,8 @@ def do_parse(path_video: str) -> int:
def main(ctx, path: str, log_level):
logger.setLevel(log_level)
logger.debug("parse_wQR.py tool")
logger.debug(f"current dir: {os.getcwd()}")
logger.debug(f"path={path}")
logger.debug(f"Working dir : {os.getcwd()}")
logger.debug(f"Video full path : {path}")

if not os.path.exists(path):
logger.error(f"Path does not exist: {path}")
Expand Down

0 comments on commit 0782d8c

Please sign in to comment.