我正在尝试制作一个应用程序,用于在 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(Firefox):在 Firefox 中,console.log('文件类型:' + vidFile.type); 行上面显示“application/xml”,同时获取视频文件(mp4、ogv、webm),因此视频标签显示“不支持视频格式或 mime 类型”。 但是,当我获取像 png 这样的图像文件时,它会显示“image/png”,并且如果设置了 img 标签的 src,则效果很好。
问题2(Chrome):在Chrome中,图像和视频甚至都没有存储到IndexedDB中。在以下行:
var put = transaction.objectStore("earth").put(blob, "video");
未捕获错误:DataCloneError:抛出 DOM IDBDatabase 异常 25。
我是 IndexedDB 的新手,不知道如何解决这个问题。我需要做的就是将视频文件存储到indexedDB中,检索它并在视频标签中显示。
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>
也尝试过没有“编解码器”属性。什么都不起作用。我已经被这个问题困扰了好几天了......也无法通过谷歌找到任何工作示例。有人好心帮我解决这个问题。
好吧,我会尝试总结一下评论中的内容。
1。火狐
最初,您从 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仍然不支持
Blob
和File
存储。
他们似乎已经解决了问题,但尚未部署修复程序。我想知道他们在等什么:[
更新:自 2014 年 7 月 1 日起,Chrome 开发者支持将 blob 存储到 IndexedDB 中。预计很快就会登陆稳定频道。
let request = window.indexedDB.open("videoDatabase", 1);
request.onupgradeneeded = function(event) {
let db = event.target.result;
let objectStore = db.createObjectStore("videos", { keyPath: "id", autoIncrement: true });
};
将视频添加到数据库:
function addVideo(videoBlob) {
let request = db.transaction(["videos"], "readwrite")
.objectStore("videos")
.add({ video: videoBlob });
request.onsuccess = function(event) {
console.log("Video added to the database");
};
request.onerror = function(event) {
console.error("Error adding video to the database");
};
}
从数据库检索视频:
function getVideo(videoId, callback) {
let transaction = db.transaction(["videos"]);
let objectStore = transaction.objectStore("videos");
let request = objectStore.get(videoId);
request.onsuccess = function(event) {
let videoBlob = event.target.result.video;
callback(videoBlob);
};
request.onerror = function(event) {
console.error("Error retrieving video from the database");
};
}
使用 Blob 获取视频数据:
确保在存储之前将视频数据转换为 Blob,并在检索视频时使用 URL.createObjectURL() 方法为视频创建 URL。
// Example of converting video file input to Blob
let input = document.getElementById("videoInput");
let videoBlob;
input.addEventListener("change", function() {
let file = input.files[0];
let reader = new FileReader();
reader.onloadend = function() {
videoBlob = new Blob([reader.result], { type: file.type });
};
reader.readAsArrayBuffer(file);
});
用法示例:
// Assuming db is the IndexedDB database
addVideo(videoBlob);
// Retrieving the video
getVideo(1, function(videoBlob) {
let videoUrl = URL.createObjectURL(videoBlob);
// Use the videoUrl to display or work with the video
});