Skip to content
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

Correction of FrameUtility V3 #48

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7cf2bae
Create Proof algorithm - ms_to_frames.md
moi15moi Nov 7, 2023
3e3d826
Create timestamps.py
moi15moi Nov 7, 2023
925f2f4
[convert] time - round ms when returning a ass timestamps string
moi15moi Nov 7, 2023
9ff7a2f
[convert] Add TimeType class
moi15moi Nov 7, 2023
5ab3205
[convert] ms_to_frames - New algorithm to match TimeType and Timestam…
moi15moi Nov 7, 2023
324644d
[convert] frames_to_ms - New algorithm to match TimeType and Timestam…
moi15moi Nov 7, 2023
18e61f0
[convert] move_ms_to_frame - New algorithm to match TimeType and Time…
moi15moi Nov 7, 2023
c9d17fc
[utils] Update FrameUtility to use Timestamps class
moi15moi Nov 7, 2023
826ecb8
[__init__] Add TimeType, RoundingMethod and Timestamps
moi15moi Nov 7, 2023
013a108
Create test_timestamps.py
moi15moi Nov 7, 2023
eb20fb8
Create test_timestamps_file_parser.py
moi15moi Nov 7, 2023
41f71b5
[test_convert] Import sys
moi15moi Nov 7, 2023
9d580da
[test_convert] Add test for ms_to_frames and frames_to_ms
moi15moi Nov 7, 2023
acf5284
[test_utils] test_frame_utility - Correct partially test
moi15moi Nov 7, 2023
d7179f2
Add required file for the new test
moi15moi Nov 7, 2023
cd8dae9
Update example to use the new version of the FrameUtility
moi15moi Nov 7, 2023
1fb252d
[ci] Add ffmpeg requirements for all platform
moi15moi Nov 7, 2023
3664dec
Format code with Black
moi15moi Nov 7, 2023
dd921b9
[timestamps] Move method validate to constructor & update test
moi15moi Nov 11, 2023
a6894d3
[timestamps] Update ffmpeg floor documentation
moi15moi Nov 11, 2023
818e5c4
[timestamps] Update VLC floor documentation
moi15moi Nov 11, 2023
ad8a839
Move comment from FrameUtility to Timestmaps
moi15moi Nov 11, 2023
4b90898
[ci] Remove ffmpeg requirements for Windows
moi15moi Nov 11, 2023
5b45986
[timestamps] Change description of fpms parameter
moi15moi Nov 11, 2023
eac63a5
[timestamps] Raise AttributeError if rounding_method is modified
moi15moi Nov 11, 2023
323da16
[convert] time - Add an explanation for the method of rounding
moi15moi Nov 12, 2023
242f7a4
Remove approximate and update test accordingly
moi15moi Nov 12, 2023
04d30fa
Update call to Convert.frames_to_ms & Convert.ms_to_frames to match n…
moi15moi Nov 16, 2023
546597c
[timestamps] from_video_file - Use mkvextract if the file is a mkv
moi15moi Dec 28, 2023
442a957
[Proof algorithm - ms_to_frames.md] Add specific formula for rounding…
moi15moi Jul 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 python3-gi python3-gi-cairo
sudo apt-get install libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 python3-gi python3-gi-cairo ffmpeg
- name: Install platform-specific requirements (macOS) # Note: brew is very slow sometimes. TODO: speedup brew by using caching.
if: matrix.os == 'macos-latest'
run: brew install python py3cairo pygobject3 pango

run: brew install python py3cairo pygobject3 pango ffmpeg
- name: Install fonts (non-Windows)
if: matrix.os != 'windows-latest'
run: |
Expand Down
55 changes: 55 additions & 0 deletions docs/Proof algorithm - ms_to_frames.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ms_to_frames
To convert an frame to an ms, here is the formula: $$ms = frame * {1 \over fps} * 1000$$
But depending on what the user want, he may need to floor the result or round it (see docs of timestamps.py for more information)
Important to note, $frame \in \mathbb{N}$. This means we need to take the **integer** between the 2 bounds of the inequations that are detailed below.

## Explanation for rounding method
$$ms = \text{round}(frame * {1 \over fps} * 1000)$$

Important to note, here the rounding method round up, so, if it encounter $round(x.5)$, it will become $x + 1$

From the previous equation, we can deduce this:
$$ms - 0.5 \le frame * {1 \over fps} * 1000 < ms + 0.5$$

And from the previous inequation, we can isolate $frame$ like this:
$$(ms - 0.5) * fps * {1 \over 1000} \le frame < (ms + 0.5) * fps * {1 \over 1000}$$

