-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSMPTE.py
executable file
·117 lines (78 loc) · 2.75 KB
/
SMPTE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Converts frames to SMPTE timecode of arbitrary frame rate and back.
# Copyright 2021, Igor Riđanović, [email protected], Meta Fide
class SMPTE(object):
'''Frames to SMPTE timecode converter and reverse.'''
def __init__(self):
self.fps = 24
self.df = False
def getframes(self, tc):
'''Converts SMPTE timecode to frame count.'''
if int(tc[9:]) > self.fps:
raise ValueError ('SMPTE timecode to frame rate mismatch.', tc, self.fps)
hours = int(tc[:2])
minutes = int(tc[3:5])
seconds = int(tc[6:8])
frames = int(tc[9:])
totalMinutes = int(60 * hours + minutes)
# Drop frame calculation using the Duncan/Heidelberger method.
if self.df:
dropFrames = int(round(self.fps * 0.066666))
timeBase = int(round(self.fps))
hourFrames = int(timeBase * 60 * 60)
minuteFrames = int(timeBase * 60)
frm = int(((hourFrames * hours) + (minuteFrames * minutes) + (timeBase * seconds) + frames) - (dropFrames * (totalMinutes - (totalMinutes // 10))))
# Non drop frame calculation.
else:
self.fps = int(round(self.fps))
frm = int((totalMinutes * 60 + seconds) * self.fps + frames)
return frm
def gettc(self, frames):
'''Converts frame count to SMPTE timecode.'''
frames = abs(frames)
# Drop frame calculation using the Duncan/Heidelberger method.
if self.df:
spacer = ':'
spacer2 = ';'
dropFrames = int(round(self.fps * .066666))
framesPerHour = int(round(self.fps * 3600))
framesPer24Hours = framesPerHour * 24
framesPer10Minutes = int(round(self.fps * 600))
framesPerMinute = int(round(self.fps) * 60 - dropFrames)
frames = frames % framesPer24Hours
d = frames // framesPer10Minutes
m = frames % framesPer10Minutes
if m > dropFrames:
frames = frames + (dropFrames * 9 * d) + dropFrames * ((m - dropFrames) // framesPerMinute)
else:
frames = frames + dropFrames * 9 * d
frRound = int(round(self.fps))
hr = int(frames // frRound // 60 // 60)
mn = int((frames // frRound // 60) % 60)
sc = int((frames // frRound) % 60)
fr = int(frames % frRound)
# Non drop frame calculation.
else:
self.fps = int(round(self.fps))
spacer = ':'
spacer2 = spacer
frHour = self.fps * 3600
frMin = self.fps * 60
hr = int(frames // frHour)
mn = int((frames - hr * frHour) // frMin)
sc = int((frames - hr * frHour - mn * frMin) // self.fps)
fr = int(round(frames - hr * frHour - mn * frMin - sc * self.fps))
# Return SMPTE timecode string.
return(
str(hr).zfill(2) + spacer +
str(mn).zfill(2) + spacer +
str(sc).zfill(2) + spacer2 +
str(fr).zfill(2)
)
if __name__ == '__main__':
# Drop frame example.
s = SMPTE()
s.fps = 29.97
s.df = True
print(s.gettc(1800))