]> id.pley.net Git - movie_parser.git/blobdiff - GenerateManifest.html
Upload Dropbox.com versions of everything
[movie_parser.git] / GenerateManifest.html
diff --git a/GenerateManifest.html b/GenerateManifest.html
new file mode 100755 (executable)
index 0000000..a6f1af1
--- /dev/null
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>GenerateManifest</title>
+    <script src=Atom.js></script>
+    <script>
+        // Add Blob.prototype.slice if it does not already exist:
+        if (typeof(Blob.prototype.slice) == 'undefined' && typeof(Blob.prototype.webkitSlice) != 'undefined')
+            Blob.prototype.slice = Blob.prototype.webkitSlice;
+
+        function onFileSelect(e) {
+            atoms = [];
+            var file = e.target.files[0];
+            var reader = new FileReader();
+            reader.readAsArrayBuffer(file);
+            reader.addEventListener('load', (e) => { onload(e, file); });
+        }
+
+        function onload(e, file) {
+            var reader = e.target;
+            var offset = 0;
+            while (offset < reader.result.byteLength) {
+                var atom = Atom.create(reader.result, offset);
+                offset += atom.size;
+                atoms.push(atom);
+            }
+
+            var manifest = generateManifest(atoms, file);
+            document.body.appendChild(document.createTextNode(JSON.stringify(manifest)));
+        }
+
+        function generateManifest(atoms, file)
+        {
+            var manifest = new Object;
+            manifest.url = file.name;
+
+            manifest.type = file.type;
+            var codecs = [];
+
+            var moov = atoms.find((atom) => { return atom.type === 'moov'; });
+            if (!moov)
+                return;
+
+            var timeScale = moov.getAtomByType('mdhd').timeScale
+
+            manifest.init = { offset: 0, size: moov.offset + moov.size };
+
+            var stsds = moov.getAtomsByType('stsd');
+            stsds.forEach((stsd) => {
+                stsd.getAtomsByType('avc1').forEach((avc1) => {
+                                       avc1.getAtomsByType('avcC').forEach((avcC) => {
+                                               var profile = ('0' + avcC.AVCProfileIndication.toString(16)).substr(-2);
+                                               var compat = ('0' + avcC.profileCompatibility.toString(16)).substr(-2);
+                                               var level = ('0' + avcC.AVCLevelIndication.toString(16)).substr(-2);
+                                               codecs.push(`"avc1.${profile + compat + level}"`);
+                                       });
+                });
+                stsd.getAtomsByType('hvc1').forEach((hvc1) => {
+                    codecs.push(`"hvc1"`);
+                });
+            });
+
+            if (codecs.length)
+                manifest.type += `; codecs=${ codecs.join(',') }`;
+
+            manifest.media = [];
+            var trex = moov.getAtomsByType('trex')[0];
+
+            atoms.forEach((atom, index) => {
+                if (atom.type !== 'moof')
+                    return;
+
+                var offset = atom.offset;
+                var size = atom.size;
+                var mdat = atoms[index + 1];
+                var timestamp = 0;
+                if (mdat.type === 'mdat')
+                    size += mdat.size;
+                var tfdt = atom.getAtomByType('tfdt');
+                if (tfdt)
+                    timestamp = tfdt.baseMediaDecodeTime / timeScale;
+
+                var defaultSampleDuration = trex.default_sample_duration;
+
+                var tfhd = atom.getAtomByType('tfhd');
+                if (tfhd.defaultSampleDurationPresent)
+                    defaultSampleDuration = tfhd.defaultSampleDuration;
+
+                var totalDuration = 0;
+                var trun = atom.getAtomByType('trun');
+                trun.samples.forEach((sample) => {
+                    if (trun.sampleDurationPresent)
+                        totalDuration += sample.sampleDuration;
+                    else
+                        totalDuration += defaultSampleDuration;
+                });
+                var duration = totalDuration / timeScale;
+
+                manifest.media.push({ offset: offset, size: size, timestamp: timestamp, duration: duration });
+            });
+            return manifest;
+        }
+
+        function setup() {
+            document.getElementById('file').addEventListener('change', onFileSelect, false);
+        }
+    </script>
+</head>
+<body onload="setup()">
+    <input type="file" id="file" name="file" />
+    <div id=output></div>
+</body>
\ No newline at end of file