-
Notifications
You must be signed in to change notification settings - Fork 3
/
blobCapWorkaround.js
124 lines (113 loc) · 3.84 KB
/
blobCapWorkaround.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
console.log("blob repro");
// (this is ugly, I know. writen as a proof of concept)
// Workaround for saving blobs larger than 500MB.
// Main idea: add and then get the blob from indexeddb to
// force it to be file-backed. Then concatinate all of the file-backed
// blobs to make the > 500MB blob that can then be downloaded.
function convertDataBlobToFileBlob(blob) {
return new Promise(function(resolve, reject) {
var db;
var request = indexedDB.open("TestDB");
var deleteEntry = function(key, blob) {
console.log("delete got key ", key, " and blob ", blob);
return new Promise(function(resolve, reject) {
var t = db.transaction(["fileStore"], "readwrite");
t.oncomplete = function(event) {
console.log("delete trans opened");
}
t.onerror = function(event) {
reject(event);
}
var objectStore = t.objectStore("fileStore");
var objectStoreRequest = objectStore.delete(key);
objectStoreRequest.onsuccess = function(event) {
resolve(blob);
}
});
};
var putEntry = function(blob) {
return new Promise(function(resolve, reject) {
var t = db.transaction(["fileStore"], "readwrite");
t.oncomplete = function(event) {
console.log("save trans opened");
}
t.onerror = function(event) {
reject(event);
}
var objectStore = t.objectStore("fileStore");
var request = objectStore.put(blob);
// blob.close();
// ^^ this guarentees that the blob passed in is released.
// you have to enable --enable-experimental-web-platform-features
// (or see about://flags) to enable this.
request.onsuccess = function(event) {
resolve(request.result);
}
});
};
var getEntry = function(key) {
return new Promise(function(resolve, reject) {
var t = db.transaction(["fileStore"], "readwrite");
t.oncomplete = function(event) {
console.log("save trans opened");
}
t.onerror = function(event) {
reject(event);
}
var objectStore = t.objectStore("fileStore");
var request = objectStore.get(key);
request.onsuccess = function(event) {
resolve({ blob: request.result, key: key });
}
});
};
request.onerror = function(evt) {
reject("Database error code: " + evt.target.errorCode);
};
request.onupgradeneeded = function (evt) {
var db = event.target.result;
db.onerror = function(event) {
console.log("Error onupgrade");
};
evt.currentTarget.result.createObjectStore(
"fileStore", { autoIncrement: true });
};
request.onsuccess = function(evt) {
db = request.result;
putEntry(blob).then(function(key) {
return getEntry(key);
}).then(function(blobkey) {
return deleteEntry(blobkey.key, blobkey.blob);
}).then(function(blob) {
resolve(blob);
}).catch(function(err) {
console.log("Error!", err);
reject(err);
});
};
});
}
var blob = new Blob([new Uint8Array(200*1024*1024)], {type: 'application/octet-string'});
console.log(blob);
var allblobs = [];
// you can create an array of promises, one for each chunk, and then resolve them all.
convertDataBlobToFileBlob(blob).then(function(blob) {
console.log("did it! ", blob);
allblobs.push(blob);
var nextBlob = new Blob([new Uint8Array(200*1024*1024)], {type: 'application/octet-string'});
return convertDataBlobToFileBlob(nextBlob);
}).then(function(blob) {
console.log("did it 2! ", blob);
allblobs.push(blob);
var nextBlob = new Blob([new Uint8Array(200*1024*1024)], {type: 'application/octet-string'});
return convertDataBlobToFileBlob(nextBlob);
}).then(function(blob) {
console.log("did it 3!", blob);
allblobs.push(blob);
}).then(function() {
var concat = new Blob(allblobs, {type: 'application/octet-string'});
console.log("concatinated blob: ", concat);
url_a = URL.createObjectURL(concat); // You can open url_a
console.log(url_a);
window.location = url_a;
});