78 lines
1.9 KiB
Python
78 lines
1.9 KiB
Python
from dataclasses import dataclass
|
|
from typing import Literal, Any
|
|
from pydantic import BaseModel
|
|
import subprocess
|
|
|
|
|
|
class Event(BaseModel):
|
|
"""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 start (or happen, if `duration` is 0)"""
|
|
|
|
duration: float
|
|
"""How long did the event last (0 if can't apply)"""
|
|
|
|
text: str
|
|
"""Textual representation of the event (or data in `payload`, if it is not None)"""
|
|
|
|
payload: str | None
|
|
"""Payload of the event. `None` for `voice`, image path for `vis`, OCR result for `ocr`"""
|
|
|
|
class Timeline(BaseModel):
|
|
"""Timeline of events"""
|
|
|
|
events: list[Event]
|
|
"""Events of the timeline"""
|
|
|
|
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,
|
|
|
|
# Audio
|
|
"-map", "0:a:0",
|
|
"-vn",
|
|
"-c:a", "libmp3lame",
|
|
"-q:a", "2",
|
|
audio_path,
|
|
|
|
# Video
|
|
"-map", "0:v:0",
|
|
"-an",
|
|
"-c:v", "libx264",
|
|
"-crf", "18",
|
|
"-preset", "fast",
|
|
video_path,
|
|
],
|
|
check=True,
|
|
)
|
|
return audio_path, video_path
|
|
|
|
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 |