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

2023-12-26

我正在尝试向我的 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();
            }
        }
    });
});

filesystem:协议存储参考相同来源的文件document其中要求LocalFileSystem。也就是说,如果问题处的 JavaScript 是在以下位置创建的:http://example.org,路径为LocalFileSystem应该同源http://example.org, not file:协议。

如果您尝试存储文件或文件夹以供访问file:协议,离线,您可以创建一个.html用作模板书签的文档。

参观当地.html在线归档一次以获取文件并填充LocalFileSystem. If navigator.onLine is true, 导航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>

也可以看看

  • 如何在 file: 协议中使用 webkitRequestFileSystem https://stackoverflow.com/questions/37502091/how-to-use-webkitrequestfilesystem-at-file-protocol

  • 如何使用javascript打印文件夹内的所有txt文件 https://stackoverflow.com/questions/37634049/how-to-print-all-the-txt-files-inside-a-folder-using-java-script/

  • 用JS读取本地XML https://stackoverflow.com/questions/41279589/read-local-xml-with-js/

  • 如何使用JavaScript写入文件(用户目录)? https://stackoverflow.com/questions/36098129/how-to-write-in-file-user-directory-using-javascript/


另一种方法可能是利用ServiceWorker

  • 将 Service Worker 和 Offline 添加到您的 Web 应用程序中 https://developers.google.com/web/fundamentals/getting-started/codelabs/offline/

  • Service Worker 示例:自定义离线页面示例 https://googlechrome.github.io/samples/service-worker/custom-offline-page/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 具有多维数组的 tf.SequenceExample

    在 Tensorflow 中 我想将多维数组保存到 TFRecord 例如 1 2 3 1 2 3 2 1 由于我试图解决的任务是连续的 因此我尝试使用 Tensorflowtf train SequenceExample 当写入数据时 我
  • 如何在 Jetpack Compose 中禁用和启用 LazyColumn/LazyRow 中的滚动?

    我想以编程方式动态启用和禁用滚动LazyColumn 好像没有相关功能LazyListState或相关参数LazyColumn本身 我怎样才能在 Compose 中实现这一目标 Since 1 2 0 userScrollEnabled范围
  • 如何从 QVBoxLayout 中删除(子)布局项?

    我找到了很多关于从 QVBoxLayout 中删除小部件的答案 但我没有找到任何有关删除布局的答案 我知道我可以将我的子布局放入 QWidget 中 我只是想了解更多 layout QtGui QVBoxLayout item in lay
  • 使用 OpenCV 读取 mp4 (Go Pro) 视频

    在 Visual Studio 2013 中使用带有 C 接口的 OpenCV 时 我在读取某些视频文件时遇到困难 我已经能够读取其他视频格式 因此相信我的代码没问题 问题视频文件是使用 Go Pro 拍摄的 格式为 mp4 我可以在使用
  • 为什么我的表单无法在 Internet Explorer 9 中上传文件?

    欢迎收看第 32 342 343 集 为什么 Internet Explorer 这么糟糕 我看到很多报道称 IE9 在上传文件方面表现不佳 显然 它有很多关于何时有效或无效的警告 如果有人有明确的列表 我很乐意看到它 然而 我发现的大多数
  • Mixpanel 人物个人资料头像图片

    我已经在互联网上搜索了此问题的解决方案 但无济于事 是否可以将我们用户的个人资料图片设置为 Mixpanel 人员报告中的个人资料图片 我尝试在声明 Mixpanel 用户属性的方法中调用我们的用户图片对象 但它没有更新照片 这里有最佳实践
  • Mean.js req.isAuthenticated 显示失败?

    我已经下载了meanjs 电子邮件受保护 cdn cgi l email protection我使用了两台服务器作为前端 我使用了 Angular 和 ionic 它在 localhost 3000 中运行 对于后端 我使用了meanjs
  • 从数组循环渲染组件

    在我的 app component ts 中 我有一个包含组件标签的数组 compData app component one app component two app component three 然后在我的 app componen
  • 链接:致命错误 LNK1104:无法打开文件“D:\...\MyProj.exe”

    使用 Visual Studio 2010 当我在短时间内构建 运行我的应用程序时 经常会收到以下错误 如果我等一两分钟再试一次就可以了 Unlocker http www emptyloop com unlocker 声称没有句柄锁定可执
  • 如何检查nodejs中的标头?

    这是运行良好的实际代码 但我想检查我的标头是否很好地传输到我的 api var request require request var express require express var router express Router GE
  • 多人网络游戏中的同步?

    最近我一直在开发一个多人网络应用程序 我已经使用 Bonjour 服务和 NSStream 对象成功实现了客户端服务器模型 双向通信已成功完成 我面临的问题是 运行该应用程序的两个设备通过本地 wifi 连接 从客户端向服务器发送消息时存在
  • 如何从 DynamoDB 获取每个主分区键的最新数据?

    我在 dynamodb 中有一张表 它存储帐户统计信息 帐户统计数据可能每天会更新多次 所以表记录可能如下所示 account id record id views stars 3 2019 03 16 1 29 3 2 2019 03 1
  • 将 numpy.stack() 与 numba njit 一起使用时出现打字错误

    最初的问题与使用有关np linspace使用数组作为开始和停止参数 尽管现在我遇到了我想出的解决方法的问题 采取以下措施 from numba import njit import numpy as np njit def f1 star
  • Rails 3.1 使文件夹公开

    你好 我是 Rails 新手 在我的 RoR 应用程序文件夹中 我有一个文件夹 app FOLDER 我想公开 有需要从浏览器获取的脚本文件 我该怎么做 在最新的 Rails 中 文件应存在于以下位置之一 app assets lib as
  • Intellij IDEA。始终显示maven的`target`目录

    使用Intellij IDEA创建maven项目时 默认情况下target目录在项目资源管理器中不可见 但我可以通过将其从模块设置中的排除文件夹中删除来使其可见 但它的作用时间很短 10 15分钟后target目录再次不可见 所以我需要再次
  • tinymce 无法在 Firefox 上运行

    我有三个文本区域 使用tinymce 作为文本区域 它们都可以在 Chrome 上运行 但不能在 Firefox 上运行 我正在使用 php 代码从 mysql 加载文本 第一个文本区域加载正常并且可以工作 但其他两个文本区域会短暂闪烁内容
  • Web Share API 级别 2 DOMException:权限被拒绝

    我正在获取一个 img 将其转换为一个文件 然后尝试共享该文件 我在 Android 上最新的 Chrome 目前唯一支持此 API 的浏览器 上测试了代码 if shareimg navigator canShare share asyn
  • 为什么我收到“UserWarning:模块 dap 已从 None 导入...”

    I have python matplotlib and python mpltoolkits basemap从 Ubuntu 软件包安装 安装中python mpltoolkits basemap还安装python dap作为依赖 当我导
  • React.lazy 无法在生产模式下工作

    我有一个正在运行的 React 应用程序 我想使用 React lazy 添加基于路由的代码分割 目前我的代码是 import PureComponent cloneElement Suspense lazy from react expo
  • 使用文件系统作为离线播放的视频源

    我正在尝试向我的 HTML5 视频播放器添加离线功能 我正在尝试将文件作为 blob 写入 chrome 文件系统 然后从那里读取它们 我相信我遇到了一个问题 文件实际上并未被写入 只是文件名 由于我的以下代码目前已构成 因此它可以工作 但