IndexedDB - 存储和检索视频

5

我正在尝试创建一个应用程序,将视频文件存储到IndexedDB并从中检索。然而,在Firefox中检索和在Chrome中存储时遇到了问题。以下是代码:

(function () {
    // IndexedDB
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
        IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
        dbVersion = 1.0;

    // Create/open database
    var request = indexedDB.open("videoFiles", dbVersion);
        var db;
        var createObjectStore = function (dataBase) {
            // Create an objectStore
            console.log("Creating objectStore")
            dataBase.createObjectStore("earth");
        },

        getVideoFile = function () {
            // Create XHR
            var xhr = new XMLHttpRequest(),
                blob;

            xhr.open("GET", "day_the_earth_stood_still.ogv", true);
            // Set the responseType to blob
            xhr.responseType = "blob";

            xhr.addEventListener("load", function () {
                if (xhr.status === 200) {
                    console.log("Video retrieved");

                    // Blob as response
                    blob = xhr.response;
                    console.log("Blob:" + blob);

                    // Put the received blob into IndexedDB
                    putEarthInDb(blob);
                }
            }, false);
            // Send XHR
            xhr.send();
        },

        putEarthInDb = function (blob) {
            console.log("Putting earth in IndexedDB");

            // Open a transaction to the database
            var transaction = db.transaction(["earth"], "readwrite");

            // Put the blob into the dabase
            var put = transaction.objectStore("earth").put(blob, "video");




            // Retrieve the file that was just stored
            transaction.objectStore("earth").get("video").onsuccess = function (event) {
                var vidFile = event.target.result;
                console.log("Got earth!" + vidFile);
                console.log('File Type: ' + vidFile.type); /// THIS SHOWS : application/xml

                // Get window.URL object
                var URL = window.URL || window.webkitURL;

                // Create and revoke ObjectURL
                var vidURL = URL.createObjectURL(vidFile);

                // Set vid src to ObjectURL

                var vidEarth = document.getElementById("earth");
                vidEarth.setAttribute("src", vidURL);




                // Revoking ObjectURL
                URL.revokeObjectURL(vidURL);
            };
        };

    request.onerror = function (event) {
        console.log("Error creating/accessing IndexedDB database");
    };

    request.onsuccess = function (event) {
        console.log("Success creating/accessing IndexedDB database");
        db = request.result;

        db.onerror = function (event) {
            console.log("Error creating/accessing IndexedDB database");
        };

        // Interim solution for Google Chrome to create an objectStore. Will be deprecated
        if (db.setVersion) {
            if (db.version != dbVersion) {
                var setVersion = db.setVersion(dbVersion);
                setVersion.onsuccess = function () {
                    createObjectStore(db);
                    getVideoFile();
                };
            }
            else {
                getVideoFile();
            }
        }
        else {
            getVideoFile();
        }
    }

    // For future use. Currently only in latest Firefox versions
    request.onupgradeneeded = function (event) {
        createObjectStore(event.target.result);
    };
})();

问题1(火狐浏览器):在火狐浏览器中,上面的代码console.log('文件类型:'+vidFile.type);在获取视频文件(mp4、ogv、webm)时会显示“application/xml”,因此Video标签会显示“不支持视频格式或MIME类型”。但是,如果获取的是像png这样的图片文件,则会显示“image/png”,并且如果将img标签的src设置了则可以正常工作。

问题2(谷歌浏览器):在谷歌浏览器中,无论是图像还是视频都没有被存储到IndexedDB中。在以下代码行:

var put = transaction.objectStore("earth").put(blob, "video");

引发了未捕获的错误: 抛出了DataCloneError: DOM IDBDatabase Exception 25。

我对IndexedDB一无所知,不知道如何解决这个问题。我只需要将视频文件存储到IndexedDB中,检索并在Video标签中显示。

以下是HTML代码(mp4):

 <div class="myVidDiv">
    <video  id="earth" type="video/mp4" codecs="avc1.42e01e, mp4a.40.2" controls>  </video>
 </div>

(ogv):
 <div class="myVidDiv">
    <video  id="earth" type="video/ogg" codecs="theora, vorbis" controls></video>
 </div>

我也尝试了不加“codecs”属性的方法,但没有作用。我被这问题困扰了好几天……在谷歌上也找不到任何可行的例子。请有人帮帮我。


关于Chrome的问题,你确定对象存储已经被创建了吗? - MaxArt
实际上,在Chrome中仍不支持存储blob。抱歉。您可能需要改用文件系统API,并回退存储blob。 - MaxArt
哦,是吗?谢谢你提供这个信息,Max。但这是我的一项作业,使用indexedDB是强制性的,这是作业的关键。所以至少在Firefox中,你有什么线索可以解释为什么从数据库检索的blob数据类型是“application/xml”,而不是像“video/ogg”或“video/mp4”之类的东西,这导致HTML5视频元素说“不支持视频格式或MIME类型”..? - user2104377
当您通过XHR检索视频时,服务器发送的Content-Type标头是什么? - MaxArt
console.log('xhr响应类型:' + xhr.response.type); 我发现即使在存储到数据库之前,xhr的响应类型对于视频文件是“application/xml”,但对于png图像文件则为“image/png”...我不知道为什么它会将视频文件视为“application/xml”类型。 - user2104377
显示剩余4条评论
1个回答

1

好的,我会尝试总结一下从评论中得出的内容。

1. Firefox

看起来最初从AJAX请求中获取到的Blob对象的内容类型为application/xml,因为这是从服务器响应中获取的。这可能是配置不正确的问题。

如果您可以访问HTTP服务器的配置,那么问题可能很容易解决。如果是Apache,您只需添加以下行:

AddType video/ogg .ogv

保存并重启Apache,这样应该就可以了。如果您无法更改服务器配置,则必须更改Blob的内容类型以匹配所需的类型:

blob = xhr.response.slice(0, xhr.response.size, "video/ogg");

注意,这可能会消耗大量内存,因为您正在复制一个(可能)很大的文件,但是xhr.response在几个步骤之后应该被清除。
2. Chrome 看起来Chrome仍然不支持BlobFile存储
似乎他们已经修复了这个问题,但还没有部署修复程序。我想知道他们在等什么:[
更新:截至2014年7月1日,Chrome dev 支持将Blob存储到IndexedDB中。它预计很快就会登陆稳定通道。

非常感谢你花时间帮我。但是它仍然是"application/xml"类型的.. :( blob = xhr.response.slice(0, xhr.response.size, "video/ogg"); console.log(blob.type); // 这仍然是 application/xml.. 视频元素也有同样的错误。这真让我抓狂! - user2104377
我认为Google正在推动FileSystem API,而不是IndexedDB中的Blob。 - Kyaw Tun
@user2104377 试试克隆它怎么样? blob = new Blob([xhr.response], "video/ogg"); - MaxArt
@user2104377 你可以使用overrideMimeType()函数覆盖mime类型,该函数作为XMLHttpRequest LEVEL 2规范的一部分被引入。 - goonerify

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接