-
-
Notifications
You must be signed in to change notification settings - Fork 4
Add horizontal (16:9) and square clip formats #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||||||||||||||
| """Output format specifications — the single source of truth for clip dimensions. | ||||||||||||||||||
|
|
||||||||||||||||||
| Every aspect-ratio decision (crop target, caption geometry, duration bounds, | ||||||||||||||||||
| which scoring profile applies) derives from a FormatSpec so the render pipeline | ||||||||||||||||||
| is parameterized on format instead of hardcoding 1080x1920 per call site. | ||||||||||||||||||
| """ | ||||||||||||||||||
|
|
||||||||||||||||||
| from dataclasses import dataclass | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| @dataclass(frozen=True) | ||||||||||||||||||
| class FormatSpec: | ||||||||||||||||||
| name: str | ||||||||||||||||||
| width: int | ||||||||||||||||||
| height: int | ||||||||||||||||||
| reframe: bool | ||||||||||||||||||
| caption_profile: str | ||||||||||||||||||
| dur_min: int | ||||||||||||||||||
| dur_max: int | ||||||||||||||||||
| target_min: int | ||||||||||||||||||
| target_max: int | ||||||||||||||||||
| score_key: str | ||||||||||||||||||
|
|
||||||||||||||||||
| @property | ||||||||||||||||||
| def dims(self) -> tuple[int, int]: | ||||||||||||||||||
| return (self.width, self.height) | ||||||||||||||||||
|
|
||||||||||||||||||
| @property | ||||||||||||||||||
| def ratio(self) -> float: | ||||||||||||||||||
| return self.width / self.height | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| FORMATS = { | ||||||||||||||||||
| "vertical": FormatSpec( | ||||||||||||||||||
| name="vertical", | ||||||||||||||||||
| width=1080, height=1920, | ||||||||||||||||||
| reframe=True, | ||||||||||||||||||
| caption_profile="vertical", | ||||||||||||||||||
| dur_min=20, dur_max=45, | ||||||||||||||||||
| target_min=20, target_max=35, | ||||||||||||||||||
| score_key="vertical_score", | ||||||||||||||||||
| ), | ||||||||||||||||||
| "horizontal": FormatSpec( | ||||||||||||||||||
| name="horizontal", | ||||||||||||||||||
| width=1920, height=1080, | ||||||||||||||||||
| reframe=False, | ||||||||||||||||||
| caption_profile="lower_third", | ||||||||||||||||||
| dur_min=60, dur_max=300, | ||||||||||||||||||
| target_min=90, target_max=240, | ||||||||||||||||||
| score_key="horizontal_score", | ||||||||||||||||||
| ), | ||||||||||||||||||
| "square": FormatSpec( | ||||||||||||||||||
| name="square", | ||||||||||||||||||
| width=1080, height=1080, | ||||||||||||||||||
| reframe=True, | ||||||||||||||||||
| caption_profile="center", | ||||||||||||||||||
| dur_min=20, dur_max=45, | ||||||||||||||||||
| target_min=20, target_max=35, | ||||||||||||||||||
| score_key="vertical_score", | ||||||||||||||||||
| ), | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| DEFAULT_FORMAT = "vertical" | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| def get_format(name: str | None) -> FormatSpec: | ||||||||||||||||||
| return FORMATS.get(name or DEFAULT_FORMAT, FORMATS[DEFAULT_FORMAT]) | ||||||||||||||||||
|
Comment on lines
+66
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Invalid
🛡️ Proposed fix to raise on unknown format def get_format(name: str | None) -> FormatSpec:
- return FORMATS.get(name or DEFAULT_FORMAT, FORMATS[DEFAULT_FORMAT])
+ key = name or DEFAULT_FORMAT
+ try:
+ return FORMATS[key]
+ except KeyError:
+ raise ValueError(f"Unknown format '{name}'. Valid formats: {', '.join(FORMATS)}")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: nmbrthirteen/podcli
Length of output: 1598
🏁 Script executed:
Repository: nmbrthirteen/podcli
Length of output: 19096
🏁 Script executed:
Repository: nmbrthirteen/podcli
Length of output: 10124
🏁 Script executed:
Repository: nmbrthirteen/podcli
Length of output: 17619
Thread clip-suggestion bounds through the selected format.
backend/services/claude_suggest.pystill imports these vertical-only aliases and uses them for both prompt limits and runtime filtering, whilehandle_suggest_clips()passes no format. Horizontal/square runs can still be clamped to vertical duration caps.🤖 Prompt for AI Agents