@@ -45,6 +45,35 @@ def make_name(src: FileInfo, tb: Fraction) -> str:
45
45
return "FFVideoFormatRateUndefined"
46
46
47
47
48
+ def parseSMPTE (val : str , fps : Fraction , log : Log ) -> int :
49
+ if len (val ) == 0 :
50
+ return 0
51
+ try :
52
+ parts = val .split (":" )
53
+ if len (parts ) != 4 :
54
+ raise ValueError (f"Invalid SMPTE format: { val } " )
55
+
56
+ hours , minutes , seconds , frames = map (int , parts )
57
+
58
+ if (
59
+ hours < 0
60
+ or minutes < 0
61
+ or minutes >= 60
62
+ or seconds < 0
63
+ or seconds >= 60
64
+ or frames < 0
65
+ ):
66
+ raise ValueError (f"Invalid SMPTE values: { val } " )
67
+
68
+ if frames >= fps :
69
+ raise ValueError (f"Frame count { frames } exceeds fps { fps } " )
70
+
71
+ total_frames = (hours * 3600 + minutes * 60 + seconds ) * fps + frames
72
+ return int (round (total_frames ))
73
+ except (ValueError , ZeroDivisionError ) as e :
74
+ log .error (f"Cannot parse SMPTE timecode '{ val } ': { e } " )
75
+
76
+
48
77
def fcp11_write_xml (
49
78
group_name : str , version : int , output : str , resolve : bool , tl : v3 , log : Log
50
79
) -> None :
@@ -83,12 +112,14 @@ def fraction(val: int) -> str:
83
112
height = f"{ tl .res [1 ]} " ,
84
113
colorSpace = get_colorspace (one_src ),
85
114
)
115
+
116
+ startPoint = parseSMPTE (one_src .timecode , tl .tb , log )
86
117
r2 = SubElement (
87
118
resources ,
88
119
"asset" ,
89
120
id = f"r{ i * 2 + 2 } " ,
90
121
name = one_src .path .stem ,
91
- start = "0s" ,
122
+ start = fraction ( startPoint ) ,
92
123
hasVideo = "1" if one_src .videos else "0" ,
93
124
format = f"r{ i * 2 + 1 } " ,
94
125
hasAudio = "1" if one_src .audios else "0" ,
@@ -115,12 +146,14 @@ def fraction(val: int) -> str:
115
146
spine = SubElement (sequence , "spine" )
116
147
117
148
def make_clip (ref : str , clip : Clip ) -> None :
149
+ startPoint = parseSMPTE (clip .src .timecode , tl .tb , log )
150
+
118
151
clip_properties = {
119
152
"name" : proj_name ,
120
153
"ref" : ref ,
121
- "offset" : fraction (clip .start ),
154
+ "offset" : fraction (clip .start + startPoint ),
122
155
"duration" : fraction (clip .dur ),
123
- "start" : fraction (clip .offset ),
156
+ "start" : fraction (clip .offset + startPoint ),
124
157
"tcFormat" : "NDF" ,
125
158
}
126
159
asset = SubElement (spine , "asset-clip" , clip_properties )
0 commit comments