Huge refactoring
This commit is contained in:
109
utils.py
109
utils.py
@@ -1,62 +1,79 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
from typing import Literal, Any
|
||||
import subprocess
|
||||
|
||||
|
||||
@dataclass
|
||||
class TimelineEvent:
|
||||
id: str
|
||||
"""ID of the event in format `asr_18`"""
|
||||
class Event:
|
||||
"""Event within the timeline"""
|
||||
|
||||
id: int
|
||||
"""Unique ID of the event (within single timeline)"""
|
||||
|
||||
type: Literal["voice", "vis", "ocr"]
|
||||
"""Type of the event"""
|
||||
|
||||
timestamp: float
|
||||
"""When did the event happen"""
|
||||
"""When did the event start (or happen, if `duration` is 0)"""
|
||||
|
||||
duration: float
|
||||
"""How long did the event last (zero if it does not make sence)"""
|
||||
"""How long did the event last (0 if can't apply)"""
|
||||
|
||||
payload: str
|
||||
"""Payload of the event (text for `asr`, description for `vis`, OCR result for `ocr`)"""
|
||||
text: str
|
||||
"""Textual representation of the event (or data in `payload`, if it is not None)"""
|
||||
|
||||
custom: dict
|
||||
"""Custom data"""
|
||||
|
||||
links: list[str]
|
||||
"""ID of related timeline events, empty list for None"""
|
||||
|
||||
def get_ai_dict(self) -> dict:
|
||||
"""Returns dict that is sanitized for AI."""
|
||||
d = {
|
||||
"id": self.id,
|
||||
"timestamp": self.timestamp,
|
||||
"payload": self.payload
|
||||
}
|
||||
if self.duration:
|
||||
d["duration"] = self.duration
|
||||
if self.links:
|
||||
d["links"] = self.links
|
||||
return d
|
||||
payload: str | None
|
||||
"""Payload of the event. `None` for `voice`, image path for `vis`, OCR result for `ocr`"""
|
||||
|
||||
@dataclass
|
||||
class AnalysisWindow:
|
||||
before_readonly: list[TimelineEvent]
|
||||
"""Timeline events for context (before current window)"""
|
||||
class Timeline:
|
||||
"""Timeline of events"""
|
||||
|
||||
modifiable: list[TimelineEvent]
|
||||
"""Timeline events that are to be analyzed"""
|
||||
events: list[Event]
|
||||
"""Events of the timeline"""
|
||||
|
||||
after_readonly: list[TimelineEvent]
|
||||
"""Timeline events for context (after current window)"""
|
||||
def ffmpeg_split_video(input_path: str) -> tuple[str, str]:
|
||||
"""Extract audio and video into ./audio.mp3 and ./video.mp4"""
|
||||
audio_path = "audio.mp3"
|
||||
video_path = "video.mp4"
|
||||
subprocess.run(
|
||||
[
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-i", input_path,
|
||||
|
||||
@dataclass
|
||||
class AgentMessage:
|
||||
content: str
|
||||
"""Content of the message"""
|
||||
# Audio
|
||||
"-map", "0:a:0",
|
||||
"-vn",
|
||||
"-c:a", "libmp3lame",
|
||||
"-q:a", "2",
|
||||
audio_path,
|
||||
|
||||
role: Literal["system", "assistant", "user"]
|
||||
"""Who sent the message"""
|
||||
# Video
|
||||
"-map", "0:v:0",
|
||||
"-an",
|
||||
"-c:v", "libx264",
|
||||
"-crf", "18",
|
||||
"-preset", "fast",
|
||||
video_path,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
return audio_path, video_path
|
||||
|
||||
@dataclass
|
||||
class TimelineProcessingResult:
|
||||
events: list[TimelineEvent]
|
||||
"""List of events"""
|
||||
|
||||
desired_events: list[TimelineEvent]
|
||||
"""List of events desired for existance"""
|
||||
def ffmpeg_to_mp3(input_path: str) -> str:
|
||||
"""Convert `input_path` path to mp3 and save it at ./audio.mp3"""
|
||||
output_path = "audio.mp3"
|
||||
subprocess.run(
|
||||
[
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-i", input_path,
|
||||
"-vn",
|
||||
"-c:a", "libmp3lame",
|
||||
"-q:a", "2",
|
||||
output_path,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
return output_path
|
||||
Reference in New Issue
Block a user