2c8f054c by David LaPalomento

Use a more concise text format for mp4 diffing

Create textifyMp4() to output a text representation of an inspected mp4. It's more concise than straight JSON.stringify() so hopefully it will allow for quicker comparisons between working and transmuxed MP4s.
1 parent 5d44efe3
...@@ -404,12 +404,12 @@ form label { ...@@ -404,12 +404,12 @@ form label {
404 /** 404 /**
405 * Diff styling 405 * Diff styling
406 */ 406 */
407 #comparison {
408 white-space: pre;
409 }
410 #comparison p { 407 #comparison p {
411 white-space: normal; 408 white-space: normal;
412 } 409 }
410 #comparison pre {
411 font-size: 90%;
412 }
413 ins, del { 413 ins, del {
414 text-decoration: none; 414 text-decoration: none;
415 } 415 }
......
...@@ -735,4 +735,65 @@ videojs.inspectMp4 = function(data) { ...@@ -735,4 +735,65 @@ videojs.inspectMp4 = function(data) {
735 } 735 }
736 return result; 736 return result;
737 }; 737 };
738
739 /**
740 * Returns a textual representation of the javascript represtentation
741 * of an MP4 file. You can use it as an alternative to
742 * JSON.stringify() to compare inspected MP4s.
743 * @param inspectedMp4 {array} the parsed array of boxes in an MP4
744 * file
745 * @param depth {number} (optional) the number of ancestor boxes of
746 * the elements of inspectedMp4. Assumed to be zero if unspecified.
747 * @return {string} a text representation of the parsed MP4
748 */
749 videojs.textifyMp4 = function(inspectedMp4, depth) {
750 var indent;
751 depth = depth || 0;
752 indent = Array(depth * 2 + 1).join(' ');
753
754 // iterate over all the boxes
755 return inspectedMp4.map(function(box, index) {
756
757 // list the box type first at the current indentation level
758 return indent + box.type + '\n' +
759
760 // the type is already included and handle child boxes separately
761 Object.keys(box).filter(function(key) {
762 return key !== 'type' && key !== 'boxes';
763
764 // output all the box properties
765 }).map(function(key) {
766 var prefix = indent + ' ' + key + ': ',
767 value = box[key];
768
769 // print out raw bytes as hexademical
770 if (value instanceof Uint8Array || value instanceof Uint32Array) {
771 var bytes = Array.prototype.slice.call(new Uint8Array(value.buffer, value.byteOffset, value.byteLength))
772 .map(function(byte) {
773 return ' ' + ('00' + byte.toString(16)).slice(-2);
774 }).join('').match(/.{1,24}/g);
775 if (bytes.length === 1) {
776 return prefix + '<' + bytes.join('').slice(1) + '>';
777 }
778 return prefix + '<\n' + bytes.map(function(line) {
779 return indent + ' ' + line;
780 }).join('\n') + '\n' + indent + ' >';
781 }
782
783 // stringify generic objects
784 return prefix +
785 JSON.stringify(value, null, 2)
786 .split('\n').map(function(line, index) {
787 if (index === 0) {
788 return line;
789 }
790 return indent + ' ' + line;
791 }).join('\n');
792 }).join('\n') +
793
794 // recursively textify the child boxes
795 (box.boxes ? '\n' + videojs.textifyMp4(box.boxes, depth + 1) : '');
796 }).join('\n');
797 };
798
738 })(window, window.videojs); 799 })(window, window.videojs);
......
...@@ -127,9 +127,6 @@ ...@@ -127,9 +127,6 @@
127 original = document.getElementById('original'), 127 original = document.getElementById('original'),
128 working = document.getElementById('working'), 128 working = document.getElementById('working'),
129 129
130 // customize JSON.stringify for more readable TypedArrays
131 stringify,
132
133 vjsParsed, 130 vjsParsed,
134 workingParsed, 131 workingParsed,
135 diffParsed, 132 diffParsed,
...@@ -150,22 +147,6 @@ ...@@ -150,22 +147,6 @@
150 console.log(event.type); 147 console.log(event.type);
151 }; 148 };
152 149
153
154 stringify = function(object) {
155 return JSON.stringify(object, function(s, o) {
156 if (o instanceof Uint8Array) {
157 return Array.prototype.slice.call(o).map(function(byte) {
158 return ('00' + byte.toString(16)).slice(-2);
159 });
160 } else if (o instanceof Uint32Array) {
161 return Array.prototype.slice.call(o).map(function(byte) {
162 return ('00000000' + byte.toString(16)).slice(-8);
163 });
164 }
165 return o;
166 }, ' ');
167 };
168
169 // output a diff of the two parsed MP4s 150 // output a diff of the two parsed MP4s
170 diffParsed = function() { 151 diffParsed = function() {
171 var comparison, diff, transmuxed; 152 var comparison, diff, transmuxed;
...@@ -189,8 +170,11 @@ ...@@ -189,8 +170,11 @@
189 'working version. A <ins>green background</ins> indicates ' + 170 'working version. A <ins>green background</ins> indicates ' +
190 'properties present in the working version but missing in the ' + 171 'properties present in the working version but missing in the ' +
191 'transmuxed output.</p>'; 172 'transmuxed output.</p>';
192 diff += QUnit.diff(stringify(transmuxed, null, ' '), 173 diff += '<pre class="mp4-diff">' +
193 stringify(workingParsed, null, ' ')); 174 QUnit.diff(videojs.textifyMp4(transmuxed, null, ' '),
175 videojs.textifyMp4(workingParsed, null, ' ')) +
176 '</pre>';
177
194 comparison.innerHTML = diff; 178 comparison.innerHTML = diff;
195 }; 179 };
196 180
...@@ -252,7 +236,7 @@ ...@@ -252,7 +236,7 @@
252 diffParsed(); 236 diffParsed();
253 237
254 // clear old box info 238 // clear old box info
255 vjsBoxes.innerHTML = stringify(vjsParsed, null, ' '); 239 vjsBoxes.innerHTML = videojs.textifyMp4(vjsParsed, null, ' ');
256 240
257 // write out the result 241 // write out the result
258 hex += '<pre>'; 242 hex += '<pre>';
...@@ -279,7 +263,7 @@ ...@@ -279,7 +263,7 @@
279 diffParsed(); 263 diffParsed();
280 264
281 // clear old box info 265 // clear old box info
282 workingBoxes.innerHTML = stringify(workingParsed, null, ' '); 266 workingBoxes.innerHTML = videojs.textifyMp4(workingParsed, null, ' ');
283 267
284 // output the hex dump 268 // output the hex dump
285 hex += '<pre>'; 269 hex += '<pre>';
...@@ -288,7 +272,7 @@ ...@@ -288,7 +272,7 @@
288 workingOutput.innerHTML = hex; 272 workingOutput.innerHTML = hex;
289 273
290 // XXX Media Sources Testing 274 // XXX Media Sources Testing
291 //window.vjsSourceBuffer.appendBuffer(bytes); 275 // window.vjsSourceBuffer.appendBuffer(bytes);
292 }); 276 });
293 reader.readAsArrayBuffer(this.files[0]); 277 reader.readAsArrayBuffer(this.files[0]);
294 }, false); 278 }, false);
......