Using File System As Source Of Videos For Playing Offline
Solution 1:
filesystem:
protocol stores files with reference to same origin as document
which requests LocalFileSystem
. That is, if JavaScript at Question is created at, for example, http://example.org
, the path to LocalFileSystem
should be same origin as http://example.org
, not file:
protocol.
If you are trying to store files or folders for accessing at file:
protocol, offline, you can create an .html
document to use as a template bookmark.
Visit the local .html
file once while online to get files and populate LocalFileSystem
. If navigator.onLine
is true
, navigate to http://example.org
, else get and process files and folders stored at LocalFileSystem
.
Create a list as JSON
or JavaScript Array
to store list of files to fetch, instead of parsing an .html
document
for file locations.
Store local file as a bookmark. Launch Chromium, Chrome with --allow-file-access-from-files
flag set to access filesystem:
protocol from file:
protocol and file:
protocol at filesystem:
protocol, if not online.
<!DOCTYPE html><html><head><title>LocalFileSystem Offline Videos Bookmark</title></head><body><script>// location to visit if onlineconst onLineURL = "https://lorempixel.com/"
+ window.innerWidth
+ "/"
+ window.innerHeight + "/cats";
const props = {
requestedBytes: 1024 * 1024 * 20000,
folder: "videos",
// list of files to fetch for offline viewingmediaList: [
"http://mirrors.creativecommons.org/movingimages/webm/"
+ "ScienceCommonsJesseDylan_240p.webm"
, "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4"
]
};
let grantedBytes = 0;
functiongetLocalFileSystem ({requestedBytes = 0, mediaList=[], folder = ""}) {
if (!requestedBytes || !mediaList.length || !folder) {
thrownewError("requestedBytes: Number"
+ " or mediaList: Array"
+ " or folder: String not defined");
};
// do stuff with `filesystem:` URLfunctionprocessLocalFilePath(localPath) {
const video = document.createElement("video");
document.body.appendChild(video);
video.controls = true;
video.src = localPath;
}
functionerrorHandler(err) {
console.log(err);
}
functionwriteFile(dir, fn, fp, localPath) {
console.log(dir, fn, fp, localPath);
dir.getFile(fn, {}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
// do stuff when file is writtenconsole.log(e.type, localPath + " written");
window.webkitResolveLocalFileSystemURL(localPath
, function(file) {
// file exists in LocalFileSystemprocessLocalFilePath(localPath);
}, errorHandler)
};
fileWriter.onerror = errorHandler;
fetch(fp).then(function(response) {
return response.blob()
}).then(function(blob) {
fileWriter.write(blob);
}).catch(errorHandler)
}, errorHandler);
}, errorHandler);
}
if (mediaList && mediaList.length) {
navigator.webkitTemporaryStorage.requestQuota(requestedBytes
, function(grantedBytes_) {
grantedBytes = grantedBytes_;
console.log("Requested bytes:", requestedBytes
, "Granted bytes:", grantedBytes);
window.webkitRequestFileSystem(window.TEMPORARY
, grantedBytes
, function(fs) {
const url = fs.root.toURL();
mediaList.forEach(function(filename) {
const localPath = url + folder + "/"
+ filename.split("/").pop();
window.webkitResolveLocalFileSystemURL(localPath
, function(file) {
// file exists in LocalFileSystemconsole.log(localPath + " exists at LocalFileSystem");
processLocalFilePath(localPath)
}, function(err) {
console.log(err, localPath
+ " not found in LocalFileSystem");
// Exception is thrown if file // or folder path not found// create `folder` directory, get files
fs.root.getDirectory(folder, {}
, function(dir) {
writeFile(dir
, filename.split("/").pop()
, filename
, localPath);
}),
errorHandler
})
})
})
}, errorHandler)
}
}
if (location.href !== onLineURL && navigator.onLine) {
location.href = onLineURL;
} else {
getLocalFileSystem(props);
}
</script></body></html>
See also
An alternative approach could be to utilize ServiceWorker
Solution 2:
Your user must grant your app permission to store data locally before your app can use persistent storage. That's why you have to request quota first. The amount of bytes you ask for is 200000 * 1024 * 1024 bytes.
window.storageInfo.requestQuota(PERSISTENT, 200000 * 1024 * 1024,
function(grantedBytes) {
window.requestFileSystem(window.PERSISTENT, grantedBytes, onInitFs, errorHandler);
},
errorHandler
);
I noticed you are writing this for Chrome, here's how you manage the quota in Chrome
Post a Comment for "Using File System As Source Of Videos For Playing Offline"