Algorithm:
```py
# We use the upper bound
upper_bound = (ms + 0.5) * fps * 1/1000
# Then, we trunc the result
trunc_frame = int(upper_bound)

# If the upper_bound equals to the trunc_frame, this means that we don't respect the inequation because it is "greater than", not "greater than or equals".
# So if it happens, this means we need to return the previous frame
if upper_bound == trunc_frame:
return trunc_frame - 1
else:
return trunc_frame
```


## Explanation for floor method
$$ms = \lfloor frame * {1 \over fps} * 1000 \rfloor$$

From the previous equation, we can deduce this:
$$ms \le frame * {1 \over fps} * 1000 < ms + 1$$

And from the previous inequation, we can isolate $frame$ like this:
$$ms * fps * {1 \over 1000} \le frame < (ms + 1) * fps * {1 \over 1000}$$

Algorithm:
```py
# We use the upper bound
upper_bound = (ms + 1) * fps * 1/1000
# Then, we trunc the result
trunc_frame = int(upper_bound)

# If the upper_bound equals to the trunc_frame, this means that we don't respect the inequation because it is "greater than", not "greater than or equals".
# So if it happens, this means we need to return the previous frame
if upper_bound == trunc_frame:
return trunc_frame - 1
else:
return trunc_frame
```
8 changes: 7 additions & 1 deletion examples/2 - Beginner/2 - Utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
As exercise, you can try to transform it into an horizontal one :)
"""

from fractions import Fraction
from pyonfx import *
import random

io = Ass("in.ass")
meta, styles, lines = io.get_data()

# Let's load the timestamps
timestamps_list = Timestamps.from_fps(Fraction(24000, 1001))


def romaji(line, l):
for syl in Utils.all_non_empty(line.syls):
Expand All @@ -44,7 +48,9 @@ def romaji(line, l):
# Main Effect
# Let's create a FrameUtility object and set up a radius for the random positions
FU = FrameUtility(
line.start_time + syl.start_time, line.start_time + syl.end_time
line.start_time + syl.start_time,
line.start_time + syl.end_time,
timestamps_list,
)
radius = 2

Expand Down
12 changes: 10 additions & 2 deletions examples/2 - Beginner/3 - Variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
It could look like much code for such a simple effect, but it's needed and an easy method with much potential for extensions.
"""

from fractions import Fraction
from pyonfx import *
import random
import math
Expand All @@ -27,6 +28,9 @@
star = Shape.star(5, 4, 10)
CU = ColorUtility(lines)

# Let's load the timestamps
timestamps_list = Timestamps.from_fps(Fraction(24000, 1001))


def romaji(line, l):
# Setting up a delay, we will use it as duration time of the leadin and leadout effects
Expand Down Expand Up @@ -107,7 +111,9 @@ def romaji(line, l):
# Jump-in to the first syl
jump_height = 18
if syl.i == 0:
FU = FrameUtility(line.start_time - line.leadin / 2, line.start_time)
FU = FrameUtility(
line.start_time - line.leadin / 2, line.start_time, timestamps_list
)
for s, e, i, n in FU:
l.start_time = s
l.end_time = e
Expand All @@ -133,7 +139,9 @@ def romaji(line, l):
else syl.width
)
FU = FrameUtility(
line.start_time + syl.start_time, line.start_time + syl.end_time
line.start_time + syl.start_time,
line.start_time + syl.end_time,
timestamps_list,
)
for s, e, i, n in FU:
l.start_time = s
Expand Down
8 changes: 7 additions & 1 deletion examples/3 - Advanced/1 - WIP.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from fractions import Fraction
from pyonfx import *
import random

io = Ass("in.ass")
meta, styles, lines = io.get_data()

# Let's load the timestamps
timestamps_list = Timestamps.from_fps(Fraction(24000, 1001))

circle = Shape.ellipse(20, 20)


Expand All @@ -29,7 +33,9 @@ def romaji(line, l):
l.layer = 1

FU = FrameUtility(
line.start_time + syl.start_time, line.start_time + syl.end_time
line.start_time + syl.start_time,
line.start_time + syl.end_time,
timestamps_list,
)
rand = random.uniform(-10, 10)

Expand Down
3 changes: 2 additions & 1 deletion pyonfx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from .font_utility import Font
from .ass_core import Ass, Meta, Style, Line, Word, Syllable, Char
from .convert import Convert, ColorModel
from .convert import Convert, ColorModel, TimeType
from .shape import Shape
from .timestamps import RoundingMethod, Timestamps
from .utils import Utils, FrameUtility, ColorUtility

__version__ = "0.9.13"
Loading
Loading