Coverage for src/blob_dict/blob/video.py: 0%
35 statements
« prev ^ index » next coverage.py v7.8.1, created at 2025-06-04 23:47 -0700
« prev ^ index » next coverage.py v7.8.1, created at 2025-06-04 23:47 -0700
1from __future__ import annotations
3from pathlib import Path
4from typing import Self, override
6from moviepy.video.io.VideoFileClip import VideoFileClip
7from moviepy.video.VideoClip import VideoClip
9from . import BytesBlob
10from .audio_video import read_from_clip
13class VideoBlob(BytesBlob):
14 def __init__(
15 self,
16 blob: bytes | VideoClip,
17 *,
18 delete_temp_clip_file: bool = False,
19 ) -> None:
20 if isinstance(blob, VideoClip):
21 blob = read_from_clip(
22 blob,
23 ".mp4",
24 delete_temp_clip_file=delete_temp_clip_file,
25 )
27 super().__init__(blob)
29 def as_video(self, filename: str) -> VideoFileClip:
30 Path(filename).write_bytes(self._blob_bytes)
32 return VideoFileClip(filename)
34 @override
35 def __repr__(self) -> str:
36 return f"{self.__class__.__name__}(...)"
38 @classmethod
39 @override
40 def load(cls: type[Self], f: Path | str) -> Self:
41 f = Path(f).expanduser()
43 if f.suffix.lower() == ".mp4":
44 return cls(f.read_bytes())
46 clip = VideoFileClip(str(f))
47 blob = cls(clip)
48 clip.close()
50 return blob
52 @override
53 def dump(self, f: Path | str) -> None:
54 f = Path(f).expanduser()
55 if f.suffix.lower() != ".mp4":
56 msg = "Only MP4 file is supported."
57 raise ValueError(msg)
59 f.write_bytes(self.as_bytes())