Skip to content

Commit ad08cc7

Browse files
committed
Fix Chrome for Android bug and add ftyp atom check
1 parent b4cf030 commit ad08cc7

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
build
2+
compiler.jar

src/analyze.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
MP4.analyze = function(blob, callback) {
22
if (!(blob instanceof Blob)) throw new TypeError("Invalid argument type");
3-
if (blob.type != "video/mp4" && blob.type != "video/quicktime" && blob.type != "audio/mp4") {
4-
throw new TypeError("Input data format is not mp4/mov");
5-
}
63

74
var ab = new ArrayBuffer(8);
85
var dv = new DataView(ab);
@@ -13,9 +10,25 @@ MP4.analyze = function(blob, callback) {
1310
atom.dataSize = -8;
1411
atom.parsed = true;
1512

16-
MP4.Atoms.visitChildren(atom, blob, new MP4.Context(), function(context) {
17-
callback(context.result());
18-
});
13+
var reader = new FileReader();
14+
reader.onloadend = function(ev) {
15+
if (ev.target.readyState === FileReader.DONE) {
16+
if (ev.target.result != "ftyp") {
17+
var context = new MP4.Context();
18+
context.error = new Error("Input data format is not mp4/mov");
19+
callback(context.result());
20+
return;
21+
}
22+
23+
blob.rewind();
24+
MP4.Atoms.visitChildren(atom, blob, new MP4.Context(), function(context) {
25+
callback(context.result());
26+
}, reader);
27+
}
28+
};
29+
30+
blob.skip(4);
31+
reader.readAsText(blob.poll(4));
1932

2033
return true;
2134
}

src/context.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ MP4.Context = function() {
2626
/** @type {?MP4.Track} */
2727
this.currentTrack = null;
2828

29+
/** @type {?Error} */
30+
this.error = null;
2931
/** @type {?MP4.Track} */
3032
this.video = null;
3133
/** @type {?MP4.Track} */
@@ -36,7 +38,11 @@ MP4.Context = function() {
3638
* @return Object.<string, *>
3739
*/
3840
this.result = function() {
41+
if (!this.video && !this.audio && !this.error)
42+
this.error = new Error("Cannot find codec information");
43+
3944
return {
45+
'error': this.error,
4046
'video': this.video && {
4147
'codec': this.video.codec
4248
},

src/visitor.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ MP4.Atoms.visitChildren = function(parent, blob, context, callback, reader) {
1616
reader.onloadend = function(ev) {
1717
if (ev.target.readyState === FileReader.DONE) {
1818
if (ev.target.result.byteLength < MP4.Atoms.Atom.HeaderSize) {
19+
context.error = new Error("Input data is corrupted or not encoded as mp4/mov");
1920
callback(context);
2021
return;
2122
}
@@ -24,6 +25,7 @@ MP4.Atoms.visitChildren = function(parent, blob, context, callback, reader) {
2425

2526
var atom = new MP4.Atoms.Atom(data, 0);
2627
if (atom.size < atom.headerSize) {
28+
context.error = new Error("Input data is corrupted or not encoded as mp4/mov");
2729
callback(context);
2830
return;
2931
}
@@ -62,16 +64,22 @@ MP4.Atoms.visitor = function(atom, blob, context, callback) {
6264
if (!atom.parsed) {
6365
if (MP4.Atoms.Map[atom.type].parser) {
6466
var reader = new FileReader();
67+
var parsedSize = MP4.Atoms.Map[atom.type].parsedSize == -1 ? atom.size : MP4.Atoms.Map[atom.type].parsedSize;
6568

6669
reader.onloadend = function(ev) {
6770
if (ev.target.readyState === FileReader.DONE) {
71+
if (ev.target.result.byteLength < parsedSize) {
72+
context.error = new Error("Input data is corrupted or not encoded as mp4/mov");
73+
callback(context);
74+
return;
75+
}
76+
6877
var data = new DataView(ev.target.result);
6978
atom = MP4.Atoms.Map[atom.type].parser(context, data, 0);
7079
MP4.Atoms.visitChildren(atom, blob, context, callback, reader);
7180
}
7281
};
7382

74-
var parsedSize = MP4.Atoms.Map[atom.type].parsedSize == -1 ? atom.size : MP4.Atoms.Map[atom.type].parsedSize;
7583
reader.readAsArrayBuffer(blob.poll(parsedSize));
7684
} else {
7785
atom.dataSize = MP4.Atoms.Map[atom.type].parsedSize-atom.headerSize;

0 commit comments

Comments
 (0)