-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoffline_download_util.js
183 lines (160 loc) · 5.15 KB
/
offline_download_util.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
* UI callback for when the download button is clicked. This will
* disable the button while the download is in progress, start the
* download, and refresh the content list once the download is
* complete.
*/
function onDownloadClick() {
const downloadButton = document.getElementById("download-button");
// Disable the download button to prevent user from requesting
// another download until this download is complete.
downloadButton.disabled = true;
setDownloadProgress(null, 0);
// Download the content and then re-enable the download button so
// that more content can be downloaded.
downloadContent(window.manifestURL, "Big bunny buck")
.then(function () {
return refreshContentList();
})
.then(function (content) {
setDownloadProgress(null, 1);
downloadButton.disabled = false;
})
.catch(function (error) {
// In the case of an error, re-enable the download button so
// that the user can try to download another item.
downloadButton.disabled = false;
onError(error);
});
}
function initStorage() {
// Create a storage instance and configure it with optional
// callbacks. Set the progress callback so that we visualize
// download progress and override the track selection callback.
window.storage = new shaka.offline.Storage();
window.storage.configure({
offline: {
usePersistentLicense: true,
progressCallback: setDownloadProgress,
trackSelectionCallback: selectTracks,
},
drm: {
servers: {
'com.widevine.alpha': WIDEVINE_LICENSE_URL + "&download=true",
},
},
});
window.storage.getNetworkingEngine().registerRequestFilter(function (type, request) {
if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
request.headers['Content-type'] = 'application/octet-stream';
}
});
}
/*
* Find our progress bar and set the value to show the progress we
* have made.
*/
function setDownloadProgress(content, progress) {
const progressBar = document.getElementById("progress-bar");
progressBar.value = progress * progressBar.max;
}
function selectTracks(tracks) {
// This example stores the highest bandwidth variant.
//
// Note that this is just an example of an arbitrary algorithm, and not a best
// practice for storing content offline. Decide what your app needs, or keep
// the default (user-pref-matching audio, best SD video, all text).
console.log(tracks);
const found = tracks
.filter(function (track) {
return track.type == "variant";
})
.sort(function (a, b) {
return a.bandwidth - b.bandwidth;
})
.pop();
console.log(found);
console.log("Offline Track bandwidth: " + found.bandwidth);
return [found];
}
function listContent() {
return window.storage.list();
}
function playContent(content) {
window.player.load(content.offlineUri);
}
function removeContent(content) {
return window.storage.remove(content.offlineUri);
}
function downloadContent(manifestUri, title) {
// Construct a metadata object to be stored along side the content.
// This can hold any information the app wants to be stored with the
// content.
const metadata = {
title: title,
downloaded: Date(),
};
return window.storage.store(manifestUri, metadata).promise; // TODO : save content with storage.
}
/*
* Update the online status box at the top of the page to tell the
* user whether or not they have an internet connection.
*/
function updateOnlineStatus() {
const signal = document.getElementById("online-signal");
if (navigator.onLine) {
signal.innerHTML = "ONLINE";
signal.style.background = "green";
} else {
signal.innerHTML = "OFFLINE";
signal.style.background = "grey";
}
}
/*
* Clear our content table and repopulate it table with the current
* list of downloaded content.
*/
function refreshContentList() {
const contentTable = document.getElementById("content-table");
// Clear old rows from the table.
while (contentTable.rows.length) {
contentTable.deleteRow(0);
}
const addRow = function (content) {
const append = -1;
const row = contentTable.insertRow(append);
row.insertCell(append).innerHTML = content.offlineUri;
Object.keys(content.appMetadata)
.map(function (key) {
return content.appMetadata[key];
})
.forEach(function (value) {
row.insertCell(append).innerHTML = value;
});
row.insertCell(append).appendChild(
createButton("PLAY", function () {
playContent(content);
})
);
row.insertCell(append).appendChild(
createButton("REMOVE", function () {
removeContent(content).then(function () {
refreshContentList();
});
})
);
};
return listContent().then(function (content) {
content.forEach(addRow);
});
}
/*
* Create a new button but do not add it to the DOM. The caller
* will need to do that.
*/
function createButton(text, action) {
const button = document.createElement("button");
button.innerHTML = text;
button.onclick = action;
return button;
}