Remove in-place translations support.
[dcpomatic.git] / hacks / make_dummy_files
index 572f40e64b1a12a8d7c6a5564e3a2915f1f3ad05..21c09e2eae7f84f2e492c6159bacadd55ce9ec1e 100755 (executable)
@@ -5,26 +5,47 @@ import os
 import ntpath
 import tempfile
 import shutil
+import hashlib
 import xml.etree.ElementTree as ET
 
 if len(sys.argv) < 2:
-    print 'Syntax: %s <film>' % sys.argv[1]
+    print('Syntax: %s <film>' % sys.argv[1])
     sys.exit(1)
 
-tree = ET.parse(os.path.join(sys.argv[1], 'metadata.xml'))
+metadata_xml = os.path.join(sys.argv[1], 'metadata.xml');
+tree = ET.parse(metadata_xml)
+
+def digest_head_tail(filename, size=1000000):
+    m = hashlib.md5()
+    f = open(filename, 'rb')
+    m.update(f.read(size))
+    f.seek(size, 2)
+    m.update(f.read(size))
+    f.close()
+    return m.hexdigest() + str(os.path.getsize(filename))
+
+def command(c):
+    print(f'*** {c}')
+    os.system(c)
+
 
 try:
     os.makedirs(os.path.join(sys.argv[1], 'dummy'))
 except:
     pass
 
-for c in tree.getroot().find('Playlist').findall('Content'):
+root = tree.getroot()
+
+for c in root.find('Playlist').findall('Content'):
     type = c.find('Type').text
     if type == 'DCP':
         # Find the ASSETMAP
         assetmap_file = None
         for p in c.findall('Path'):
             if os.path.basename(p.text) == 'ASSETMAP':
+                interop = True
+            elif os.path.basename(p.text) == 'ASSETMAP.xml':
+                interop = False
                 assetmap_file = p.text
 
         assert(assetmap_file is not None)
@@ -33,15 +54,17 @@ for c in tree.getroot().find('Playlist').findall('Content'):
         assets = {}
 
         assetmap = ET.parse(assetmap_file)
-        ns = {'am': 'http://www.digicine.com/PROTO-ASDCP-AM-20040311#'}
+        ns = {'am': 'http://www.digicine.com/PROTO-ASDCP-AM-20040311#'} if interop else {'am': 'http://www.smpte-ra.org/schemas/429-9/2007/AM'}
         for a in assetmap.getroot().find('am:AssetList', ns).findall('am:Asset', ns):
             assets[a.find('am:Id', ns).text[9:]] = a.find('am:ChunkList', ns).find('am:Chunk', ns).find('am:Path', ns).text
 
         cpl_id = None
-        for k, v in assets.iteritems():
+        cpl_ns = 'http://www.digicine.com/PROTO-ASDCP-CPL-20040511#}' if interop else 'http://www.smpte-ra.org/schemas/429-7/2006/CPL'
+        for k, v in assets.items():
             try:
                 e = ET.parse(os.path.join(dir, v))
-                if e.getroot().tag == '{http://www.digicine.com/PROTO-ASDCP-CPL-20040511#}CompositionPlaylist':
+                print(e.getroot().tag)
+                if e.getroot().tag == "{" + cpl_ns + "}CompositionPlaylist":
                     cpl_id = k
             except:
                 pass
@@ -49,20 +72,30 @@ for c in tree.getroot().find('Playlist').findall('Content'):
         assert(cpl_id is not None)
         cpl = ET.parse(os.path.join(dir, assets[cpl_id]))
 
-        ns = {'cpl': 'http://www.digicine.com/PROTO-ASDCP-CPL-20040511#'}
+        ns = {'cpl': cpl_ns}
         for r in cpl.find('cpl:ReelList', ns).findall('cpl:Reel', ns):
             for a in r.find('cpl:AssetList', ns).iter():
                 if a.tag == '{%s}MainPicture' % ns['cpl']:
                     id = a.find('cpl:Id', ns).text[9:]
                     duration = int(a.find('cpl:IntrinsicDuration', ns).text)
                     black_png = tempfile.NamedTemporaryFile('wb', suffix='.png')
+                    black_j2cs = []
                     black_j2c = tempfile.NamedTemporaryFile('wb', suffix='.j2c')
                     os.system('convert -size 1998x1080 xc:black %s' % black_png.name)
-                    os.system('image_to_j2k -i %s -o %s' % (black_png.name, black_j2c.name))
+                    os.system('opj_compress -i %s -o %s' % (black_png.name, black_j2c.name))
                     j2c_dir = tempfile.mkdtemp()
-                    print j2c_dir
                     for i in range(0, duration):
