使用文件系统作为离线播放视频的来源

Kev*_*Moe 5 javascript google-chrome-os html5-filesystem

我正在尝试为我的HTML5视频播放器添加离线功能.我试图将文件作为blob写入chrome文件系统,然后从那里读取它们.我相信我遇到的问题是文件实际上并没有被写入,只是文件名.由于我的下面的代码目前已经构成,它仍然有效,但仍然只有它永久连接到互联网.我的目标是将文件下载到文件系统中的永久目录,然后在互联网断开连接时继续播放.

$(document).ready(function() {


    var dir = "http://www.kevmoe.com/networks/gsplayer/";
    var fileextension = ".mp4";
    var srcfiles = $.ajax({
        //This will retrieve the contents of the folder if the folder is configured as 'browsable'
        url: dir,
        success: function(data) {
            //List all .mp4 file names in the page
            $(data).find("a:contains(" + fileextension + ")").each(function() {
                var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", "");

                $("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>");
                async: false;


                window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;

                window.requestFileSystem(window.PERSISTANT, 200000 * 1024 * 1024, initFS, errorHandler);

                function initFS(fs) {
                    console.log('filesystem engaged'); // Just to check if everything is OK :)
                    // place the functions you will learn bellow here
                    function errorHandler(err) {
                        var msg = 'An error occured: ';
                    };

                    function createDir(rootDir, folders) {
                        rootDir.getDirectory(folders[0], {
                            create: true
                        }, function(dirEntry) {
                            if (folders.length) {
                                createDir(dirEntry, folders.slice(1));
                            }
                        }, errorHandler);
                    };

                    createDir(fs.root, 'files/video/'.split('/'));

                    fs.root.getDirectory('video', {}, function(dirEntry) {
                        var dirReader = dirEntry.createReader();
                        dirReader.readEntries(function(entries) {
                            for (var i = 0; i < entries.length; i++) {
                                var entry = entries[i];
                                if (entry.isDirectory) {
                                    console.log('Directory: ' + entry.fullPath);
                                } else if (entry.isFile) {
                                    console.log('File: ' + entry.fullPath);
                                }
                            }

                        }, errorHandler);
                    }, errorHandler);

                    fs.root.getFile(filename, {
                        create: true,
                        exclusive: true
                    }, function(fileEntry) {
                        fileEntry.createWriter(function(fileWriter) {
                            var blob = new Blob([data], {
                                type: 'video/mp4'
                            });
                            fileWriter.write(blob);
                        }, errorHandler);

                        console.log('file downloaded');
                    }, errorHandler);

                    //Try to add an event listener for when all files are finished loading into file system. Then use another function to source the videos locally.
                    var dirReader = fs.root.createReader();
                    var entries = [];

                    // Call the reader.readEntries() until no more results are returned.

                    dirReader.readEntries(function(results) {

                        //List all .mp4 file names in the page
                        $(results).find("a:contains(" + fileextension + ")").each(function() {
                            var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", "");

                            $("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>");
                            async: false;

                        }, errorHandler);
                    });
                };

                function errorHandler() {
                    console.log('An error occured');
                };
            });


            var videos = $('.video');
            //handle ending of video
            videos.find('video').on('ended', function() {
                playNextVideo(videos);
            });

            // start with the first one
            playNextVideo(videos);


            function playNextVideo(videoList) {
                var activeVideo = videoList.filter('.active').removeClass('active'), // identify active video and remove active class
                    activeIndex = videoList.index(activeVideo), // get the active video index in the group
                    nextVideo = videoList.eq(activeIndex + 1), // get the next video in line
                    actualVideo;

                // if there is no next video start from first
                if (nextVideo.length == 0) nextVideo = videoList.first();

                // pause all videos
                videoList.find('video').each(function() {
                    this.pause();
                })

                // get reference to next video element
                actualVideo = nextVideo.find('video').get(0);

                // add active class to next video
                nextVideo.addClass('active');

                // load and play
                actualVideo.volume = 0.04;
                actualVideo.load();
                actualVideo.play();
            }
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

gue*_*314 1

filesystem:协议存储参考与document请求相同的来源的文件LocalFileSystem。也就是说,如果问题处的 JavaScript 是在例如 处创建的,http://example.org则 的路径LocalFileSystem应与 相同http://example.org,而不是file:协议。

如果您尝试存储文件或文件夹以便通过file:协议脱机访问,您可以创建一个.html文档用作模板书签。

.html在线访问一次本地文件以获取文件并填充LocalFileSystem。如果navigator.onLinetrue,则导航到http://example.org,否则获取并处理存储在 的文件和文件夹LocalFileSystem

创建一个列表JSON或 JavaScriptArray来存储要获取的文件列表,而不是解析.html document文件位置。

将本地文件存储为书签。启动 Chromium、Chrome,并设置标志以从协议--allow-file-access-from-files访问协议和在协议处访问协议(如果不在线)。filesystem:file:file:filesystem:

<!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>
Run Code Online (Sandbox Code Playgroud)

也可以看看


另一种方法可能是利用ServiceWorker