]> git.parisson.com Git - telemeta.git/commitdiff
Fixed parsing of 6.24.0 files
authorGael Le Mignot <gael@pilotsystems.net>
Thu, 28 Apr 2022 09:09:44 +0000 (11:09 +0200)
committerGael Le Mignot <gael@pilotsystems.net>
Thu, 28 Apr 2022 09:09:44 +0000 (11:09 +0200)
telemeta/util/kdenlive/session.py

index d9ed7eb0ed02bcb4a0be5dc90bf1eb7c5c4fa018..a10a0f104022052fbfa7691a7f4d1dc112b0bab6 100644 (file)
 
 import time
 from telemeta.util.xmltodict2 import *
+import json
 
-def parse_timestamp(value):
+def parse_timecode(value, fps):
     """
-    Parse a timestamp, either new HH:MM:SS.mmm format or old seconds format
+    Parse a timestamp, either new HH:MM:SS.mmm format or old frames format
     """
     if ':' in value:
         if '.' in value:
-            value = value.split('.')[0]
+            value, decimal = value.split('.')
         comps = value.split(':')
         comps = [ int(c) for c in comps ]
         res = 0
         for comp in comps:
             res = res * 60 + comp
+        res += float(decimal) / 10**len(decimal)
     else:
-        res = int(value)
+        res = float(value)  / fps
     return res
     
 
@@ -80,18 +82,21 @@ class KDEnLiveSession(object):
     def entries_sorted(self):
         return sorted(self.entries(), key=lambda k: int(k['in']), reverse=False)
 
-    def entries_video_seconds(self):
+    def get_fps(self):
         profile = self.profile()
         fps = float(profile['frame_rate_num'])/float(profile['frame_rate_den'])
-        #fps= 25
+        return fps
+    
+    def entries_video_seconds(self):
+        fps = self.get_fps()
         res = []
         start = 0
         entries = self.video_entries()
 
         for entry in entries:
             id = entry['producer'].split('_')[0]
-            t_in = parse_timestamp(entry['in'])/fps
-            t_out = parse_timestamp(entry['out'])/fps
+            t_in = parse_timecode(entry['in'], fps)
+            t_out = parse_timecode(entry['out'], fps)
             t_len = t_out - t_in
             end = start + t_len
             res.append({ 'id': str(id), 't': start, 'in': t_in, 'out': t_out })
@@ -132,17 +137,40 @@ class KDEnLiveSession(object):
 
             offset: general origin offset
         """
-
-        abs_time = 0
         markers = []
-        i = 0
         entries = self.entries_video_seconds()
         title = ''
+        fps = self.get_fps()
+
+        def add_marker(rel_time, comment):
+            """
+            Add a marker to the list from it's id, timestamp and comment
+            """
+            marker = {}
+            marker['time'] = rel_time
+            marker['session_timecode'] = time.strftime('%H:%M:%S', time.gmtime(rel_time))
+            if ":" in comment:
+                pre, post = comment.split(':', 1)
+                if pre.isdigit():
+                    comment = post
+            marker['comment'] = comment
+            markers.append(marker)
+
+        def get_reltime(entry_id, marker_time):
+            """
+            Get the relative time of a marker linked to an entry
+            """
+            rel_time = 0
+
+            for entry in entries:
+                if entry['in'] <= marker_time <= entry['out'] and entry_id == entry['id']:
+                    rel_time = entry['t'] + (marker_time - entry['in']) + offset
+                    return rel_time            
 
         for attr in self.session['children']:
             if 'playlist' in attr['name'] and 'children' in attr:
+                # Old v 6.4 file format, markers in playlist
                 for att in attr['children']:
-                    marker = {}
                     if 'name' in att['attributes']:
                         name = att['attributes']['name']
                         if 'docmetadata.meta.attr.title.markup' in name:
@@ -150,28 +178,29 @@ class KDEnLiveSession(object):
                         if 'marker' in name:
                             name = name.encode('utf8')
                             marker_time = float(name.split(':')[-1].replace(',','.').replace(' ', ''))
-                            id = str(name.split(':')[-2].split('.')[-1])
-                            rel_time = 0
-
-                            for entry in entries:
-                                if entry['in'] <= marker_time <= entry['out'] and id == entry['id']:
-                                    if i == 0 and from_first_marker:
-                                        abs_time = entry['t']
-                                    rel_time = entry['t'] + (marker_time - entry['in']) - abs_time + offset
-                                    break
-                            else:
-                                continue
-
-                            marker['time'] = rel_time
-                            marker['session_timecode'] = time.strftime('%H:%M:%S', time.gmtime(rel_time))
+                            entry_id = str(name.split(':')[-2].split('.')[-1])
                             comment = self.fix_text(att['cdata'])
-                            if ":" in comment:
-                                pre, post = comment.split(':', 1)
-                                if pre.isdigit():
-                                    comment = post
-                            marker['comment'] = comment
-                            markers.append(marker)
-
-                        i += 1
+                            rel_time = get_reltime(entry_id, marker_time)
+                            if rel_time is not None:
+                                add_marker(rel_time, comment)
+            elif 'producer' in attr['name'] and 'children' in attr:
+                # New v 6.24 file format, markers in producers
+                if "id" in attr['attributes']:
+                    entry_id = attr['attributes']['id']
+                    for att in attr['children']:
+                        name = att['attributes']['name']
+                        if 'markers' in name:
+                            items = json.loads(self.fix_text(att['cdata']))
+                            for marker in items:
+                                marker_time = float(marker['pos'] / fps)
+                                rel_time = get_reltime(entry_id, marker_time)
+                                if rel_time is not None:
+                                    add_marker(rel_time, marker['comment'])
+
+
+        if markers and from_first_marker:
+            delta = min([ marker['time'] for marker in markers ])
+            for marker in markers:
+                marker['time'] -= delta
         return title, markers