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 online
const onLineURL = "https://lorempixel.com/"
+ window.innerWidth
+ "/"
+ window.innerHeight + "/cats";
const props = {
requestedBytes: 1024 * 1024 * 20000,
folder: "videos",
// list of files to fetch for offline viewing
mediaList: [
"http://mirrors.creativecommons.org/movingimages/webm/"
+ "ScienceCommonsJesseDylan_240p.webm"
, "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4"
]
};
let grantedBytes = 0;
function getLocalFileSystem ({requestedBytes = 0, mediaList=[], folder = ""}) {
if (!requestedBytes || !mediaList.length || !folder) {
throw new Error("requestedBytes: Number"
+ " or mediaList: Array"
+ " or folder: String not defined");
};
// do stuff with `filesystem:` URL
function processLocalFilePath(localPath) {
const video = document.createElement("video");
document.body.appendChild(video);
video.controls = true;
video.src = localPath;
}
function errorHandler(err) {
console.log(err);
}
function writeFile(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 written
console.log(e.type, localPath + " written");
window.webkitResolveLocalFileSystemURL(localPath
, function(file) {
// file exists in LocalFileSystem
processLocalFilePath(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 LocalFileSystem
console.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"