sprocket-systems.coda.sdk 1.3.0__py3-none-any.whl → 1.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
coda/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # The versions below will be replaced automatically in CI.
2
2
  # You do not need to modify any of the versions below.
3
- __version__ = "1.3.0"
3
+ __version__ = "1.3.2"
4
4
  CODA_APP_SUITE_VERSION = "+coda-1.72.0"
5
5
  FINAL_VERSION = __version__ + CODA_APP_SUITE_VERSION
6
6
 
coda/sdk.py CHANGED
@@ -203,14 +203,18 @@ class CodaEssence(object):
203
203
  opts = F['opts']
204
204
  f = F['url']
205
205
 
206
- label =""
207
- chlabels = ['Lsr','Rsr','Lts','Rts','Lss','Rss','Lfe','Ls','Rs','L','C','R']
208
- for ch in chlabels:
209
- if '.'+ch.upper()+'.' in f.upper():
210
- label = ch[0:1].upper()+ch[1:].lower()
211
- if ch=='Lfe':
212
- label = 'LFE'
213
- break
206
+ if 'channel_label' in F:
207
+ label = F['channel_label']
208
+ else:
209
+ label =""
210
+ chlabels = ['Lsr','Rsr','Lts','Rts','Lss','Rss','Lfe','Ls','Rs','L','C','R']
211
+ for ch in chlabels:
212
+ if '.'+ch.upper()+'.' in f.upper():
213
+ label = ch[0:1].upper()+ch[1:].lower()
214
+ if ch=='Lfe':
215
+ label = 'LFE'
216
+ break
217
+
214
218
  res ={
215
219
  'bit_depth' : quant,
216
220
  'sample_rate' : srate,
coda/tc_tools.py CHANGED
@@ -1,50 +1,50 @@
1
1
  ###########################################################
2
2
  # Application Name : tc_tools.py
3
3
  # Author : Skywalker Dev Labs
4
- # Date : December 13th, 2024
4
+ # Date : September 4th, 2025
5
5
  # Description : tools for calculations with timecode
6
6
  # Location : Original is kept in 1031-tc_tools
7
7
  #
8
- # Frame rate tools:
9
- # string float_to_v_fr_string(double v_fr) <- does not yet exist (29.97df can not be distinguished from 29.97)
10
- # double v_fr_string_to_float(v_fr_string)
11
- # double v_fr_string_to_non_pulldown_float(v_fr_string)
12
- # Conversion to/from:
13
- # double vid_frames_to_audio_frames(v_fs, v_fr_string, a_fr)
14
- # double audio_frames_to_vid_frames(a_fs, v_fr_string, a_fr)
15
- # double vid_frames_to_time_seconds(v_fs, v_fr_string)
16
- # double time_seconds_to_vid_frames(time_s, v_fr_string)
17
- # double vid_frames_to_timecode_seconds(v_fs, v_fr_string)
18
- # double timecode_seconds_to_vid_frames(timecode_s, v_fr_string) <- does not yet exist
19
- # Specialty:
20
- # double vid_frames_align_to_audio_frames(v_fs, v_fr_string, a_fr, pad_or_trim)
21
- # Timecode/frame rate tools:
22
- # General:
23
- # bool tc_is_whole_video_frames(tc, v_fr_string)
24
- # string tc_round(tc, partial_v_fr_digits, v_fr_string)
25
- # Conversion to/from:
26
- # double tc_to_vid_frames(tc, v_fr_string)
27
- # string vid_frames_to_tc(v_fs, v_fr_string)
28
- # double tc_to_time_seconds(tc, v_fr_string)
29
- # string time_seconds_to_tc(time_s, v_fr_string)
30
- # double tc_to_audio_frames(tc, v_fr_string, a_fr)
31
- # string audio_frames_to_tc(a_fs, v_fr_string, a_fr)
32
- # double tc_add(tc_addend_a, tc_addend_b, v_fr_string)
33
- # double tc_sub(tc_minuend, tc_subtrahend, v_fr_string)
34
- #
35
- # Utilites
36
- # string tc_tools_version()
37
- # bool compare_with_precision(float_a, float_b, precision) (this should be removed!!!)
38
- #
39
- # Abbreviations used in this file:
40
- # v_fr video frame rate as a double "(v)ideo (f)rame (r)ate"
41
- # v_fs video frame count as a double "(v)ideo (f)rame(s)"
42
- # a_fr audio frame rate as a double "(a)udio (f)rame (r)ate"
43
- # a_fs audio frame count as a double "(a)udio (f)rame(s)"
44
- # tc timecode as a string in the form "HR:MN:SC:FR.partial_frames"
8
+ # Frame rate tools:
9
+ # string float_to_v_fr_string(double v_fr) <- does not yet exist (29.97df can not be distinguished from 29.97)
10
+ # double v_fr_string_to_float(v_fr_string)
11
+ # double v_fr_string_to_non_pulldown_float(v_fr_string)
12
+ # Conversion to/from:
13
+ # double vid_frames_to_audio_frames(v_fs, v_fr_string, a_fr)
14
+ # double audio_frames_to_vid_frames(a_fs, v_fr_string, a_fr)
15
+ # double vid_frames_to_time_seconds(v_fs, v_fr_string)
16
+ # double time_seconds_to_vid_frames(time_s, v_fr_string)
17
+ # double vid_frames_to_timecode_seconds(v_fs, v_fr_string)
18
+ # double timecode_seconds_to_vid_frames(timecode_s, v_fr_string)
19
+ # Specialty:
20
+ # double vid_frames_align_to_audio_frames(v_fs, v_fr_string, a_fr, pad_or_trim)
21
+ # Timecode/frame rate tools:
22
+ # General:
23
+ # bool tc_is_whole_video_frames(tc, v_fr_string)
24
+ # string tc_round(tc, partial_v_fr_digits, v_fr_string)
25
+ # Conversion to/from:
26
+ # double tc_to_vid_frames(tc, v_fr_string)
27
+ # string vid_frames_to_tc(v_fs, v_fr_string)
28
+ # double tc_to_time_seconds(tc, v_fr_string)
29
+ # string time_seconds_to_tc(time_s, v_fr_string)
30
+ # double tc_to_audio_frames(tc, v_fr_string, a_fr)
31
+ # string audio_frames_to_tc(a_fs, v_fr_string, a_fr)
32
+ # double tc_add(tc_addend_a, tc_addend_b, v_fr_string)
33
+ # double tc_sub(tc_minuend, tc_subtrahend, v_fr_string)
34
+ #
35
+ # Utilites
36
+ # string tc_tools_version()
37
+ # tc_hr, tc_min, tc_sec, tc_frames, tc_partial_frames parse_tc_string(tc, v_fr_string)
38
+ #
39
+ # Abbreviations used in this file:
40
+ # v_fr video frame rate as a double "(v)ideo (f)rame (r)ate"
41
+ # v_fs video frame count as a double "(v)ideo (f)rame(s)"
42
+ # a_fr audio frame rate as a double "(a)udio (f)rame (r)ate"
43
+ # a_fs audio frame count as a double "(a)udio (f)rame(s)"
44
+ # tc timecode as a string in the form "HR:MN:SC:FR.partial_frames"
45
45
  # time_s time in real seconds (not timecode seconds)
46
46
  # timecode_s time in timecode seconds
47
- # v_fr_string video frame rate as a string, one of:
47
+ # v_fr_string video frame rate as a string, one of:
48
48
  # VID_FRAME_RATE_STRING_2397
49
49
  # VID_FRAME_RATE_STRING_2400
50
50
  # VID_FRAME_RATE_STRING_2500
@@ -54,36 +54,30 @@
54
54
  # pad_or_trim add or trim to align video frames to audio frames. one of:
55
55
  # 'pad'
56
56
  # 'trim'
57
- #
58
- # Notes:
59
- # partial_frames: is a fraction of the given frame rate.
60
- # For example: "00:00:00:03.141" @ 24.00 fps is equal to 3.141 video frames.
61
- #
62
- # timecode_seconds: the number of seconds at the timecode rate... not the clock on the wall.
63
- # timecode_seconds will differ from time_s for pull-down rates (23, 29, and 29DF)
64
- # 29.97df is a special case where timecode_seconds is equal to the number of video frames at the timecode rate.
65
- # And so:
66
- # 00:01:00;02 @29.97df is equal to 60.0000000 timecode_seconds.
67
- # 00:01:00:00 @29.97 is equal to 60.0000000 timecode_seconds.
68
- # 00:01:00:02 @29.97 is equal to 60.0666667 timecode_seconds.
69
- # 00:01:00:00 @30.00 is equal to 60.0000000 timecode_seconds.
70
- # partial_v_fr_digits: an int, the number of decimal places to round to
71
- #
72
- # As of 2023-05-09:
73
- # vid_frames_to_tc will round to the nearest thousandth of a partial frame (using const PARTIAL_FRAME_NUMBER_OF_DIGITS for precision)
74
- # time_seconds_to_tc will round to the nearest thousandth of a partial frame (using const PARTIAL_FRAME_NUMBER_OF_DIGITS for precision)
57
+ #
58
+ # Notes:
59
+ # partial_frames: is a fraction of the given frame rate.
60
+ # For example: "00:00:00:03.141" @ 24.00 fps is equal to 3.141 video frames.
61
+ #
62
+ # timecode_seconds: the number of seconds at the timecode rate... not the clock on the wall.
63
+ # timecode_seconds will differ from time_s for pull-down rates (23, 29, and 29DF)
64
+ # 29.97df is a special case where timecode_seconds is equal to the number of video frames at the timecode rate.
65
+ # And so:
66
+ # 00:01:00;02 @29.97df is equal to 60.0000000 timecode_seconds.
67
+ # 00:01:00:00 @29.97 is equal to 60.0000000 timecode_seconds.
68
+ # 00:01:00:02 @29.97 is equal to 60.0666667 timecode_seconds.
69
+ # 00:01:00:00 @30.00 is equal to 60.0000000 timecode_seconds.
70
+ # partial_v_fr_digits: an int, the number of decimal places to round to
71
+ #
72
+ # As of 2023-05-09:
73
+ # vid_frames_to_tc will round to the nearest thousandth of a partial frame (using const PARTIAL_FRAME_NUMBER_OF_DIGITS for precision)
74
+ # time_seconds_to_tc will round to the nearest thousandth of a partial frame (using const PARTIAL_FRAME_NUMBER_OF_DIGITS for precision)
75
75
  ###########################################################
76
76
 
77
77
  from decimal import Decimal
78
78
 
79
- DEBUG_vid_frames_to_tc = False
80
- DEBUG_tc_components_to_tc = False
81
- DEBUG_audio_frames_to_vid_frames = False
82
- DEBUG_tc_to_vid_frames = False
83
-
84
-
85
79
  def tc_tools_version():
86
- return "1.2.4"
80
+ return '1.3.2'
87
81
 
88
82
  # @abstract Video frame rates as strings use by tool
89
83
  # @discussion VID_FRAME_RATE_STRING_2997df is not fully supported
@@ -93,6 +87,9 @@ VID_FRAME_RATE_STRING_2500 = '25'
93
87
  VID_FRAME_RATE_STRING_2997 = '29'
94
88
  VID_FRAME_RATE_STRING_2997df = '29DF'
95
89
  VID_FRAME_RATE_STRING_3000 = '30'
90
+ VID_FRAME_RATE_STRING_4800 = '48'
91
+ VID_FRAME_RATE_STRING_5000 = '50'
92
+ VID_FRAME_RATE_STRING_6000 = '60'
96
93
 
97
94
  # delimeter to use when creating a 2997df tc string
98
95
  # this has no effect on reading a tc string (when reading, it can be either : or ;);
@@ -102,43 +99,87 @@ PARTIAL_FRAME_NUMBER_OF_DIGITS = 7
102
99
  ALIGN_VFS_ROUND_DIGITS = 9
103
100
 
104
101
 
102
+ valid_v_fr_strings = [
103
+ VID_FRAME_RATE_STRING_2397,
104
+ VID_FRAME_RATE_STRING_2400,
105
+ VID_FRAME_RATE_STRING_2500,
106
+ VID_FRAME_RATE_STRING_2997,
107
+ VID_FRAME_RATE_STRING_2997df,
108
+ VID_FRAME_RATE_STRING_3000,
109
+ VID_FRAME_RATE_STRING_4800,
110
+ VID_FRAME_RATE_STRING_5000,
111
+ VID_FRAME_RATE_STRING_6000,
112
+ ]
113
+
114
+
115
+ def v_fr_string_validate(v_fr_string):
116
+ """Validate v_fr_string and return an upper() version"""
117
+ v_fr_str_upper = v_fr_string.upper()
118
+ v_fr_str_okay = False
119
+ for v in valid_v_fr_strings:
120
+ if v == v_fr_str_upper:
121
+ v_fr_str_okay = True
122
+ break
123
+ if not v_fr_str_okay:
124
+ err_msg = ''.join(['tc_tools: frame rate not recognized = ', v_fr_string])
125
+ print(err_msg)
126
+ raise Exception(err_msg)
127
+ return v_fr_str_upper
128
+
129
+
105
130
  def v_fr_string_to_non_pulldown_float(v_fr_string):
106
131
  """Convert from one of the enum frame rate strings to the non-pulldown float value."""
107
- if v_fr_string == VID_FRAME_RATE_STRING_2397:
132
+ v_fr_str_upper = v_fr_string_validate(v_fr_string)
133
+ if v_fr_str_upper == VID_FRAME_RATE_STRING_2397:
108
134
  v_fr = 24.0
109
- elif v_fr_string == VID_FRAME_RATE_STRING_2400:
135
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2400:
110
136
  v_fr = 24.0
111
- elif v_fr_string == VID_FRAME_RATE_STRING_2500:
137
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2500:
112
138
  v_fr = 25.0
113
- elif v_fr_string == VID_FRAME_RATE_STRING_2997:
139
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2997:
114
140
  v_fr = 30.0
115
- elif v_fr_string == VID_FRAME_RATE_STRING_2997df:
141
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2997df:
116
142
  v_fr = 30.0
117
- elif v_fr_string == VID_FRAME_RATE_STRING_3000:
143
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_3000:
118
144
  v_fr = 30.0
145
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_4800:
146
+ v_fr = 48.0
147
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_5000:
148
+ v_fr = 50.0
149
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_6000:
150
+ v_fr = 60.0
119
151
  else:
120
- print("tc_tools: frame rate not recognized = " , v_fr_string)
121
- raise;
152
+ err_msg = ''.join(['tc_tools: frame rate not recognized = ', v_fr_string, ' This should never happen.'])
153
+ print(err_msg)
154
+ raise Exception(err_msg)
122
155
  return v_fr
123
156
 
124
157
 
125
158
  def v_fr_string_to_float(v_fr_string):
126
159
  """Convert from one of the enum frame rate strings to the actual float value."""
127
- if v_fr_string == VID_FRAME_RATE_STRING_2397:
160
+ v_fr_str_upper = v_fr_string_validate(v_fr_string)
161
+ if v_fr_str_upper == VID_FRAME_RATE_STRING_2397:
128
162
  v_fr = 24.0/1.001
129
- elif v_fr_string == VID_FRAME_RATE_STRING_2400:
163
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2400:
130
164
  v_fr = 24.0
131
- elif v_fr_string == VID_FRAME_RATE_STRING_2500:
165
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2500:
132
166
  v_fr = 25.0
133
- elif v_fr_string == VID_FRAME_RATE_STRING_2997:
167
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2997:
134
168
  v_fr = 30/1.001
135
- elif v_fr_string == VID_FRAME_RATE_STRING_2997df:
169
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_2997df:
136
170
  v_fr = 30/1.001
137
- elif v_fr_string == VID_FRAME_RATE_STRING_3000:
171
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_3000:
138
172
  v_fr = 30.0
173
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_4800:
174
+ v_fr = 48.0
175
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_5000:
176
+ v_fr = 50.0
177
+ elif v_fr_str_upper == VID_FRAME_RATE_STRING_6000:
178
+ v_fr = 60.0
139
179
  else:
140
- print("tc_tools: frame rate not recognized = " , v_fr_string)
141
- raise;
180
+ err_msg = ''.join(['tc_tools: frame rate not recognized = ', v_fr_string, ' This should never happen.'])
181
+ print(err_msg)
182
+ raise Exception(err_msg)
142
183
  return v_fr
143
184
 
144
185
 
@@ -148,54 +189,89 @@ def vid_frames_to_audio_frames(v_fs, v_fr_string, a_fr):
148
189
  a_fs = v_fs * ( a_fr / v_fr )
149
190
  return a_fs
150
191
 
192
+ def audio_frames_to_vid_frames(a_fs, v_fr_string, a_fr):
193
+ """Convert from number of audio frames to video frames."""
194
+ v_fr = v_fr_string_to_float(v_fr_string)
195
+ v_fs = a_fs * (v_fr / a_fr)
196
+ return v_fs
197
+
151
198
 
152
199
  def vid_frames_to_time_seconds(v_fs, v_fr_string):
153
200
  """Convert from number of video frames to time in seconds."""
154
201
  v_fr = v_fr_string_to_float(v_fr_string)
155
202
  return v_fs / v_fr
156
203
 
204
+ def time_seconds_to_vid_frames(time_s, v_fr_string):
205
+ """Convert from time in seconds to number of video frames."""
206
+ v_fr = v_fr_string_to_float(v_fr_string)
207
+ return v_fr * time_s
208
+
157
209
 
158
210
  def vid_frames_to_timecode_seconds(v_fs, v_fr_string):
159
211
  """Convert from number of video frames to time in timcode seconds."""
160
- #if v_fr_string == VID_FRAME_RATE_STRING_2997df:
161
- if False:
162
- # for every 1800 video frames, add two video frames
163
- minutes_fr_to_add = int(v_fs/1800) * 2
164
- #print('vid_frames_to_timecode_seconds(): minutes_fr_to_add =',minutes_fr_to_add)
165
- # for every 18000 video frames, take away two video frames
166
- minutes_fr_to_remove = int(v_fs/18000) * 2
167
- #print('vid_frames_to_timecode_seconds(): minutes_fr_to_remove =',minutes_fr_to_remove)
168
- v_fs += minutes_fr_to_add
169
- v_fs -= minutes_fr_to_remove
170
212
  v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
171
213
  return v_fs / v_fr
172
214
 
173
-
174
- def time_seconds_to_vid_frames(time_s, v_fr_string):
175
- """Convert from time in seconds to number of video frames."""
176
- v_fr = v_fr_string_to_float(v_fr_string)
215
+ def timecode_seconds_to_vid_frames(time_s, v_fr_string):
216
+ """Convert from time in timecode seconds to number of video frames."""
217
+ v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
177
218
  return v_fr * time_s
178
219
 
179
220
 
180
- def audio_frames_to_vid_frames(a_fs, v_fr_string, a_fr):
181
- """Convert from number of audio frames to video frames."""
182
- if DEBUG_audio_frames_to_vid_frames:
183
- print('tc_tools: audio_frames_to_vid_frames: Top of Function.')
184
- print('tc_tools: audio_frames_to_vid_frames() a_fs =', a_fs)
185
- print('tc_tools: audio_frames_to_vid_frames() v_fr_string =', v_fr_string)
186
- print('tc_tools: audio_frames_to_vid_frames() a_fr =', a_fr)
187
- v_fr = v_fr_string_to_float(v_fr_string);
188
- v_fs = a_fs * (v_fr / a_fr);
189
- if DEBUG_audio_frames_to_vid_frames:
190
- print('tc_tools: audio_frames_to_vid_frames() v_fs =', v_fs)
191
- print('tc_tools: audio_frames_to_vid_frames: Bottom of Function.')
192
- return v_fs;
193
-
221
+ ############################################################################################
222
+ # Local utility functions
223
+ ############################################################################################
194
224
 
195
225
  def is_float_whole_number(f):
196
226
  if f == round(f): return True
197
227
  return False
198
228
 
229
+ def tc_components_to_tc(tc_hr, tc_min, tc_sec, tc_fr, tc_partial_frames, v_fr_string):
230
+ """Assemble timecode components into a timecode string."""
231
+ # 2023-11-30 DRJ: need to accomodate 2997df
232
+ # if tc_partial_frames + tc_fr + tc_sec ends up adding to minutes, we need to make adjustments.
233
+ # v_fr_string = VID_FRAME_RATE_STRING_2997df
234
+ # tc_hr = 0
235
+ # tc_min = 0
236
+ # tc_sec = 59
237
+ # tc_fr = 30
238
+ # tc_partial_frames = 0
239
+ # the resulting tc would be 00:01:00:02
240
+ # 2024-05-10 DRJ: when tc_partial_frames was less than 0.0001, it was being written in exp notation.
241
+ # And so, I added the Decimal bits.
242
+ # 2025-01-07 DRJ: Decimal does some mangled rounding! 0.6 is printed ad 0.599999999999999999999
243
+ v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
244
+ sec_fr_delimiter = ':'
245
+ if v_fr_string == VID_FRAME_RATE_STRING_2997df:
246
+ sec_fr_delimiter = TC_TOOLS_29DF_SEC_FRAME_DELIM
247
+
248
+ while tc_partial_frames >= 1.0:
249
+ tc_fr += 1
250
+ tc_partial_frames -= 1.0
251
+ while tc_fr >= v_fr:
252
+ tc_sec += 1
253
+ tc_fr -= int(v_fr)
254
+ while tc_sec >= 60:
255
+ tc_min += 1
256
+ tc_sec -= 60
257
+ while tc_min >= 60:
258
+ tc_hr += 1
259
+ tc_min -= 60
260
+
261
+ tc = ''.join([ str(tc_hr).zfill(2), ':', str(tc_min).zfill(2), ':',str(tc_sec).zfill(2), sec_fr_delimiter, str(tc_fr).zfill(2)])
262
+ if tc_partial_frames > 0.0:
263
+ tc_partial_frames_string = str(tc_partial_frames).lstrip('0')
264
+ if tc_partial_frames < 0.0001:
265
+ tc_partial_frames_string = str(Decimal(tc_partial_frames)).lstrip('0')
266
+ if (len(tc_partial_frames_string) + 1) > PARTIAL_FRAME_NUMBER_OF_DIGITS:
267
+ tc_partial_frames_string = tc_partial_frames_string[0:PARTIAL_FRAME_NUMBER_OF_DIGITS + 1].rstrip('0')
268
+ tc = ''.join([tc,tc_partial_frames_string ])
269
+ return tc
270
+
271
+
272
+ ############################################################################################
273
+ # specialty and general conversion
274
+ ############################################################################################
199
275
 
200
276
  #
201
277
  # returns the number of video frames you must add or trim so that video and audio frames are aligned
@@ -204,16 +280,20 @@ def is_float_whole_number(f):
204
280
  # a_fr the audio frame rate
205
281
  # pad_or_trim either 'pad' or 'trim'
206
282
  def vid_frames_align_to_audio_frames(v_fs, v_fr_string, a_fr, pad_or_trim):
283
+ #booger
284
+ v_fr_str_upper = v_fr_string_validate(v_fr_string)
285
+
207
286
  rounded_v_fs = round(v_fs, ALIGN_VFS_ROUND_DIGITS)
208
287
  if pad_or_trim == 'pad':
209
288
  v_fs_to_add = 0.0
210
289
  if not is_float_whole_number(rounded_v_fs):
211
290
  v_fs_to_add += int(v_fs + 1) - v_fs
212
291
  v_fs_to_add = round(v_fs_to_add, ALIGN_VFS_ROUND_DIGITS)
213
- if (v_fr_string == VID_FRAME_RATE_STRING_2997) or (v_fr_string == VID_FRAME_RATE_STRING_2997df):
292
+ if (v_fr_str_upper == VID_FRAME_RATE_STRING_2997) or (v_fr_str_upper == VID_FRAME_RATE_STRING_2997df):
214
293
  if a_fr != 48000.0:
215
- print('tc_tools: vid_frames_align_to_audio_frames() currently only audio frame rate of 48000.0 is supported.')
216
- raise
294
+ err_msg = ''.join(['tc_tools: align_to_audio_frames: 29.97 and 29DF currently only audio frame rate of 48000.0 is supported. a_fr = ', str(a_fr)])
295
+ print(err_msg)
296
+ raise Exception(err_msg)
217
297
  v_fs_whole_vid_frames = round(v_fs + v_fs_to_add, ALIGN_VFS_ROUND_DIGITS)
218
298
  v_fs_whole_vid_frames_mod_5 = v_fs_whole_vid_frames % 5.0
219
299
  if v_fs_whole_vid_frames_mod_5:
@@ -223,41 +303,68 @@ def vid_frames_align_to_audio_frames(v_fs, v_fr_string, a_fr, pad_or_trim):
223
303
  v_fs_to_trim = 0.0
224
304
  if not is_float_whole_number(rounded_v_fs):
225
305
  v_fs_to_trim += v_fs - int(v_fs)
226
- if (v_fr_string == VID_FRAME_RATE_STRING_2997) or (v_fr_string == VID_FRAME_RATE_STRING_2997df):
306
+ if (v_fr_str_upper == VID_FRAME_RATE_STRING_2997) or (v_fr_str_upper == VID_FRAME_RATE_STRING_2997df):
227
307
  if a_fr != 48000.0:
228
- print('tc_tools: vid_frames_align_to_audio_frames() currently only audio frame rate of 48000.0 is supported.')
229
- raise
308
+ err_msg = ''.join(['tc_tools: align_to_audio_frames: 29.97 and 29DF currently only audio frame rate of 48000.0 is supported. a_fr = ', str(a_fr)])
309
+ print(err_msg)
310
+ raise Exception(err_msg)
230
311
  v_fs_whole_vid_frames = round(v_fs - v_fs_to_trim, ALIGN_VFS_ROUND_DIGITS)
231
312
  v_fs_whole_vid_frames_mod_5 = v_fs_whole_vid_frames % 5.0
232
313
  if v_fs_whole_vid_frames_mod_5:
233
314
  v_fs_to_trim += v_fs_whole_vid_frames_mod_5
234
315
  return v_fs_to_trim
235
- print('tc_tools: vid_frames_align_to_audio_frames() mode must be one of trim or pad.')
236
- raise
237
-
316
+ err_msg = ''.join(['tc_tools: align_to_audio_frames: mode must be one of trim or pad'])
317
+ print(err_msg)
318
+ raise Exception(err_msg)
319
+
320
+
321
+ def parse_tc_string(tc, v_fr_string):
322
+ """
323
+ parse tc into tc_hr, tc_min, tc_sec, tc_frames, tc_partial_frames
324
+ TODO: 2025-09-26: use frame rate to only allow ';' in the case of VID_FRAME_RATE_STRING_2997df
325
+ """
326
+ parse_ok = True
327
+ tc_splits = tc.rstrip().split(":")
328
+ try:
329
+ if 3 == len(tc_splits):
330
+ tc_splits_df = tc_splits[2].split(";")
331
+ if 2 == len(tc_splits_df):
332
+ tc_sec = int(tc_splits_df[0])
333
+ tc_fr_and_partial = tc_splits_df[1]
334
+ else:
335
+ parse_ok = False
336
+ elif 4 == len(tc_splits):
337
+ tc_sec = int(tc_splits[2])
338
+ tc_fr_and_partial = tc_splits[3]
339
+ else:
340
+ parse_ok = False
341
+ if parse_ok:
342
+ tc_hr = int(tc_splits[0])
343
+ tc_min = int(tc_splits[1])
344
+ tc_frames = int(tc_fr_and_partial.split(".")[0])
345
+ if len(tc_fr_and_partial) > 2:
346
+ tc_partial_frames = float(''.join(['0.', tc_fr_and_partial.split(".")[1]]))
347
+ else:
348
+ tc_partial_frames = 0.0
349
+ except:
350
+ parse_ok = False
351
+ if not parse_ok:
352
+ err_msg = ''.join(['tc is not valid form HR:MN:SC:FR.partial tc = ', tc])
353
+ print(err_msg)
354
+ raise Exception(err_msg)
355
+ return tc_hr, tc_min, tc_sec, tc_frames, tc_partial_frames
238
356
 
239
357
 
240
358
  def tc_is_whole_video_frames(tc, v_fr_string):
241
359
  """Return true if timecode string is a whole number of video frames."""
242
- tc_splits = tc.split(":")
243
- if 4 == len(tc_splits):
244
- tc_fr_and_partial = tc_splits[3]
245
- elif 3 == len(tc_splits):
246
- tc_splits_df = tc_splits[2].split(";")
247
- if 2 == len(tc_splits_df):
248
- tc_fr_and_partial = tc_splits_df[1]
249
- else:
250
- print("tc_tools: tc_is_whole_video_frames() failed to parse tc.")
251
- raise
252
- else:
253
- print("tc_tools: tc_is_whole_video_frames() tc is not valid form HR:MN:SC:FR.partial")
254
- raise;
255
- tc_frames = int(tc_fr_and_partial.split(".")[0])
256
- if len(tc_fr_and_partial) > 2:
257
- tc_partial_frames = float(''.join(['0.', tc_fr_and_partial.split(".")[1]]))
258
- #print('tc_tools: tc_is_whole_video_frames() tc_partial_frames =',tc_partial_frames)
259
- if tc_partial_frames != 0.0:
260
- return False
360
+ try:
361
+ tc_hr, tc_min, tc_sec, tc_frames, tc_partial_frames = parse_tc_string(tc, v_fr_string)
362
+ except Exception as e:
363
+ err_msg = ''.join(['tc_tools: tc_is_whole_video_frames: ', str(e)])
364
+ print(err_msg)
365
+ raise Exception(err_msg)
366
+ if tc_partial_frames != 0.0:
367
+ return False
261
368
  return True
262
369
 
263
370
 
@@ -267,42 +374,19 @@ def tc_round(tc, partial_v_fr_digits, v_fr_string):
267
374
  return vid_frames_to_tc(v_fs, v_fr_string)
268
375
 
269
376
 
377
+ ############################################################################################
378
+ # Conversion to/from timecode
379
+ ############################################################################################
380
+
270
381
  def tc_to_vid_frames(tc, v_fr_string):
271
382
  """Get the number of video frames from timecode."""
272
- v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
273
- tc_splits = tc.split(":")
274
- if 3 == len(tc_splits):
275
- tc_splits_df = tc_splits[2].split(";")
276
- if 2 == len(tc_splits_df):
277
- tc_sec = int(tc_splits_df[0])
278
- tc_fr_and_partial = tc_splits_df[1]
279
- else:
280
- print("tc_tools: tc_to_vid_frames() failed to parse tc. tc_splits_df =", str(tc_splits_df))
281
- raise
282
- elif 4 == len(tc_splits):
283
- tc_sec = int(tc.split(":")[2])
284
- tc_fr_and_partial = tc.split(":")[3]
285
- else:
286
- print("tc_tools: tc_to_vid_frames() failed to parse tc")
287
- raise
288
- tc_hr = int(tc.split(":")[0])
289
- tc_min = int(tc.split(":")[1])
290
- tc_frames = int(tc_fr_and_partial.split(".")[0])
291
- if len(tc_fr_and_partial) > 2:
292
- tc_partial_frames = float(''.join(['0.', tc_fr_and_partial.split(".")[1]]))
293
- else:
294
- tc_partial_frames = 0.0
295
- frame_count = tc_frames
296
- if DEBUG_tc_to_vid_frames:
297
- print('tc_to_vid_frames() tc_hr =',tc_hr)
298
- print('tc_to_vid_frames() tc_min =',tc_min)
299
- print('tc_to_vid_frames() tc_sec =',tc_sec)
300
- print('tc_to_vid_frames() tc_fr_and_partial =',tc_fr_and_partial)
301
- print('tc_to_vid_frames() tc_frames =',tc_frames)
302
- print('tc_to_vid_frames() tc_partial_frames =',tc_partial_frames)
383
+ v_fr_str_upper = v_fr_string_validate(v_fr_string)
303
384
 
385
+ v_fr = v_fr_string_to_non_pulldown_float(v_fr_str_upper)
386
+ tc_hr, tc_min, tc_sec, tc_frames, tc_partial_frames = parse_tc_string(tc, v_fr_str_upper)
387
+ frame_count = tc_frames
304
388
  # 29.97 Drop-Frame Time Code eliminates 2 frames every minute except for minutes 00, 10, 20, 30, 40, and 50
305
- if v_fr_string == VID_FRAME_RATE_STRING_2997df:
389
+ if v_fr_str_upper == VID_FRAME_RATE_STRING_2997df:
306
390
  total_minutes = tc_min + (tc_hr * 60)
307
391
  frames_due_to_minutes = v_fr * total_minutes * 60
308
392
  frames_due_to_minutes -= (int(total_minutes) * 2)
@@ -314,81 +398,15 @@ def tc_to_vid_frames(tc, v_fr_string):
314
398
  frame_count += v_fr * tc_sec
315
399
  frame_count += v_fr * tc_min * 60
316
400
  frame_count += v_fr * tc_hr * 60 * 60
317
- if DEBUG_tc_to_vid_frames:
318
- print('tc_to_vid_frames() frame_count =',frame_count + tc_partial_frames)
319
401
  return frame_count + tc_partial_frames
320
402
 
321
-
322
- def tc_components_to_tc(tc_hr, tc_min, tc_sec, tc_fr, tc_partial_frames, v_fr_string):
323
- """Assemble timecode components into a timecode string."""
324
- # 2023-11-30 DRJ: need to accomodate 2997df
325
- # if tc_partial_frames + tc_fr + tc_sec ends up adding to minutes, we need to make adjustments.
326
- # v_fr_string = VID_FRAME_RATE_STRING_2997df
327
- # tc_hr = 0
328
- # tc_min = 0
329
- # tc_sec = 59
330
- # tc_fr = 30
331
- # tc_partial_frames = 0
332
- # the resulting tc would be 00:01:00:02
333
- # 2024-05-10 DRJ: when tc_partial_frames was less than 0.0001, it was being written in exp notation.
334
- # And so, I added the Decimal bits.
335
- # 2025-01-07 DRJ: Decimal does some mangled rounding! 0.6 is printed ad 0.599999999999999999999
336
- if DEBUG_tc_components_to_tc:
337
- print('tc_tools: tc_components_to_tc: Top of Function.')
338
- print('tc_tools: tc_components_to_tc() tc_hr =', tc_hr)
339
- print('tc_tools: tc_components_to_tc() tc_min =', tc_min)
340
- print('tc_tools: tc_components_to_tc() tc_sec =', tc_sec)
341
- print('tc_tools: tc_components_to_tc() tc_fr =', tc_fr)
342
- print('tc_tools: tc_components_to_tc() tc_partial_frames =', tc_partial_frames)
343
- print('tc_tools: tc_components_to_tc() PARTIAL_FRAME_NUMBER_OF_DIGITS =', PARTIAL_FRAME_NUMBER_OF_DIGITS)
344
- v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
345
- sec_fr_delimiter = ':'
346
- if v_fr_string == VID_FRAME_RATE_STRING_2997df:
347
- sec_fr_delimiter = TC_TOOLS_29DF_SEC_FRAME_DELIM
348
-
349
- while tc_partial_frames >= 1.0:
350
- tc_fr += 1
351
- tc_partial_frames -= 1.0
352
- while tc_fr >= v_fr:
353
- tc_sec += 1
354
- tc_fr -= int(v_fr)
355
- while tc_sec >= 60:
356
- tc_min += 1
357
- tc_sec -= 60
358
- while tc_min >= 60:
359
- tc_hr += 1
360
- tc_min -= 60
361
-
362
- tc = ''.join([ str(tc_hr).zfill(2), ':', str(tc_min).zfill(2), ':',str(tc_sec).zfill(2), sec_fr_delimiter, str(tc_fr).zfill(2)])
363
- if tc_partial_frames > 0.0:
364
- tc_partial_frames_string = str(tc_partial_frames).lstrip('0')
365
- if tc_partial_frames < 0.0001:
366
- tc_partial_frames_string = str(Decimal(tc_partial_frames)).lstrip('0')
367
- if DEBUG_tc_components_to_tc:
368
- print('tc_tools: tc_components_to_tc() tc_partial_frames =', tc_partial_frames)
369
- print('tc_tools: tc_components_to_tc() tc_partial_frames_string =', tc_partial_frames_string)
370
- if (len(tc_partial_frames_string) + 1) > PARTIAL_FRAME_NUMBER_OF_DIGITS:
371
- tc_partial_frames_string = tc_partial_frames_string[0:PARTIAL_FRAME_NUMBER_OF_DIGITS + 1].rstrip('0')
372
- tc = ''.join([tc,tc_partial_frames_string ])
373
- if DEBUG_tc_components_to_tc:
374
- print('tc_tools: tc_components_to_tc() tc =',tc)
375
- print('tc_tools: tc_components_to_tc() Bottom of Function.')
376
-
377
- return tc
378
-
379
-
380
403
  def vid_frames_to_tc(v_fs, v_fr_string):
381
404
  """Get timecode from the number of video frames ."""
382
- if DEBUG_vid_frames_to_tc:
383
- print('vid_frames_to_tc() Top of Funcion.')
384
- print('vid_frames_to_tc() v_fr_string =',v_fr_string)
385
- print('vid_frames_to_tc() v_fs =',v_fs)
386
- v_fr = v_fr_string_to_non_pulldown_float(v_fr_string)
405
+ v_fr_str_upper = v_fr_string_validate(v_fr_string)
406
+ v_fr = v_fr_string_to_non_pulldown_float(v_fr_str_upper)
387
407
  # if we are negative, wrap around
388
- v_fs_24hr = tc_to_vid_frames('24:00:00:00', v_fr_string)
389
- v_fs = round(v_fs,PARTIAL_FRAME_NUMBER_OF_DIGITS)
390
- if DEBUG_vid_frames_to_tc:
391
- print('vid_frames_to_tc() v_fs (rounded) =',v_fs)
408
+ v_fs_24hr = tc_to_vid_frames('24:00:00:00', v_fr_str_upper)
409
+ v_fs = round(v_fs, PARTIAL_FRAME_NUMBER_OF_DIGITS)
392
410
  if v_fs < 0:
393
411
  v_fs = v_fs + v_fs_24hr
394
412
  if v_fs > v_fs_24hr:
@@ -396,14 +414,12 @@ def vid_frames_to_tc(v_fs, v_fr_string):
396
414
 
397
415
  _tc = str("00:00:00:00")
398
416
  _vid_frames = v_fs
399
- if v_fr_string == VID_FRAME_RATE_STRING_2997df:
417
+ if v_fr_str_upper == VID_FRAME_RATE_STRING_2997df:
400
418
  if True:
401
419
  # for every 1800 video frames, add two video frames
402
420
  minutes_fr_to_add = int(v_fs/1800) * 2
403
- #print('vid_frames_to_timecode_seconds(): minutes_fr_to_add =',minutes_fr_to_add)
404
421
  # for every 18000 video frames, take away two video frames
405
422
  minutes_fr_to_remove = int(v_fs/18000) * 2
406
- #print('vid_frames_to_timecode_seconds(): minutes_fr_to_remove =',minutes_fr_to_remove)
407
423
  v_fs += minutes_fr_to_add
408
424
  v_fs -= minutes_fr_to_remove
409
425
  total_seconds = v_fs / v_fr
@@ -411,17 +427,7 @@ def vid_frames_to_tc(v_fs, v_fr_string):
411
427
  total_minutes_int = int(total_minutes)
412
428
  _vid_frames += (total_minutes_int * 2)
413
429
  _vid_frames -= (int(total_minutes_int / 10) * 2)
414
- if DEBUG_vid_frames_to_tc:
415
- print('vid_frames_to_tc() v_fs =',v_fs)
416
- print('vid_frames_to_tc() total_seconds =',total_seconds)
417
- print('vid_frames_to_tc() total_minutes =',total_minutes)
418
- print('vid_frames_to_tc() total_minutes_int =',total_minutes_int)
419
- print('vid_frames_to_tc() _vid_frames =',_vid_frames)
420
430
  if True:
421
- #tc_hr = 0
422
- #tc_min = 0
423
- #tc_sec = 0
424
- #tc_fr = 0
425
431
  _tc_hr = int(_vid_frames / (v_fr * 60 * 60))
426
432
  _vid_frames = _vid_frames - v_fr * _tc_hr * 60 * 60
427
433
  _tc_min = int(_vid_frames / (v_fr * 60))
@@ -432,25 +438,13 @@ def vid_frames_to_tc(v_fs, v_fr_string):
432
438
  _vid_frames = _vid_frames - _tc_fr
433
439
  _tc_subfr = _vid_frames
434
440
  _subframes = round(_tc_subfr, PARTIAL_FRAME_NUMBER_OF_DIGITS)
435
-
436
- if DEBUG_vid_frames_to_tc:
437
- print('vid_frames_to_tc() _tc_hr =',_tc_hr)
438
- print('vid_frames_to_tc() _tc_min =',_tc_min)
439
- print('vid_frames_to_tc() _tc_sec =',_tc_sec)
440
- print('vid_frames_to_tc() _tc_fr =',_tc_fr)
441
- print('vid_frames_to_tc() _tc_subfr =',_tc_subfr)
442
- print('vid_frames_to_tc() _subframes =',_subframes)
443
-
444
- _tc = tc_components_to_tc(_tc_hr, _tc_min, _tc_sec, _tc_fr, _subframes, v_fr_string)
445
- _tc_v_vs = tc_to_vid_frames(_tc,v_fr_string)
441
+ _tc = tc_components_to_tc(_tc_hr, _tc_min, _tc_sec, _tc_fr, _subframes, v_fr_str_upper)
442
+ _tc_v_vs = tc_to_vid_frames(_tc, v_fr_string)
446
443
  if _tc_v_vs > v_fs_24hr:
447
444
  # should never happen
448
- print("tc_tools: vid_frames_to_tc() result exceeds 24hr. This should never happen.")
449
- raise
450
- if DEBUG_vid_frames_to_tc:
451
- print('vid_frames_to_tc() _tc =',_tc)
452
- print('vid_frames_to_tc() Bottom of Funcion.')
453
-
445
+ err_msg = ''.join(['tc_tools: vid_frames_to_tc() result exceeds 24hr. This should never happen.'])
446
+ print(err_msg)
447
+ raise Exception(err_msg)
454
448
  return _tc
455
449
 
456
450
 
@@ -467,12 +461,12 @@ def tc_to_time_seconds(tc, v_fr_string):
467
461
 
468
462
  def tc_to_audio_frames(tc, v_fr_string, a_fr):
469
463
  v_fs = tc_to_vid_frames(tc, v_fr_string)
470
- return vid_frames_to_audio_frames(v_fs, v_fr_string, a_fr)
464
+ return vid_frames_to_audio_frames(v_fs, v_fr_string, a_fr)
471
465
 
472
466
 
473
467
  def audio_frames_to_tc(a_fs, v_fr_string, a_fr):
474
468
  v_fs = audio_frames_to_vid_frames(a_fs, v_fr_string, a_fr)
475
- return vid_frames_to_tc(v_fs, v_fr_string)
469
+ return vid_frames_to_tc(v_fs, v_fr_string)
476
470
 
477
471
 
478
472
  def tc_sub(tc_minuend, tc_subtrahend, v_fr_string):
@@ -486,334 +480,17 @@ def tc_add(tc_addend_a, tc_addend_b, v_fr_string):
486
480
  sum_vid_frames = tc_to_vid_frames(tc_addend_a, v_fr_string) + tc_to_vid_frames(tc_addend_b, v_fr_string)
487
481
  return sum_vid_frames
488
482
 
483
+
489
484
  ############################################################################################
490
485
  #
491
486
  # for direct testing
492
487
  #
493
488
  ############################################################################################
494
489
 
495
- def compare_with_precision(float_a, float_b, precision):
496
- """return true if the floats are close"""
497
- _diff = abs(float_a - float_b)
498
- if _diff > precision: return False
499
- return True
500
-
501
-
502
- def test_vid_frames_to_tc():
503
- tc_1 = '01:00:11:16.6'
504
- vid_frame_rate = VID_FRAME_RATE_STRING_2397
505
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
506
- #_v_fs = 86592.0 + 89.6 - 1
507
-
508
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
509
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " = " , _v_fs, " frames = " , tc)
510
- if tc_1 != tc:
511
- print("FAIL: tc_to_vid_frames()")
512
- raise
513
-
514
- exit(-1)
515
- vid_frame_rate = VID_FRAME_RATE_STRING_2400
516
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
517
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
518
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " = " , _v_fs, " frames = " , tc)
519
- if tc_1 != tc:
520
- print("FAIL: tc_to_vid_frames()")
521
- raise
522
-
523
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
524
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
525
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
526
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " = " , _v_fs, " frames = " , tc)
527
- if tc_1 != tc:
528
- print("FAIL: tc_to_vid_frames()")
529
- raise
530
-
531
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
532
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
533
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
534
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " = " , _v_fs, " frames = " , tc)
535
- if tc_1 != tc:
536
- print("FAIL: tc_to_vid_frames()")
537
- raise
538
-
539
- #vid_frame_rate = VID_FRAME_RATE_STRING_2997df
540
- #_v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
541
- #tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
542
- #print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " = " , _v_fs, " frames = " , tc)
543
-
544
-
545
- # Test 1 frame less than 1 hour
546
- tc_1 = '01:00:00:00'
547
- vid_frame_rate = VID_FRAME_RATE_STRING_2397
548
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
549
- _v_fs -= 1
550
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
551
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " - 1 frame = " , _v_fs, " frames = " , tc)
552
- if '00:59:59:23' != tc:
553
- print("FAIL: tc_to_vid_frames()")
554
- raise
555
-
556
- vid_frame_rate = VID_FRAME_RATE_STRING_2400
557
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
558
- _v_fs -= 1
559
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
560
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " - 1 frame = " , _v_fs, " frames = " , tc)
561
- if '00:59:59:23' != tc:
562
- print("FAIL: tc_to_vid_frames()")
563
- raise
564
-
565
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
566
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
567
- _v_fs -= 1
568
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
569
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " - 1 frame = " , _v_fs, " frames = " , tc)
570
- if '00:59:59:24' != tc:
571
- print("FAIL: tc_to_vid_frames()")
572
- raise
573
-
574
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
575
- _v_fs = tc_to_vid_frames(tc_1, vid_frame_rate)
576
- _v_fs -= 1
577
- tc = vid_frames_to_tc(_v_fs,vid_frame_rate)
578
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_1, " - 1 frame = " , _v_fs, " frames = " , tc)
579
- if '00:59:59:29' != tc:
580
- print("FAIL: tc_to_vid_frames()")
581
- raise
582
-
583
- def test_audio_frames_to_tc():
584
- a_fs = 1.0
585
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
586
- tc = audio_frames_to_tc(a_fs, vid_frame_rate, 48000.0)
587
- print("test_audio_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", a_fs, ": tc = " , tc)
588
- #if tc_1 != tc:
589
- # print("FAIL: tc_to_vid_frames()")
590
- # raise
591
-
592
- exit(-1)
593
-
594
- def test_time_seconds_to_tc():
595
- print('test_time_seconds_to_tc()')
596
- a_fr = 48000.0
597
- a_fs = 1.0
598
- time_seconds_1af = a_fs / a_fr # .000020833333333333333
599
- time_seconds = time_seconds_1af
600
- print('test_time_seconds_to_tc() time_seconds =',time_seconds)
601
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
602
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
603
- vid_frame_rate = VID_FRAME_RATE_STRING_2997df
604
-
605
- tc = time_seconds_to_tc(time_seconds, vid_frame_rate)
606
- print("test_time_seconds_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", time_seconds, ": tc = " , tc)
607
- #if tc_1 != tc:
608
- # print("FAIL: tc_to_vid_frames()")
609
- # raise
610
-
611
- time_seconds = 86399.0
612
- time_seconds = 86399.0 + 0.000020833333333333333
613
-
614
- time_seconds = 86485.3990 # 23:59:59:00 @ 2997
615
- time_seconds = 86398.9126 # 23:59:59:00 @ 2997df 86398.9126
616
- time_seconds += time_seconds_1af
617
- tc = time_seconds_to_tc(time_seconds, vid_frame_rate)
618
- print('test_time_seconds_to_tc() time_seconds =',time_seconds)
619
- print("test_time_seconds_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", time_seconds, ": tc = " , tc)
620
-
621
-
622
- def test_tc_to_time_seconds():
623
- print('test_tc_to_time_seconds() Top of Function.')
624
- a_fr = 48000.0
625
- a_fs = 1.0
626
- tc = '23:59:59:00'
627
- tc = '23:59:59:02'
628
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
629
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
630
- vid_frame_rate = VID_FRAME_RATE_STRING_2997df
631
- time_seconds = tc_to_time_seconds(tc, vid_frame_rate)
632
- print("test_time_seconds_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," tc = " , tc, ' time_seconds =',time_seconds)
633
- tc = '23:59:59;02.0006244'
634
- time_seconds = tc_to_time_seconds(tc, vid_frame_rate)
635
- print("test_time_seconds_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," tc = " , tc, ' time_seconds =',time_seconds)
636
- #if tc_1 != tc:
637
- # print("FAIL: tc_to_vid_frames()")
638
- # raise
639
-
640
-
641
- def test_tc_to_vid_frames():
642
- print('test_tc_to_vid_frames() Top of Function.')
643
- a_fr = 48000.0
644
- a_fs = 1.0
645
- tc = '23:59:59:02'
646
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
647
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
648
- vid_frame_rate = VID_FRAME_RATE_STRING_2997df
649
- v_fs = tc_to_vid_frames(tc, vid_frame_rate)
650
- print("test_tc_to_vid_frames: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," tc = " , tc, ' v_fs =',v_fs)
651
- tc = '23:59:59;02.0006244'
652
- v_fs = tc_to_vid_frames(tc, vid_frame_rate)
653
- print("test_tc_to_vid_frames: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," tc = " , tc, ' v_fs =',v_fs)
654
- #if tc_1 != tc:
655
- # print("FAIL: tc_to_vid_frames()")
656
- # raise
657
-
658
-
659
- def test_vid_frames_to_audio_frames():
660
- print('test_vid_frames_to_audio_frames() Top of Function.')
661
- a_fr = 48000.0
662
- a_fs = 1.0
663
- vid_frame_rate = VID_FRAME_RATE_STRING_2500
664
- vid_frame_rate = VID_FRAME_RATE_STRING_2997
665
- vid_frame_rate = VID_FRAME_RATE_STRING_2997df
666
- v_fs = 2589380.0006244
667
- a_fs = vid_frames_to_audio_frames(v_fs, vid_frame_rate, a_fr)
668
- print("test_vid_frames_to_audio_frames: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," v_fs = " , v_fs, ' a_fs =',a_fs)
669
- #if tc_1 != tc:
670
- # print("FAIL: tc_to_vid_frames()")
671
- # raise
672
-
673
-
674
- def test_rounding():
675
- vid_frame_rate = VID_FRAME_RATE_STRING_2397
676
- time_s = 3633.5882708333334
677
- tc = time_seconds_to_tc(time_s, vid_frame_rate)
678
- print("test_rounding: time_seconds_to_tc: ", time_s, " = " , tc, " @" ,vid_frame_rate, "fps")
679
- if '01:00:29:23' != tc:
680
- print("FAIL: time_seconds_to_tc()")
681
- raise
682
-
683
- time_s = 3633.5882608333334
684
- tc = time_seconds_to_tc(time_s, vid_frame_rate)
685
- print("test_rounding: time_seconds_to_tc: ", time_s, " = " , tc, " @" ,vid_frame_rate, "fps")
686
- if '01:00:29:22.999' != tc:
687
- print("FAIL: time_seconds_to_tc()")
688
- raise
689
-
690
- tc_24hrs = "24:00:00:00"
691
- vid_frame_rate = VID_FRAME_RATE_STRING_3000
692
- vid_frames = tc_to_vid_frames(tc_24hrs, vid_frame_rate)
693
- print("test_vid_frames_to_tc: video frame rate = ", '{0: <7}'.format(vid_frame_rate)," ", tc_24hrs, " = " , vid_frames, " frames")
694
- vid_frames_2 = vid_frames - 0.1
695
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
696
- vid_frames_2 = vid_frames - 0.01
697
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
698
- vid_frames_2 = vid_frames - 0.001
699
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
700
- vid_frames_2 = vid_frames - 0.0001
701
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
702
- vid_frames_2 = vid_frames - 0.00001
703
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
704
- vid_frames_2 = vid_frames - 0.000001
705
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
706
- vid_frames_2 = vid_frames - 0.0000001
707
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
708
- vid_frames_2 = vid_frames - 0.00000001
709
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
710
- vid_frames_2 = vid_frames - 0.000000001
711
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
712
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
713
- print('.')
714
- vid_frames_2 = vid_frames - 0.000000005
715
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
716
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
717
- print('.')
718
- vid_frames = 2
719
- vid_frames_2 = vid_frames - 0.000000001
720
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
721
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
722
- print('.')
723
- vid_frames_2 = vid_frames - 0.000000005
724
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
725
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
726
- print('.')
727
- vid_frames_2 = vid_frames - 0.000000006
728
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
729
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
730
- print('.')
731
- vid_frames = 3
732
- vid_frames_2 = vid_frames - 0.000000005
733
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
734
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
735
- print('.')
736
- vid_frames_2 = vid_frames - 0.000000006
737
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
738
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
739
- print('.')
740
-
741
- vid_frames = 4147200000
742
- vid_frames_2 = vid_frames - 0.0001
743
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
744
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
745
- print('.')
746
- vid_frames_2 = vid_frames - 0.00001
747
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
748
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
749
- print('.')
750
- vid_frames_2 = vid_frames - 0.000001
751
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
752
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,8), " frames")
753
- print('.')
754
- print('.')
755
- print('.')
756
- vid_frames_2 = vid_frames - 0.000004
757
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
758
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
759
- print('.')
760
- vid_frames_2 = vid_frames - 0.000005
761
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
762
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
763
- print('.')
764
- vid_frames_2 = vid_frames - 0.000006
765
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
766
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
767
- print('.')
768
- print('.')
769
- print('.')
770
- print('.')
771
- vid_frames = 3.14159265358979323846
772
- vid_frames_2 = vid_frames - 0.0
773
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
774
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
775
- print('.')
776
- vid_frames = 1.14159265358979323846
777
- vid_frames_2 = vid_frames - 0.0
778
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
779
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
780
- print('.')
781
- vid_frames = 2.14159265358979323846
782
- vid_frames_2 = vid_frames - 0.0
783
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
784
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
785
- print('.')
786
- vid_frames_2 = vid_frames - 0.000005
787
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
788
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
789
- print('.')
790
- vid_frames_2 = vid_frames - 0.000006
791
- print("test_vid_frames_to_tc: vid_frames_2 =" , vid_frames_2, " frames")
792
- print("test_vid_frames_to_tc: vid_frames_2 =" , round(vid_frames_2,5), " frames")
793
-
794
-
795
-
796
- print('done.')
797
-
798
-
799
-
800
-
801
-
802
-
803
490
  if __name__ == "__main__":
804
491
  print('tc_tools: top of __main__')
805
- #test_audio_frames_to_tc()
806
- test_time_seconds_to_tc()
807
- test_tc_to_time_seconds()
808
- test_tc_to_vid_frames()
809
- test_vid_frames_to_audio_frames()
810
- #test_vid_frames_to_tc()
811
- #test_rounding()
812
- exit(-1);
813
- vid_frame_rate = VID_FRAME_RATE_STRING_2397
814
- tc = "01:00:23:45.31415"
815
- tc_rounded = tc_round(tc, 3, vid_frame_rate )
816
492
 
493
+ vid_frame_rate = VID_FRAME_RATE_STRING_2397
817
494
  tc = '00:00:01:15'
818
495
  tc_v_fs = tc_to_vid_frames(tc, vid_frame_rate)
819
496
  print('__main__: tc = ',tc)
@@ -831,7 +508,6 @@ if __name__ == "__main__":
831
508
  print('__main__: tc_v_fs = ',tc_v_fs)
832
509
  print('__main__: tc = ',tc)
833
510
 
834
-
835
511
  vid_frame_rate = VID_FRAME_RATE_STRING_2400
836
512
  tc = '00:00:01:15'
837
513
  tc_v_fs = tc_to_vid_frames(tc, vid_frame_rate)
@@ -852,6 +528,4 @@ if __name__ == "__main__":
852
528
  print('__main__: tc_v_fs = ',tc_v_fs)
853
529
  print('__main__: timecode_seconds = ',vid_frames_to_timecode_seconds(tc_v_fs, vid_frame_rate))
854
530
 
855
-
856
-
857
531
  exit(0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sprocket-systems.coda.sdk
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: The Coda SDK provides a Python interface to define Coda workflows, create jobs and run them.
5
5
  Keywords: python,coda,sdk
6
6
  Author-Email: Sprocket Systems <support@sprocket.systems>
@@ -0,0 +1,8 @@
1
+ coda/__init__.py,sha256=9Ps-oyYzXdgi2nKa84OaMl43O8kB5Q_GCNT38Al60m8,1034
2
+ coda/sdk.py,sha256=fF-MKjh183A-D4xbBqEdhFvKr4YAx1GYDjF0zSJZyio,70474
3
+ coda/tc_tools.py,sha256=hEtVE6xtPqg93WfJ-lQdRQroPdQTkH5HkMLWCIkwIlo,22010
4
+ sprocket_systems_coda_sdk-1.3.2.dist-info/METADATA,sha256=SzuQpezPJRER2GllclsPTv08LsLvA5h0hB3KrJzYnVU,1213
5
+ sprocket_systems_coda_sdk-1.3.2.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
6
+ sprocket_systems_coda_sdk-1.3.2.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
7
+ sprocket_systems_coda_sdk-1.3.2.dist-info/licenses/LICENSE,sha256=wrFjizFlraIAPW8JIteGftNH2laAZBBRhdEnPVUsKTM,10198
8
+ sprocket_systems_coda_sdk-1.3.2.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- coda/__init__.py,sha256=XjHXqopjUC_5KLid3L3slEU3Ghm-vtYzsKlHxqeyf5o,1034
2
- coda/sdk.py,sha256=yO8JT2wKfgmpfmus90Mg0OAloZdM9UtZQ3m_1a6Md2w,70343
3
- coda/tc_tools.py,sha256=55aoPnfIJRtPJCeaOHJatWU9D2ZZ5lFdYO0JM3W_Qig,37020
4
- sprocket_systems_coda_sdk-1.3.0.dist-info/METADATA,sha256=qWjb3h7H_UwLAwnIhEzN6Zzn3orAwWkMVftE5lfTIEM,1213
5
- sprocket_systems_coda_sdk-1.3.0.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
6
- sprocket_systems_coda_sdk-1.3.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
7
- sprocket_systems_coda_sdk-1.3.0.dist-info/licenses/LICENSE,sha256=wrFjizFlraIAPW8JIteGftNH2laAZBBRhdEnPVUsKTM,10198
8
- sprocket_systems_coda_sdk-1.3.0.dist-info/RECORD,,