-                        shutil.copyfile(black_j2c.name, os.path.join(j2c_dir, '%06d.j2c' % i))
+                        try:
+                            os.link(black_j2c.name, os.path.join(j2c_dir, '%06d.j2c' % i))
+                        except OSError as e:
+                            if e.errno == 31:
+                                # Too many links
+                                black_j2cs.append(black_j2c)
+                                black_j2c = tempfile.NamedTemporaryFile('wb', suffix='.j2c')
+                                os.link(black_j2c.name, os.path.join(j2c_dir, '%06d.j2c' % i))
+                            else:
+                                raise
+                    print('=> wrap it')
                     os.system('asdcp-wrap -a %s %s %s' % (id, j2c_dir, os.path.join(sys.argv[1], 'dummy', assets[id])))
                 elif a.tag == '{%s}MainSound' % ns['cpl']:
                     wav = tempfile.NamedTemporaryFile('wb', suffix='.wav')
@@ -78,23 +111,44 @@ for c in tree.getroot().find('Playlist').findall('Content'):
         audio_length = int(c.find('AudioLength').text)
         os.system('sox -n -r %d -c %d %s trim 0.0 %f' % (audio_frame_rate, channels, path, float(audio_length) / audio_frame_rate))
     elif type == 'FFmpeg':
-        if c.find('VideoFrameRate') is not None:
-            video_frame_rate = int(c.find('VideoFrameRate').text)
-            video_length = int(c.find('VideoLength').text)
-            path = os.path.join(sys.argv[1], 'dummy', ntpath.basename(c.find('Path').text))
-            os.system('ffmpeg -t %d -s qcif -f rawvideo -pix_fmt rgb24 -r %d -i /dev/zero -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 -shortest "%s"' % (float(video_length) / video_frame_rate, video_frame_rate, path))
-        elif c.find('AudioGain') is not None:
+        video_cmd = ''
+        audio_cmd = ''
+        path = os.path.join(sys.argv[1], 'dummy', ntpath.basename(c.find('Path').text))
+        if c.find('AudioStream') is not None:
+            audio_channels = int(c.find('AudioStream').find('Mapping').find('InputChannels').text)
             audio_frame_rate = int(c.find('AudioStream').find('FrameRate').text)
-            channels = int(c.find('AudioStream').find('Mapping').find('InputChannels').text)
-            path = os.path.join(sys.argv[1], 'dummy', ntpath.basename(c.find('Path').text))
             audio_length = int(c.find('AudioStream').find('Length').text)
-            os.system('sox -n -r %d -c %d %s trim 0.0 %f' % (audio_frame_rate, channels, path, float(audio_length) / audio_frame_rate))
+            names = { 1: 'mono', 2: 'stereo', 3: '3.0', 4: '4.0', 5: '4.1', 6: '5.1', 7: '6.1', 8: '7.1' }
+            os.system(f'ffmpeg -t {float(audio_length) / audio_frame_rate} -f lavfi -i anullsrc=channel_layout={names[audio_channels]}:sample_rate={audio_frame_rate} audio.aac')
+        if c.find('VideoFrameRate') is not None:
+            video_frame_rate = float(c.find('VideoFrameRate').text)
+            video_length = int(c.find('VideoLength').text)
+            video_cmd = '-s qcif -f rawvideo -pix_fmt rgb24 -r %f -i /dev/zero' % video_frame_rate
+            command(f'ffmpeg -t {video_length / video_frame_rate} -s qcif -f rawvideo -pix_fmt rgb24 -r {video_frame_rate} -i /dev/zero -shortest video.mp4')
+        if c.find('AudioStream') is not None and c.find('VideoFrameRate') is not None:
+            command(f'ffmpeg -i video.mp4 -i audio.aac -c copy -shortest "{path}"')
+        elif c.find('VideoFrameRate') is not None:
+            command(f'ffmpeg -i video.mp4 "{path}"')
         else:
-            print 'Skipped %s' % type
+            command('sox -n -r %d -c %d %s trim 0.0 %f' % (audio_frame_rate, audio_channels, path, float(audio_length) / audio_frame_rate))
+        try:
+            os.unlink('video.mp4')
+            os.unlink('audio.aac')
+        except:
+            pass
+        c.find('Path').text = path
+        c.find('Digest').text = digest_head_tail(path)
     elif type == 'Image':
         width = int(c.find('VideoWidth').text)
         height = int(c.find('VideoHeight').text)
         path = os.path.join(sys.argv[1], 'dummy', ntpath.basename(c.find('Path').text))
         os.system('convert -size %dx%d xc:black "%s"' % (width, height, path))
     else:
-        print 'Skipped %s' % type
+        print('Skipped %s' % type)
+
+
+shutil.move(metadata_xml, metadata_xml + '.bak')
+r = open(metadata_xml, 'w')
+r.write(ET.tostring(root).decode('UTF-8'))
+r.close()
+