1- import  std/ json
2- import  std/ strutils
1+ import  std/ [strformat, strutils, json]
32
43import  ../ log
54import  ../ timeline
65import  ../ ffmpeg
76import  ../ media
87import  ../ util/ color
98
9+ proc  parseEffect (val: string ): Action  = 
10+   #  Parse effect strings like "speed:2.0", "volume:1.5", or simple "cut", "nil"
11+   if  val ==  " cut"  :
12+     return  Action  (kind: actCut)
13+   if  val ==  " nil"  :
14+     return  Action  (kind: actNil)
15+ 
16+   let  parts =  val.split (" :"  )
17+   if  parts.len ==  2 :
18+     let  effectType =  parts[0 ]
19+     let  effectVal =  parseFloat (parts[1 ])
20+     case  effectType
21+     of  " speed"  : return  Action  (kind: actSpeed, val: effectVal)
22+     of  " volume"  : return  Action  (kind: actVolume, val: effectVal)
23+     of  " pitch"  : return  Action  (kind: actPitch, val: effectVal)
24+     else : error  & " unknown action: { effectType}  " 
25+ 
26+   error  & " unknown action: { val}  " 
27+ 
1028proc  parseClip (node: JsonNode , interner: var  StringInterner , effects: var  seq [Action ]): Clip  = 
1129  result .src =  interner.intern (node[" src"  ].getStr ())
1230  result .start =  node[" start"  ].getInt ()
1331  result .dur =  node[" dur"  ].getInt ()
1432  result .offset =  node[" offset"  ].getInt ()
1533  result .stream =  node[" stream"  ].getInt ().int32 
1634
17-   #  Parse effects array and find/add to effects list
1835  var  clipAction =  Action  (kind: actNil)
1936  if  node.hasKey (" effects"  ) and  node[" effects"  ].kind ==  JArray :
2037    for  effectNode in  node[" effects"  ]:
21-       let  effectStr =  effectNode.getStr ()
22-       #  Parse effect strings like "speed:2.0", "volume:1.5"
23-       let  parts =  effectStr.split (" :"  )
24-       if  parts.len ==  2 :
25-         let  effectType =  parts[0 ]
26-         let  effectVal =  parseFloat (parts[1 ])
27-         case  effectType
28-         of  " speed"  :
29-           clipAction =  Action  (kind: actSpeed, val: effectVal)
30-         of  " volume"  :
31-           clipAction =  Action  (kind: actVolume, val: effectVal)
32-         of  " pitch"  :
33-           clipAction =  Action  (kind: actPitch, val: effectVal)
34-         else :
35-           discard 
38+       clipAction =  parseEffect (effectNode.getStr ())
3639
3740  #  Find or add the action to the effects list
3841  let  effectIndex =  effects.find (clipAction)
@@ -55,7 +58,7 @@ proc parseV3*(jsonNode: JsonNode, interner: var StringInterner): v3 =
5558    error (" sr/bg bad structure"  )
5659
5760  result .sr =  jsonNode[" samplerate"  ].getInt ().cint 
58-   result .background  =  parseColor (jsonNode[" background"  ].getStr ())
61+   result .bg  =  parseColor (jsonNode[" background"  ].getStr ())
5962
6063  if  not  jsonNode.hasKey (" resolution"  ) or  jsonNode[" resolution"  ].kind !=  JArray :
6164    error (" 'resolution' has bad structure"  )
@@ -89,6 +92,34 @@ proc parseV3*(jsonNode: JsonNode, interner: var StringInterner): v3 =
8992          track.c.add (parseClip (audioNode, interner, result .effects))
9093      result .a.add (track)
9194
95+ proc  parseV2 * (jsonNode: JsonNode , interner: var  StringInterner ): v3 = 
96+   let  input =  jsonNode[" source"  ].getStr ()
97+   let  ptrInput =  intern (interner, input)
98+   var  effects: seq [Action ]
99+   var  clips: seq [Clip2 ]
100+   let  tb: AVRational  =  jsonNode[" tb"  ].getStr ()
101+ 
102+   if  jsonNode.hasKey (" clips"  ) and  jsonNode[" clips"  ].kind ==  JArray :
103+     for  chunkNode in  jsonNode[" clips"  ]:
104+       if  chunkNode.kind ==  JArray  and  chunkNode.len >=  3 :
105+         let  start: int64  =  chunkNode[0 ].getInt ()
106+         let  `end`: int64  =  chunkNode[1 ].getInt ()
107+         let  effect =  uint32  (chunkNode[2 ].getInt ())
108+         clips.add  Clip2  (start: start, `end`: `end`, effect: effect)
109+ 
110+   if  jsonNode.hasKey (" effects"  ) and  jsonNode[" effects"  ].kind ==  JArray :
111+     for  effectNode in  jsonNode[" effects"  ]:
112+       #  TODO : Support multiple actions
113+       let  clipAction =  parseEffect (effectNode.getStr ())
114+       let  effectIndex =  effects.find (clipAction)
115+       if  effectIndex ==  - 1 :
116+         effects.add (clipAction)
117+ 
118+   let  mi =  initMediaInfo (input)
119+   let  bg =  RGBColor  (red: 0 , green: 0 , blue: 0 )
120+   result  =  toNonLinear2 (ptrInput, tb, bg, mi, clips, effects)
121+ 
122+ 
92123proc  parseV1 * (jsonNode: JsonNode , interner: var  StringInterner ): v3 = 
93124  var  chunks: seq [(int64 , int64 , float64 )] =  @ []
94125
@@ -113,10 +144,10 @@ proc parseV1*(jsonNode: JsonNode, interner: var StringInterner): v3 =
113144
114145proc  readJson * (jsonStr: string , interner: var  StringInterner ): v3 = 
115146  let  jsonNode =  parseJson (jsonStr)
116- 
117147  let  version: string  =  jsonNode[" version"  ].getStr (" unknown"  )
118-   if  version ==  " 3"  :
119-     return  parseV3 (jsonNode, interner)
120-   if  version ==  " 1"  :
121-     return  parseV1 (jsonNode, interner)
122-   error (" Unsupported version"  )
148+ 
149+   case  version:
150+     of  " 3"  : return  parseV3 (jsonNode, interner)
151+     of  " 2"  : return  parseV2 (jsonNode, interner)
152+     of  " 1"  : return  parseV1 (jsonNode, interner)
153+     else : error  & " Unsupported version: { version}  " 
0 commit comments