I am trying to create an offline video player that would download video content from my site for later viewing offline via an HTML5 video element. The code below works fine in Chrome for the desktop, but not on mobile (Nexus S smartphone, Nexus 7 tablet, 4.1 since only that runs chrome, which is required for the filesystem api). I am using the filesystem API that is supported by chrome on both the desktop and mobile.
I have confirmed it is correctly storing the file on the mobile device and I can retrieve the file correctly, but for some reason after retrieving the video from the localsystem chrome does not want to play the video. This is true whether I am using the html5 video element or whether I am navigating directly to the filesystem URL. When I use the html5 video element it returns the error media_err_not_supported. I have confirmed that the device can play the video if I navigate directly to it on my server (without first storing it using the filesystem api), so the issue is not a codec or video format problem. I am also using the video/mp4 mime type in both cases.
Again, this works on desktop, but not mobile. Any ideas?
Here is the code we are using:
<!DOCTYPE html >
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"> </script>
<script type="text/javascript">
var _fs;
var filename = "test3.mp4";
var diskSpaceRequired = 10 * 1024 * 1024;
$(document).ready(function () {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function onInitFs(fs) {
_fs = fs;
getVideo(fs);
}
if (!!window.requestFileSystem) {
window.webkitStorageInfo.requestQuota(
window.webkitStorageInfo.PERSISTENT,
diskSpaceRequired, // amount of bytes you need
function () { },
function () {}
);
window.requestFileSystem(window.PERSISTENT, diskSpaceRequired, onInitFs, function () { alert('error'); });
} else {
alert('not supported');
}
$("#play").on('click', playVideo);
$("#ourVideo").on('error', function(e) { console.log('ERROR!!!', e, arguments);
console.log($("#ourVideo")[0].error);
});
});
function playVideo() {
_fs.root.getFile(filename, {}, function (fileEntry) {
$("#ourVideo").attr('src', fileEntry.toURL());
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
$("#ourVideo").get(0).play();
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
function getVideo(fs) {
fs.root.getFile(filename, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fetchResource(fileWriter);
}, errorHandler);
}, errorHandler);
}
function errorHandler(e) {
console.log('error', e);
}
function fetchResource(fileWriter) {
console.log('fetchresource');
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.open("GET", "http://mydomain.com/trailer.mp4", true);
xhr.onload = function(e) {
if (this.status == 200) {
var bb = new WebKitBlobBuilder();
bb.append(this.response);
var blob = bb.getBlob("video\/mp4");
fileWriter.write(blob);
} else {
console.log(this.status);
}
};
xhr.send();
}
</script>
<title>foo</title>
</head>
<body>
<input type="button" value="Play Video" id="play"/>
<video id="ourVideo" controls="">
<source id="vidSource" type="video/mp4"/>
</video>
</body>
</html>