├── .gitattributes
├── .gitignore
├── .jshintrc
├── .travis.yml
├── LICENSE
├── README.md
├── gulpfile.js
├── index.html
├── package-lock.json
├── package.json
├── src
├── manifest-object.js
├── parse-iiif-manifest.js
└── player.js
├── static
├── favicon.ico
├── main.js
├── manifests
│ ├── manifest_chopin_etude_aud.json
│ ├── manifest_chopin_etude_vid.json
│ └── manifest_lunchroom_manners.json
├── media
│ ├── Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.mp4
│ ├── Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.webm
│ └── chopin_etude.mp3
├── mei
│ └── demo.mei
├── player.js
├── ui.js
└── verovio-toolkit.js
└── webpack.config.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | index.html merge=ours
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # SublimeText
4 | *.sublime-project
5 | *.sublime-workspace
6 |
7 | /node_modules/
8 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "eqeqeq": true,
3 | "eqnull": true,
4 | "devel": true,
5 | "expr": true,
6 | "latedef": "nofunc",
7 | "node": true,
8 | "undef": true,
9 | "unused": true,
10 | "esversion": 6,
11 | "browser": true,
12 | "globals": {
13 | "$": false
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: 10
3 | os: osx
4 | sudo: false
5 |
6 | install:
7 | - npm install --no-spin
8 |
9 | script:
10 | - gulp develop:lint
11 |
12 | notifications:
13 | email: false
14 | slack:
15 | secure: E6faEXi4tTwbIL9AovjAxAhf1CQGUCuIG8nqViYeWek7jM/7rjNd4oiLGtKlQec4Sx/8Ld385rGtOayFGm0zArek42vsXxpja0U+FAoN8zft3xkZthjzy781fX5ya8wLz447ePRLsDZuEqmj8h2x3atXiHwDAhynIFJdn55+DynV0Ti+1OkWQqf6DB7sdVh+xw6aFYy6LEug6KXr+rVJCaG+/JalGPaJgYnkajiK11CUEWkEmmh5Xaz+uoec9yiQAPMDnl9e4d9DO7rWzSWmZs5nMC7vynr+w90jWXkILOtT3tgALulpujGd0UIQa8RuwDVKDSrGMo4Vej7j/Ll6xVpwEtdYnpfJG+NlXGQolcj9iOPb9unBW1PJXDjgXB420BSTbDLeNJGA+wg7Lbz2RtD+fAPgH/UOnHy30W+zp++bJp47FkexJQYvkXf5x55KTjgaWfI3KwpKasobr0D7nKg2vqHArwug3YohZ1Sjf04FLz40KXuWePrm5fttnet4rYnSn0BAGCToYZBg43U1yd3esPRFrzT0mcHYLAfUmZ7MnaEc3u4NoTGSdUoq1g2qqWT6EnZ/1jwqTs3SxuXp9tGNjHfD+nM8EG64GB5Rbvp/iUE7Gv51opUOOJJsmhzuKf33u+gBo283GzLVd827LuQIv2+1fwtuMfHBER8R/Rg=
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2021 Eric Han Liu, Andrew Kam, Gabriel Vigliensoni
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IIIF Audio/Video Player
2 | IIIF A/V Player (WIP)
3 |
4 | ## Usage
5 | - Clone the repo:
6 | ```bash
7 | git clone https://github.com/DDMAL/IIIF-AV-player.git
8 | ```
9 | - Install node modules with `npm install`.
10 | - Run `gulp` or `npm start` to build and start the server.
11 | - The server will now be running at `localhost:9001`.
12 |
13 | ## Making Changes
14 | If you wish to alter any of the `src` code, make sure to rebundle with `gulp develop:build`.
15 |
16 | It might be ideal to keep a server running in the background with `gulp develop:server &`, instead of running `gulp` every time you make a change.
17 |
18 | ## Integration
19 | To integrate this player with an independent webpage, include the following 3 scripts in your `index.html`:
20 | ```javascript
21 |
22 |
23 |
24 | ```
25 | The player and score will be created in a `.main` container div, which will be appended to the `body` once the script is run. If you wish to alter where the player is generated, edit `static/main.js`:
26 | ```javascript
27 | // line 41, change body to your target
28 | $('body').append(main);
29 | ```
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const webpack = require('webpack');
3 | const WebpackDevServer = require('webpack-dev-server');
4 | const gutil = require('gulp-util');
5 | const webpackConf = require('./webpack.config');
6 | const jshint = require('gulp-jshint');
7 |
8 | function webpackDevServer ()
9 | {
10 | let compiler = webpack(webpackConf);
11 |
12 | new WebpackDevServer(compiler,
13 | {
14 | stats: {
15 | colors: true
16 | }
17 | }).listen(9001, 'localhost', function (err)
18 | {
19 | if (err) throw new gutil.PluginError('webpack-dev-server', err);
20 | gutil.log('[webpack-dev-server]', 'http://localhost:9001/index.html');
21 | });
22 | }
23 |
24 | function lint (files)
25 | {
26 | return gulp.src(files)
27 | .pipe(jshint({lookup: true}))
28 | .pipe(jshint.reporter('jshint-stylish'))
29 | .pipe(jshint.reporter('fail')); // fails task if error
30 | }
31 |
32 | function lintSrc ()
33 | {
34 | return lint('src/*.js');
35 | }
36 |
37 | function lintMain ()
38 | {
39 | return lint('static/main.js');
40 | }
41 |
42 | function build (done)
43 | {
44 | webpack(webpackConf).run(done);
45 | }
46 |
47 | gulp.task('develop:lint', gulp.series(lintSrc, lintMain));
48 |
49 | gulp.task('develop:build', gulp.series('develop:lint', build));
50 | gulp.task('develop:server', webpackDevServer);
51 | gulp.task('develop', gulp.series('develop:lint', build, 'develop:server'));
52 | gulp.task('default', gulp.series('develop'));
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | IIIF AV Player
7 |
8 |
9 |
10 |
11 |
V3
12 | static/manifests/manifest_chopin_etude_aud.json
13 | static/manifests/manifest_chopin_etude_vid.json
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "IIIF-AV-player",
3 | "version": "1.0.0",
4 | "description": "IIIF A/V Player",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "gulp"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/DDMAL/IIIF-AV-player.git"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "bugs": {
18 | "url": "https://github.com/DDMAL/IIIF-AV-player/issues"
19 | },
20 | "homepage": "https://github.com/DDMAL/IIIF-AV-player#readme",
21 | "devDependencies": {
22 | "babel-cli": "^6.26.0",
23 | "babel-preset-env": "^1.7.0",
24 | "gulp": "^4.0.0",
25 | "gulp-jshint": "^2.1.0",
26 | "jshint": "^2.13.6",
27 | "jshint-stylish": "^2.2.1",
28 | "webpack": "^4.14.0",
29 | "webpack-cli": "^3.3.12",
30 | "webpack-dev-server": "^4.11.1"
31 | },
32 | "dependencies": {
33 | "gulp-util": "^3.0.8",
34 | "jquery": "^3.5.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/manifest-object.js:
--------------------------------------------------------------------------------
1 | import parseVersionManifest from './parse-iiif-manifest';
2 |
3 | class ManifestObject
4 | {
5 | constructor (url)
6 | {
7 | this.manifest;
8 | this.url = url;
9 | }
10 |
11 | fetchManifest (callback)
12 | {
13 | fetch(this.url, {
14 | headers: {
15 | "Accept": "application/json"
16 | }
17 | }).then( (response) =>
18 | {
19 | if (!response.ok)
20 | {
21 | alert('Could not get manifest! Make sure you provide a proper link.');
22 | }
23 | return response.json();
24 | }).then( (responseData) =>
25 | {
26 | this.setManifest(responseData, callback);
27 | });
28 | }
29 |
30 | setManifest (responseData, callback)
31 | {
32 | this.manifest = parseVersionManifest(responseData);
33 |
34 | callback(this.manifest);
35 | }
36 | }
37 |
38 | (function (global)
39 | {
40 | global.ManifestObject = global.ManifestObject || ManifestObject;
41 | }) (window);
--------------------------------------------------------------------------------
/src/parse-iiif-manifest.js:
--------------------------------------------------------------------------------
1 | import {Player} from './player';
2 |
3 | const getMaxZoomLevel = (width, height) =>
4 | {
5 | const largestDimension = Math.max(width, height);
6 | return Math.ceil(Math.log((largestDimension + 1) / (256 + 1)) / Math.log(2));
7 | };
8 |
9 | const incorporateZoom = (imageDimension, zoomDifference) => imageDimension / (Math.pow(2, zoomDifference));
10 |
11 | const getOtherImageData = (otherImages, lowestMaxZoom) =>
12 | {
13 | return otherImages.map( (itm) =>
14 | {
15 | const w = itm.width;
16 | const h = itm.height;
17 | const info = parseImageInfo(itm);
18 | const url = info.url.slice(-1) !== '/' ? info.url + '/' : info.url; // append trailing slash to url if it's not there.
19 |
20 | const dims = new Array(lowestMaxZoom + 1);
21 | for (let j = 0; j < lowestMaxZoom + 1; j++)
22 | {
23 | dims[j] = {
24 | h: Math.floor(incorporateZoom(h, lowestMaxZoom - j)),
25 | w: Math.floor(incorporateZoom(w, lowestMaxZoom - j))
26 | };
27 | }
28 |
29 | return {
30 | f: info.url,
31 | url: url,
32 | il: itm.label || "",
33 | d: dims
34 | };
35 | });
36 | };
37 |
38 | /**
39 | * Check if manifest is IIIFv3, then send to appropriate parser. IIIFv3 manifests MUST have
40 | * the 'items' property, whereas v2 will not.
41 | */
42 | export default function parseVersionManifest (manifest)
43 | {
44 | if (manifest.items)
45 | {
46 | console.log('IIIF v3 Manifest, work in progress');
47 | return parseIIIF3Manifest(manifest);
48 | }
49 | else
50 | {
51 | console.log('IIIF v2 (or lower) Manifest');
52 | return parseIIIFManifest(manifest);
53 | }
54 | }
55 |
56 | function parseIIIF3Manifest (manifest)
57 | {
58 | var canvases = manifest.items,
59 | numCanvases = canvases.length;
60 |
61 | for (var i = 0; i < numCanvases; i++)
62 | {
63 | let canvas = canvases[i];
64 | let canvasDims = {
65 | width: canvas.width,
66 | height: canvas.height
67 | };
68 |
69 | let annotationPages = canvas.items,
70 | numAnnotationPages = annotationPages.length;
71 |
72 | for (var j = 0; j < numAnnotationPages; j++)
73 | {
74 | let annotations = annotationPages[j].items,
75 | numAnnotations = annotations.length;
76 |
77 | // iterate over all annotations (media items)
78 | for (var k = 0; k < numAnnotations; k++)
79 | {
80 | let annotation = annotations[k];
81 | let body = annotation.body;
82 |
83 | if (annotation.motivation !== "painting")
84 | continue;
85 |
86 | // if choice choose first
87 | if (body.type === "Choice")
88 | {
89 | annotation.body = body.items[0];
90 | }
91 |
92 | // get the target zones of media onto canvas
93 | let spatialTarget = /xywh=([^&]+)/g.exec(annotation.target);
94 | let temporalTarget = /t=([^&]+)/g.exec(annotation.target);
95 | var xywh;
96 | var t;
97 | if (spatialTarget && spatialTarget[1])
98 | {
99 | xywh = spatialTarget[1].split(',');
100 | }
101 | else
102 | {
103 | xywh = [0, 0, canvas.width, canvas.height];
104 | }
105 | if(temporalTarget && temporalTarget[1])
106 | {
107 | t = temporalTarget[1].split(',');
108 | }
109 | else
110 | {
111 | t = [0, canvas.duration];
112 | }
113 |
114 | let percentageLeft = parseInt(xywh[0]) / canvas.width * 100,
115 | percentageTop = parseInt(xywh[1]) / canvas.height * 100,
116 | percentageWidth = parseInt(xywh[2]) / canvas.width * 100,
117 | percentageHeight = parseInt(xywh[3]) / canvas.height * 100;
118 |
119 | // info of media item for rendering
120 | var info = {
121 | 'type': annotation.body.type,
122 | 'source': annotation.body.id,
123 | 'offsetX': percentageLeft,
124 | 'offsetY': percentageTop,
125 | 'width': percentageWidth,
126 | 'height': percentageHeight,
127 | 'start': parseInt(t[0]),
128 | 'end': parseInt(t[1])
129 | };
130 |
131 | // render media item onto page
132 | let player = new Player();
133 | player.render(info);
134 | }
135 | }
136 |
137 | canvases[i] = {
138 | url: canvas.id,
139 | type: canvas.type,
140 | label: canvas.label || "Label",
141 | dims: canvasDims,
142 | duration: canvas.duration,
143 | annotationPages: annotationPages
144 | };
145 | }
146 |
147 | // parse structures into different timestamps
148 | // assumes depth-2 structure (range then items)
149 | let starts = [];
150 | let ends = [];
151 | let structures = manifest.structures;
152 | if (structures)
153 | {
154 | for (var m = 0; m < structures.length; m++)
155 | {
156 | let range = structures[m];
157 |
158 | for (var n = 0; n < range.items.length; n++)
159 | {
160 |
161 | if (range.items[n].id.includes('#','=',','))
162 | {
163 | // get x from #t=x,y
164 | let time = range.items[n].id.split('#')[1].split('=')[1].split(',');
165 |
166 | starts.push(time[0]);
167 | ends.push(time[1]);
168 | }
169 | }
170 | }
171 | }
172 |
173 | // parse additional rendering file information
174 | var rendering;
175 | let renderings = manifest.rendering;
176 | if (renderings)
177 | {
178 | let numRenderings = renderings.length;
179 |
180 | for (var r = 0; r < numRenderings; r++)
181 | {
182 | rendering = renderings[r];
183 |
184 | if (rendering.id.search(".mei") !== -1)
185 | break;
186 | }
187 | }
188 |
189 | return {
190 | item_title: manifest.label,
191 | url: manifest.id,
192 | canvases: canvases,
193 | structures: structures,
194 | timeStarts: starts,
195 | timeEnds: ends,
196 | rendering: rendering
197 | };
198 | }
199 |
200 | /**
201 | * Parses an IIIF Presentation API Manifest and converts it into a Diva.js-format object
202 | * (See https://github.com/DDMAL/diva.js/wiki/Development-notes#data-received-through-ajax-request)
203 | *
204 | * @param {Object} manifest - an object that represents a valid IIIF manifest
205 | * @returns {Object} divaServiceBlock - the data needed by Diva to show a view of a single document
206 | */
207 | function parseIIIFManifest (manifest)
208 | {
209 | var sequence = manifest.sequences[0];
210 | var canvases = sequence.canvases;
211 | const numCanvases = canvases.length;
212 |
213 | const pages = new Array(canvases.length);
214 |
215 | let thisCanvas, thisResource, thisImage, otherImages, context, url, info, imageAPIVersion, width, height, maxZoom, canvas, label, imageLabel, zoomDimensions, widthAtCurrentZoomLevel, heightAtCurrentZoomLevel;
216 |
217 | let lowestMaxZoom = 100;
218 | let maxRatio = 0;
219 | let minRatio = 100;
220 |
221 | // quickly determine the lowest possible max zoom level (i.e., the upper bound for images) across all canvases.
222 | // while we're here, compute the global ratios as well.
223 | for (let z = 0; z < numCanvases; z++)
224 | {
225 | const c = canvases[z];
226 | const w = c.width;
227 | const h = c.height;
228 | const mz = getMaxZoomLevel(w, h);
229 | const ratio = h / w;
230 | maxRatio = Math.max(ratio, maxRatio);
231 | minRatio = Math.min(ratio, minRatio);
232 |
233 | lowestMaxZoom = Math.min(lowestMaxZoom, mz);
234 | }
235 |
236 | /*
237 | These arrays need to be pre-initialized since we will do arithmetic and value checking on them
238 | */
239 | const totalWidths = new Array(lowestMaxZoom + 1).fill(0);
240 | const totalHeights = new Array(lowestMaxZoom + 1).fill(0);
241 | const maxWidths = new Array(lowestMaxZoom + 1).fill(0);
242 | const maxHeights = new Array(lowestMaxZoom + 1).fill(0);
243 |
244 | for (let i = 0; i < numCanvases; i++)
245 | {
246 | thisCanvas = canvases[i];
247 | canvas = thisCanvas['@id'];
248 | label = thisCanvas.label;
249 | thisResource = thisCanvas.images[0].resource;
250 |
251 | /*
252 | * If a canvas has multiple images it will be encoded
253 | * with a resource type of "oa:Choice". The primary image will be available
254 | * on the 'default' key, with other images available under 'item.'
255 | * */
256 | if (thisResource['@type'] === "oa:Choice")
257 | {
258 | thisImage = thisResource.default;
259 | }
260 | else
261 | {
262 | thisImage = thisResource;
263 | }
264 |
265 | // Prioritize the canvas height / width first, since images may not have h/w
266 | width = thisCanvas.width || thisImage.width;
267 | height = thisCanvas.height || thisImage.height;
268 | if (width <= 0 || height <= 0)
269 | {
270 | console.warn('Invalid width or height for canvas ' + label + '. Skipping');
271 | continue;
272 | }
273 |
274 | maxZoom = getMaxZoomLevel(width, height);
275 |
276 | if (thisResource.item)
277 | {
278 | otherImages = getOtherImageData(thisResource.item, lowestMaxZoom);
279 | }
280 | else
281 | {
282 | otherImages = [];
283 | }
284 |
285 | imageLabel = thisImage.label || null;
286 |
287 | info = parseImageInfo(thisImage);
288 | url = info.url.slice(-1) !== '/' ? info.url + '/' : info.url; // append trailing slash to url if it's not there.
289 |
290 | context = thisImage.service['@context'];
291 | if (context === 'http://iiif.io/api/image/2/context.json')
292 | {
293 | imageAPIVersion = 2;
294 | }
295 | else if (context === 'http://library.stanford.edu/iiif/image-api/1.1/context.json')
296 | {
297 | imageAPIVersion = 1.1;
298 | }
299 | else
300 | {
301 | imageAPIVersion = 1.0;
302 | }
303 |
304 | zoomDimensions = new Array(lowestMaxZoom + 1);
305 |
306 | for (let k = 0; k < lowestMaxZoom + 1; k++)
307 | {
308 | widthAtCurrentZoomLevel = Math.floor(incorporateZoom(width, lowestMaxZoom - k));
309 | heightAtCurrentZoomLevel = Math.floor(incorporateZoom(height, lowestMaxZoom - k));
310 | zoomDimensions[k] = {
311 | h: heightAtCurrentZoomLevel,
312 | w: widthAtCurrentZoomLevel
313 | };
314 |
315 | totalWidths[k] += widthAtCurrentZoomLevel;
316 | totalHeights[k] += heightAtCurrentZoomLevel;
317 | maxWidths[k] = Math.max(widthAtCurrentZoomLevel, maxWidths[k]);
318 | maxHeights[k] = Math.max(heightAtCurrentZoomLevel, maxHeights[k]);
319 | }
320 |
321 | pages[i] = {
322 | d: zoomDimensions,
323 | m: maxZoom,
324 | l: label, // canvas label ('page 1, page 2', etc.)
325 | il: imageLabel, // default image label ('primary image', 'UV light', etc.)
326 | f: info.url,
327 | url: url,
328 | api: imageAPIVersion,
329 | paged: thisCanvas.viewingHint !== 'non-paged',
330 | facingPages: thisCanvas.viewingHint === 'facing-pages',
331 | canvas: canvas,
332 | otherImages: otherImages,
333 | xoffset: info.x || null,
334 | yoffset: info.y || null
335 | };
336 | }
337 |
338 | const averageWidths = new Array(lowestMaxZoom + 1);
339 | const averageHeights = new Array(lowestMaxZoom + 1);
340 |
341 | for (let a = 0; a < lowestMaxZoom + 1; a++)
342 | {
343 | averageWidths[a] = totalWidths[a] / numCanvases;
344 | averageHeights[a] = totalHeights[a] / numCanvases;
345 | }
346 |
347 | const dims = {
348 | a_wid: averageWidths,
349 | a_hei: averageHeights,
350 | max_w: maxWidths,
351 | max_h: maxHeights,
352 | max_ratio: maxRatio,
353 | min_ratio: minRatio,
354 | t_hei: totalHeights,
355 | t_wid: totalWidths
356 | };
357 |
358 | return {
359 | item_title: manifest.label,
360 | dims: dims,
361 | max_zoom: lowestMaxZoom,
362 | pgs: pages,
363 | paged: manifest.viewingHint === 'paged' || sequence.viewingHint === 'paged'
364 | };
365 | }
366 |
367 | /**
368 | * Takes in a resource block from a canvas and outputs the following information associated with that resource:
369 | * - Image URL
370 | * - Image region to be displayed
371 | *
372 | * @param {Object} resource - an object representing the resource block of a canvas section in a IIIF manifest
373 | * @returns {Object} imageInfo - an object containing image URL and region
374 | */
375 | function parseImageInfo (resource)
376 | {
377 | let url = resource['@id'] || resource.id;
378 | const fragmentRegex = /#xywh=([0-9]+,[0-9]+,[0-9]+,[0-9]+)/;
379 | let xywh = '';
380 | let stripURL = true;
381 |
382 | if (/\/([0-9]+,[0-9]+,[0-9]+,[0-9]+)\//.test(url))
383 | {
384 | // if resource in image API format, extract region x,y,w,h from URL (after 4th slash from last)
385 | // matches coordinates in URLs of the form http://www.example.org/iiif/book1-page1/40,50,1200,1800/full/0/default.jpg
386 | const urlArray = url.split('/');
387 | xywh = urlArray[urlArray.length - 4];
388 | }
389 | else if (fragmentRegex.test(url))
390 | {
391 | // matches coordinates of the style http://www.example.org/iiif/book1/canvas/p1#xywh=50,50,320,240
392 | const result = fragmentRegex.exec(url);
393 | xywh = result[1];
394 | }
395 | else if (resource.service && resource.service['@id'])
396 | {
397 | // assume canvas size based on image size
398 | url = resource.service['@id'];
399 | // this URL excludes region parameters so we don't need to remove them
400 | stripURL = false;
401 | }
402 |
403 | if (stripURL)
404 | {
405 | // extract URL up to identifier (we eliminate the last 5 parameters: /region/size/rotation/quality.format)
406 | url = url.split('/').slice(0, -4).join('/');
407 | }
408 |
409 | const imageInfo = {
410 | url: url
411 | };
412 |
413 | if (xywh.length)
414 | {
415 | // parse into separate components
416 | const dimensions = xywh.split(',');
417 | imageInfo.x = parseInt(dimensions[0], 10);
418 | imageInfo.y = parseInt(dimensions[1], 10);
419 | imageInfo.w = parseInt(dimensions[2], 10);
420 | imageInfo.h = parseInt(dimensions[3], 10);
421 | }
422 |
423 | return imageInfo;
424 | }
425 |
--------------------------------------------------------------------------------
/src/player.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | export class Player
4 | {
5 | constructor ()
6 | {
7 | this.mediaElement;
8 | }
9 |
10 | render (info)
11 | {
12 | if ($('.playerContainer').length) // if media already exists on page
13 | {
14 | $('.playerContainer').remove();
15 | }
16 | let container = $('
');
17 | container.css({
18 | width: '100%'
19 | });
20 | $('.player').append(container);
21 | switch(info.type)
22 | {
23 | case 'Image':
24 | this.mediaElement = $(' ');
25 | break;
26 | case 'Video':
27 | this.mediaElement = $(' ');
28 | break;
29 | case 'Audio':
30 | this.mediaElement = $(' ');
31 | break;
32 | default:
33 | return null;
34 | }
35 | this.mediaElement.css({
36 | width: '100%', // temporary - should be based on media dimensions eventually
37 | height: '100%'
38 | });
39 | $('.playerContainer').append(this.mediaElement);
40 | }
41 | }
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DDMAL/IIIF-AV-player/dbb539e810ac9f50b56b47f0325b0bec589823e0/static/favicon.ico
--------------------------------------------------------------------------------
/static/main.js:
--------------------------------------------------------------------------------
1 | // Manifest fetching and callback actions
2 | var manifestObject;
3 | $('#getURL').click(function ()
4 | {
5 | let url = $('#urlBox').val();
6 |
7 | manifestObject = new ManifestObject(url); // jshint ignore:line
8 | manifestObject.fetchManifest(function ()
9 | {
10 | // callback once manifest is fetched
11 | // set title
12 | let title = manifestObject.manifest.item_title;
13 | if (typeof title !== 'string')
14 | title = title.en[0];
15 | $('#title').html(title);
16 |
17 | renderVerovio();
18 |
19 | $("#player_controls").show();
20 | });
21 | });
22 |
23 |
24 | function loadPreset (url) // jshint ignore:line
25 | {
26 | $('#urlBox').val(url);
27 | $('#getURL').click();
28 | }
29 |
30 | // Verovio score rendering and score manipulation
31 | var toolkit = new verovio.toolkit(); // jshint ignore:line
32 | var page = 0;
33 | async function renderVerovio () // jshint ignore:line
34 | {
35 | let scoreFile = "static/mei/demo.mei";
36 |
37 | if (manifestObject.manifest.rendering)
38 | {
39 | scoreFile = manifestObject.manifest.rendering.id;
40 | }
41 |
42 | await $.ajax({ // jshint ignore:line
43 | url: scoreFile,
44 | dataType: "text",
45 | success: function (data)
46 | {
47 | $('.score').empty(); // clear previous verovio renderings
48 | toolkit.loadData(data, {});
49 | for (var i = 1; i <= toolkit.getPageCount(); i++) // verovio pages are 1-indexed
50 | {
51 | let svg = toolkit.renderToSVG(i, {});
52 | $('.score').append(svg);
53 | $('.score').children().last().find('.measure').attr('class', 'measure page'+i);
54 | $('.score').children().hide();
55 | }
56 | $('.score').children().first().show(); // show first page
57 | $('svg').width("100%");
58 | $('svg').height("100%");
59 | }
60 | });
61 | linkScore();
62 | }
63 | function pagePrev () // jshint ignore:line
64 | {
65 | if (page === 0)
66 | return;
67 | $('.score').children().eq(page).hide();
68 | page--;
69 | $('.score').children().eq(page).show();
70 | }
71 | function pageNext () // jshint ignore:line
72 | {
73 | if (page === toolkit.getPageCount()-1)
74 | return;
75 | $('.score').children().eq(page).hide();
76 | page++;
77 | $('.score').children().eq(page).show();
78 | }
79 | function goToPage (n)
80 | {
81 | if (n < 0 || n >= toolkit.getPageCount())
82 | return;
83 | $('.score').children().eq(page).hide();
84 | page = n;
85 | $('.score').children().eq(page).show();
86 | }
87 |
88 |
89 | // score and player syncing
90 | var loopMeasureStart = null;
91 | var loopMeasureEnd = null;
92 | function linkScore ()
93 | {
94 | let count = 0;
95 | let max = manifestObject.manifest.timeStarts.length;
96 | // assign a start and end time to every measure
97 | $('.measure').each(function ()
98 | {
99 | let timeStart = parseFloat(manifestObject.manifest.timeStarts[count]);
100 | let timeEnd = parseFloat(manifestObject.manifest.timeEnds[count]);
101 | if (count >= max)
102 | timeStart = timeEnd = 0;
103 | $(this).attr('timeStart', timeStart);
104 | $(this).attr('timeStop', timeEnd);
105 | count++;
106 | });
107 | // fill red and goto time in video
108 | var clickMeasureInitial = null;
109 | var clickMeasureFinal = null;
110 | $('.measure').click(function (event)
111 | {
112 | clearMeasures();
113 | fillMeasure(this);
114 |
115 | // user selecting multiple measure for looping
116 | if (event.shiftKey)
117 | {
118 | // second click in selection
119 | if (clickMeasureInitial !== null && $('video')[0].paused)
120 | {
121 | clickMeasureFinal = this;
122 |
123 | let measureInitialTime = truncateNum($(clickMeasureInitial).attr('timeStart'), 3);
124 | let measureFinalTime = truncateNum($(clickMeasureFinal).attr('timeStart'), 3);
125 |
126 | // find if second click is before or after initial click in the score
127 | if (measureInitialTime <= measureFinalTime)
128 | {
129 |
130 | loopMeasureStart = clickMeasureInitial;
131 | loopMeasureEnd = clickMeasureFinal;
132 | $('video')[0].currentTime = measureInitialTime;
133 | }
134 | else
135 | {
136 | loopMeasureStart = clickMeasureFinal;
137 | loopMeasureEnd = clickMeasureInitial;
138 | $('video')[0].currentTime = measureFinalTime;
139 | }
140 |
141 | fillMeasureRange(loopMeasureStart, loopMeasureEnd);
142 | }
143 | }
144 | else // regular left-click
145 | {
146 | if ($('video')[0].paused)
147 | {
148 | clickMeasureInitial = this;
149 | }
150 |
151 | loopMeasureStart = null;
152 | loopMeasureEnd = null;
153 |
154 | $('video')[0].currentTime = $(this).attr('timeStart');
155 | }
156 | });
157 | }
158 | // track video progress and move score highlight
159 | var animationID;
160 | function trackVideo ()
161 | {
162 | let time = $('video')[0].currentTime;
163 |
164 | // looping is enabled
165 | if (loopMeasureStart !== null && loopMeasureEnd !== null)
166 | {
167 | // loop back
168 | if (time >= $(loopMeasureEnd).attr('timeStop'))
169 | {
170 | $('video')[0].currentTime = $(loopMeasureStart).attr('timeStart');
171 | time = $(loopMeasureStart).attr('timeStart');
172 | }
173 |
174 | fillMeasureRange(loopMeasureStart, loopMeasureEnd);
175 | }
176 | else
177 | {
178 | clearMeasures();
179 | }
180 |
181 | $('.measure').each(function () {
182 | let lower = truncateNum($(this).attr('timeStart'), 3);
183 | let upper = truncateNum($(this).attr('timeStop'), 3);
184 | if (time >= lower && time < upper && time !== 0)
185 | {
186 | fillMeasure(this);
187 | }
188 | else if (time === 0)
189 | $('.measure').removeAttr('fill');
190 | });
191 |
192 | if (!$('video')[0].paused)
193 | animationID = requestAnimationFrame(trackVideo);
194 | }
195 | function fillMeasure (measure)
196 | {
197 | $(measure).attr('fill', '#dd0000');
198 | goToPage($(measure).attr('class').split(' ')[1].slice(-1) - 1);
199 | }
200 | function fillMeasureRange(measureStart, measureEnd)
201 | {
202 | let loopStartTime = $(measureStart).attr('timeStart');
203 | let loopEndTime = $(measureEnd).attr('timeStart');
204 |
205 | $('.measure').each(function ()
206 | {
207 | let measureTime = truncateNum($(this).attr('timeStart'), 3);
208 |
209 | if (measureTime >= loopStartTime && measureTime <= loopEndTime )
210 | {
211 | $(this).attr('fill', '#000080');
212 | }
213 | });
214 |
215 | }
216 | function clearMeasures ()
217 | {
218 | $('.measure').removeAttr('fill');
219 | }
220 |
221 |
222 | // video and score control
223 | function playButtonPress () // jshint ignore:line
224 | {
225 | if ($('video')[0].paused)
226 | {
227 | $('video')[0].play();
228 | $('#button_play i').attr('class', "fa fa-pause");
229 |
230 | trackVideo();
231 | }
232 | else
233 | {
234 | $('video')[0].pause();
235 | $('#button_play i').attr('class', "fa fa-play");
236 |
237 | cancelAnimationFrame(animationID);
238 | }
239 | }
240 | function stopButtonPress () // jshint ignore:line
241 | {
242 | $('#button_play i').attr('class', "fa fa-play");
243 |
244 | $('video')[0].pause();
245 | $('video')[0].currentTime = 0;
246 |
247 | $('.measure').removeAttr('fill');
248 |
249 | loopMeasureStart = null;
250 | loopMeasureEnd = null;
251 |
252 | cancelAnimationFrame(animationID);
253 | }
254 | function backButtonPress () // jshint ignore:line
255 | {
256 | let measureFound = false;
257 | let time = truncateNum($('video')[0].currentTime, 3);
258 |
259 | let measureTimeMin = 0;
260 | // looping is enabled
261 | if (loopMeasureStart !== null && loopMeasureEnd !== null)
262 | measureTimeMin = $(loopMeasureStart).attr('timeStart');
263 |
264 | // iterate backwards until current measure and get next one back
265 | $($('.measure').get().reverse()).each(function () {
266 | let measureTime = truncateNum($(this).attr('timeStart'), 3);
267 |
268 | if (measureTime <= time && measureTime >= measureTimeMin) {
269 | if (measureFound) {
270 | $('video')[0].currentTime = $(this).attr('timeStart');
271 | return false;
272 | }
273 | measureFound = true;
274 | }
275 | });
276 |
277 | trackVideo();
278 | }
279 | function forwardButtonPress () // jshint ignore:line
280 | {
281 | let time = truncateNum($('video')[0].currentTime, 3);
282 |
283 | let measureTimeMax = $('.measure').last().attr('timeStart');
284 | // looping is enabled
285 | if (loopMeasureStart !== null && loopMeasureEnd !== null)
286 | measureTimeMax = $(loopMeasureEnd).attr('timeStart');
287 |
288 | // iterate forward until next measure from current
289 | $('.measure').each(function ()
290 | {
291 | let measureTime = truncateNum($(this).attr('timeStart'), 3);
292 |
293 | if (measureTime > time && measureTime <= measureTimeMax)
294 | {
295 | $('video')[0].currentTime = $(this).attr('timeStart');
296 | return false;
297 | }
298 | });
299 |
300 | trackVideo();
301 | }
302 |
303 | function truncateNum(num, fixed)
304 | {
305 | var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
306 | return Number(num.toString().match(re)[0]);
307 | }
308 |
--------------------------------------------------------------------------------
/static/manifests/manifest_chopin_etude_aud.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context":[
3 | "http://www.w3.org/ns/anno.jsonld",
4 | "http://iiif.io/api/presentation/3/context.json"
5 | ],
6 | "type":"Manifest",
7 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/lunchroom_manners.v6",
8 | "label":{
9 | "en":[
10 | "Etude in F Minor"
11 | ]
12 | },
13 | "metadata":[
14 | {
15 | "label":{
16 | "en":[
17 | "Title"
18 | ]
19 | },
20 | "value":{
21 | "en":[
22 | "Lunchroom Manners"
23 | ]
24 | }
25 | },
26 | {
27 | "label":{
28 | "en":[
29 | "Creator"
30 | ]
31 | },
32 | "value":{
33 | "en":[
34 | "IIIF Demo User"
35 | ]
36 | }
37 | },
38 | {
39 | "label":{
40 | "en":[
41 | "Keyword"
42 | ]
43 | },
44 | "value":{
45 | "en":[
46 | "IIIF",
47 | "lunchroom",
48 | "demo"
49 | ]
50 | }
51 | },
52 | {
53 | "label":{
54 | "en":[
55 | "Rights statement"
56 | ]
57 | },
58 | "value":{
59 | "en":[
60 | "http://rightsstatements.org/vocab/UND.0/"
61 | ]
62 | }
63 | }
64 | ],
65 | "items":[
66 | {
67 | "type":"Canvas",
68 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1",
69 | "label":{
70 | "en":[
71 | "lunchroom_manners"
72 | ]
73 | },
74 | "thumbnail":[
75 | {
76 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/thumbnail/lunchroom_manners_poster.jpg",
77 | "type":"Image"
78 | }
79 | ],
80 | "items":[
81 | {
82 | "type":"AnnotationPage",
83 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1/annotation_page1",
84 | "items":[
85 | {
86 | "type":"Annotation",
87 | "motivation":"painting",
88 | "target":"http://dlib.indiana.edu/iiif_av/canvas/1",
89 | "body":{
90 | "type":"Choice",
91 | "choiceHint":"user",
92 | "items":[
93 | {
94 | "id":"static/media/chopin_etude.mp3",
95 | "type":"Video",
96 | "format":"audio/mp3",
97 | "label":"mp3"
98 | }
99 | ]
100 | }
101 | }
102 | ]
103 | }
104 | ],
105 | "duration":null
106 | }
107 | ],
108 | "structures":[
109 | {
110 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/1",
111 | "type":"Range",
112 | "label":{
113 | "en":[
114 | "Movement I"
115 | ]
116 | },
117 | "items":[
118 | {
119 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=3.120,5.204",
120 | "type":"Canvas"
121 | },
122 | {
123 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=5.204,6.669",
124 | "type":"Canvas"
125 | },
126 | {
127 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=6.669,7.692",
128 | "type":"Canvas"
129 | }
130 | ]
131 | },
132 | {
133 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/2",
134 | "type":"Range",
135 | "label":{
136 | "en":[
137 | "Movement II"
138 | ]
139 | },
140 | "items":[
141 | {
142 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=7.692,9.315",
143 | "type":"Canvas"
144 | },
145 | {
146 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=9.315,11.106",
147 | "type":"Canvas"
148 | },
149 | {
150 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=11.106,12.311",
151 | "type":"Canvas"
152 | },
153 | {
154 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=12.311,13.749",
155 | "type":"Canvas"
156 | },
157 | {
158 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=13.749,15.465",
159 | "type":"Canvas"
160 | },
161 | {
162 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=15.465,17.538",
163 | "type":"Canvas"
164 | },
165 | {
166 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=17.538,18.930",
167 | "type":"Canvas"
168 | },
169 | {
170 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=18.930,20.113",
171 | "type":"Canvas"
172 | },
173 | {
174 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=20.113,21.834",
175 | "type":"Canvas"
176 | },
177 | {
178 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=21.834,23.715",
179 | "type":"Canvas"
180 | },
181 | {
182 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=23.715,24.952",
183 | "type":"Canvas"
184 | },
185 | {
186 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=24.952,26.549",
187 | "type":"Canvas"
188 | },
189 | {
190 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=26.549,28.302",
191 | "type":"Canvas"
192 | },
193 | {
194 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=28.302,30.656",
195 | "type":"Canvas"
196 | },
197 | {
198 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=30.656,32.598",
199 | "type":"Canvas"
200 | },
201 | {
202 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=32.598,34.294",
203 | "type":"Canvas"
204 | },
205 | {
206 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=34.294,36.253",
207 | "type":"Canvas"
208 | },
209 | {
210 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=36.253,38.868",
211 | "type":"Canvas"
212 | },
213 | {
214 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=38.868,40.531",
215 | "type":"Canvas"
216 | },
217 | {
218 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=40.531,41.977",
219 | "type":"Canvas"
220 | },
221 | {
222 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=41.977,43.345",
223 | "type":"Canvas"
224 | },
225 | {
226 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=43.345,45.129",
227 | "type":"Canvas"
228 | },
229 | {
230 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=45.129,46.495",
231 | "type":"Canvas"
232 | },
233 | {
234 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=46.495,47.995",
235 | "type":"Canvas"
236 | },
237 | {
238 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=47.995,49.884",
239 | "type":"Canvas"
240 | }
241 | ]
242 | },
243 | {
244 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/3",
245 | "type":"Range",
246 | "label":{
247 | "en":[
248 | "Movement III"
249 | ]
250 | },
251 | "items":[
252 | {
253 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=49.884,52.154",
254 | "type":"Canvas"
255 | },
256 | {
257 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=52.154,53.971",
258 | "type":"Canvas"
259 | },
260 | {
261 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=53.971,55.781",
262 | "type":"Canvas"
263 | },
264 | {
265 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=55.781,58.066",
266 | "type":"Canvas"
267 | },
268 | {
269 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=58.066,60.727",
270 | "type":"Canvas"
271 | },
272 | {
273 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=60.727,62.986",
274 | "type":"Canvas"
275 | },
276 | {
277 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=62.986,65.080",
278 | "type":"Canvas"
279 | },
280 | {
281 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=65.080,68.137",
282 | "type":"Canvas"
283 | },
284 | {
285 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=68.137,70.512",
286 | "type":"Canvas"
287 | },
288 | {
289 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=70.512,71.795",
290 | "type":"Canvas"
291 | },
292 | {
293 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=71.795,73.189",
294 | "type":"Canvas"
295 | },
296 | {
297 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=73.189,75.087",
298 | "type":"Canvas"
299 | },
300 | {
301 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=75.087,76.868",
302 | "type":"Canvas"
303 | },
304 | {
305 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=76.868,78.211",
306 | "type":"Canvas"
307 | },
308 | {
309 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=78.211,79.523",
310 | "type":"Canvas"
311 | },
312 | {
313 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=79.523,81.290",
314 | "type":"Canvas"
315 | },
316 | {
317 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=81.290,83.080",
318 | "type":"Canvas"
319 | },
320 | {
321 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=83.080,84.251",
322 | "type":"Canvas"
323 | },
324 | {
325 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=84.251,85.647",
326 | "type":"Canvas"
327 | },
328 | {
329 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=85.647,87.539",
330 | "type":"Canvas"
331 | },
332 | {
333 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=87.539,89.652",
334 | "type":"Canvas"
335 | },
336 | {
337 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=89.652,91.471",
338 | "type":"Canvas"
339 | },
340 | {
341 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=91.471,93.124",
342 | "type":"Canvas"
343 | },
344 | {
345 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=93.124,94.963",
346 | "type":"Canvas"
347 | },
348 | {
349 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=94.963,96.693",
350 | "type":"Canvas"
351 | },
352 | {
353 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=96.693,98.037",
354 | "type":"Canvas"
355 | },
356 | {
357 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=98.037,99.437",
358 | "type":"Canvas"
359 | },
360 | {
361 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=99.437,101.742",
362 | "type":"Canvas"
363 | },
364 | {
365 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=101.742,104.471",
366 | "type":"Canvas"
367 | },
368 | {
369 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=104.471,106.943",
370 | "type":"Canvas"
371 | },
372 | {
373 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=106.943,109.175",
374 | "type":"Canvas"
375 | },
376 | {
377 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=109.175,111.359",
378 | "type":"Canvas"
379 | },
380 | {
381 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=111.359,114.237",
382 | "type":"Canvas"
383 | },
384 | {
385 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=114.237,117.091",
386 | "type":"Canvas"
387 | },
388 | {
389 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=117.091,120.134",
390 | "type":"Canvas"
391 | },
392 | {
393 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=120.134,122.721",
394 | "type":"Canvas"
395 | },
396 | {
397 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=122.721,124.951",
398 | "type":"Canvas"
399 | },
400 | {
401 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=124.951,127.531",
402 | "type":"Canvas"
403 | },
404 | {
405 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=127.531,134.000",
406 | "type":"Canvas"
407 | }
408 | ]
409 | }
410 | ],
411 | "rendering":[
412 | {
413 | "id":"static/mei/demo.mei",
414 | "type":"Text",
415 | "label":{"en":["Score"]},
416 | "format":"application/xml"
417 | }
418 | ]
419 | }
--------------------------------------------------------------------------------
/static/manifests/manifest_chopin_etude_vid.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context":[
3 | "http://www.w3.org/ns/anno.jsonld",
4 | "http://iiif.io/api/presentation/3/context.json"
5 | ],
6 | "type":"Manifest",
7 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/lunchroom_manners.v6",
8 | "label":{
9 | "en":[
10 | "Etude in F Minor"
11 | ]
12 | },
13 | "metadata":[
14 | {
15 | "label":{
16 | "en":[
17 | "Title"
18 | ]
19 | },
20 | "value":{
21 | "en":[
22 | "Lunchroom Manners"
23 | ]
24 | }
25 | },
26 | {
27 | "label":{
28 | "en":[
29 | "Creator"
30 | ]
31 | },
32 | "value":{
33 | "en":[
34 | "IIIF Demo User"
35 | ]
36 | }
37 | },
38 | {
39 | "label":{
40 | "en":[
41 | "Keyword"
42 | ]
43 | },
44 | "value":{
45 | "en":[
46 | "IIIF",
47 | "lunchroom",
48 | "demo"
49 | ]
50 | }
51 | },
52 | {
53 | "label":{
54 | "en":[
55 | "Rights statement"
56 | ]
57 | },
58 | "value":{
59 | "en":[
60 | "http://rightsstatements.org/vocab/UND.0/"
61 | ]
62 | }
63 | }
64 | ],
65 | "items":[
66 | {
67 | "type":"Canvas",
68 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1",
69 | "label":{
70 | "en":[
71 | "lunchroom_manners"
72 | ]
73 | },
74 | "thumbnail":[
75 | {
76 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/thumbnail/lunchroom_manners_poster.jpg",
77 | "type":"Image"
78 | }
79 | ],
80 | "items":[
81 | {
82 | "type":"AnnotationPage",
83 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1/annotation_page1",
84 | "items":[
85 | {
86 | "type":"Annotation",
87 | "motivation":"painting",
88 | "target":"http://dlib.indiana.edu/iiif_av/canvas/1",
89 | "body":{
90 | "type":"Choice",
91 | "choiceHint":"user",
92 | "items":[
93 | {
94 | "id":"static/media/Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.mp4",
95 | "type":"Video",
96 | "height":360,
97 | "width":480,
98 | "duration":115.000
99 | }
100 | ]
101 | }
102 | }
103 | ]
104 | }
105 | ],
106 | "height":360,
107 | "width":480,
108 | "duration":115.000
109 | }
110 | ],
111 | "structures":[
112 | {
113 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/1",
114 | "type":"Range",
115 | "label":{
116 | "en":[
117 | "Movement I"
118 | ]
119 | },
120 | "items":[
121 | {
122 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=0.000,1.684",
123 | "type":"Canvas"
124 | },
125 | {
126 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=1.684,2.982",
127 | "type":"Canvas"
128 | },
129 | {
130 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=2.982,4.253",
131 | "type":"Canvas"
132 | }
133 | ]
134 | },
135 | {
136 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/2",
137 | "type":"Range",
138 | "label":{
139 | "en":[
140 | "Movement II"
141 | ]
142 | },
143 | "items":[
144 | {
145 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=4.253,5.649",
146 | "type":"Canvas"
147 | },
148 | {
149 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=5.649,7.166",
150 | "type":"Canvas"
151 | },
152 | {
153 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=7.166,8.548",
154 | "type":"Canvas"
155 | },
156 | {
157 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=8.548,9.877",
158 | "type":"Canvas"
159 | },
160 | {
161 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=9.877,11.919",
162 | "type":"Canvas"
163 | },
164 | {
165 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=11.919,13.689",
166 | "type":"Canvas"
167 | },
168 | {
169 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=13.689,14.976",
170 | "type":"Canvas"
171 | },
172 | {
173 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=14.976,16.365",
174 | "type":"Canvas"
175 | },
176 | {
177 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=16.365,17.684",
178 | "type":"Canvas"
179 | },
180 | {
181 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=17.684,19.257",
182 | "type":"Canvas"
183 | },
184 | {
185 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=19.257,20.880",
186 | "type":"Canvas"
187 | },
188 | {
189 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=20.880,22.405",
190 | "type":"Canvas"
191 | },
192 | {
193 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=22.405,24.218",
194 | "type":"Canvas"
195 | },
196 | {
197 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=24.218,25.942",
198 | "type":"Canvas"
199 | },
200 | {
201 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=25.942,27.147",
202 | "type":"Canvas"
203 | },
204 | {
205 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=27.147,28.688",
206 | "type":"Canvas"
207 | },
208 | {
209 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=28.688,30.536",
210 | "type":"Canvas"
211 | },
212 | {
213 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=30.536,32.072",
214 | "type":"Canvas"
215 | },
216 | {
217 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=32.072,33.883",
218 | "type":"Canvas"
219 | },
220 | {
221 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=33.883,35.507",
222 | "type":"Canvas"
223 | },
224 | {
225 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=35.507,37.721",
226 | "type":"Canvas"
227 | },
228 | {
229 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=37.721,39.998",
230 | "type":"Canvas"
231 | },
232 | {
233 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=39.998,41.344",
234 | "type":"Canvas"
235 | },
236 | {
237 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=41.344,42.727",
238 | "type":"Canvas"
239 | },
240 | {
241 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=42.727,44.546",
242 | "type":"Canvas"
243 | },
244 | {
245 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=44.546,46.884",
246 | "type":"Canvas"
247 | },
248 | {
249 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=46.884,48.409",
250 | "type":"Canvas"
251 | },
252 | {
253 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=48.409,50.191",
254 | "type":"Canvas"
255 | },
256 | {
257 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=50.191,51.850",
258 | "type":"Canvas"
259 | },
260 | {
261 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=51.850,53.834",
262 | "type":"Canvas"
263 | },
264 | {
265 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=53.834,55.561",
266 | "type":"Canvas"
267 | },
268 | {
269 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=55.561,57.626",
270 | "type":"Canvas"
271 | },
272 | {
273 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=57.626,60.464",
274 | "type":"Canvas"
275 | },
276 | {
277 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=60.464,61.834",
278 | "type":"Canvas"
279 | },
280 | {
281 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=61.834,63.184",
282 | "type":"Canvas"
283 | },
284 | {
285 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=63.184,64.759",
286 | "type":"Canvas"
287 | },
288 | {
289 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=64.759,66.036",
290 | "type":"Canvas"
291 | },
292 | {
293 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=66.036,67.282",
294 | "type":"Canvas"
295 | },
296 | {
297 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=67.282,69.064",
298 | "type":"Canvas"
299 | },
300 | {
301 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=69.064,70.314",
302 | "type":"Canvas"
303 | },
304 | {
305 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=70.314,72.253",
306 | "type":"Canvas"
307 | },
308 | {
309 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=72.253,73.874",
310 | "type":"Canvas"
311 | },
312 | {
313 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=73.874,75.650",
314 | "type":"Canvas"
315 | },
316 | {
317 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=75.650,76.861",
318 | "type":"Canvas"
319 | },
320 | {
321 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=76.861,78.381",
322 | "type":"Canvas"
323 | },
324 | {
325 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=78.381,79.809",
326 | "type":"Canvas"
327 | }
328 | ]
329 | },
330 | {
331 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/3",
332 | "type":"Range",
333 | "label":{
334 | "en":[
335 | "Movement III"
336 | ]
337 | },
338 | "items":[
339 | {
340 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=79.809,81.265",
341 | "type":"Canvas"
342 | },
343 | {
344 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=81.265,82.602",
345 | "type":"Canvas"
346 | },
347 | {
348 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=82.602,84.085",
349 | "type":"Canvas"
350 | },
351 | {
352 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=84.085,86.526",
353 | "type":"Canvas"
354 | },
355 | {
356 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=86.526,87.744",
357 | "type":"Canvas"
358 | },
359 | {
360 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=87.744,88.970",
361 | "type":"Canvas"
362 | },
363 | {
364 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=88.970,91.341",
365 | "type":"Canvas"
366 | },
367 | {
368 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=91.341,93.850",
369 | "type":"Canvas"
370 | },
371 | {
372 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=93.850,95.694",
373 | "type":"Canvas"
374 | },
375 | {
376 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=95.694,97.391",
377 | "type":"Canvas"
378 | },
379 | {
380 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=97.391,99.427",
381 | "type":"Canvas"
382 | },
383 | {
384 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=99.427,101.938",
385 | "type":"Canvas"
386 | },
387 | {
388 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=101.938,104.563",
389 | "type":"Canvas"
390 | },
391 | {
392 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=104.563,106.846",
393 | "type":"Canvas"
394 | },
395 | {
396 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=106.846,110.262",
397 | "type":"Canvas"
398 | },
399 | {
400 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=110.262,111.759",
401 | "type":"Canvas"
402 | },
403 | {
404 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=111.759,113.667",
405 | "type":"Canvas"
406 | },
407 | {
408 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=113.667,115.000",
409 | "type":"Canvas"
410 | }
411 | ]
412 | }
413 | ],
414 | "rendering":[
415 | {
416 | "id":"static/mei/demo.mei",
417 | "type":"Text",
418 | "label":{"en":["Score"]},
419 | "format":"application/xml"
420 | }
421 | ]
422 | }
--------------------------------------------------------------------------------
/static/manifests/manifest_lunchroom_manners.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context":[
3 | "http://www.w3.org/ns/anno.jsonld",
4 | "http://iiif.io/api/presentation/3/context.json"
5 | ],
6 | "type":"Manifest",
7 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/lunchroom_manners.v6",
8 | "label":{
9 | "en":[
10 | "Lunchroom Manners"
11 | ]
12 | },
13 | "metadata":[
14 | {
15 | "label":{
16 | "en":[
17 | "Title"
18 | ]
19 | },
20 | "value":{
21 | "en":[
22 | "Lunchroom Manners"
23 | ]
24 | }
25 | },
26 | {
27 | "label":{
28 | "en":[
29 | "Creator"
30 | ]
31 | },
32 | "value":{
33 | "en":[
34 | "IIIF Demo User"
35 | ]
36 | }
37 | },
38 | {
39 | "label":{
40 | "en":[
41 | "Keyword"
42 | ]
43 | },
44 | "value":{
45 | "en":[
46 | "IIIF",
47 | "lunchroom",
48 | "demo"
49 | ]
50 | }
51 | },
52 | {
53 | "label":{
54 | "en":[
55 | "Rights statement"
56 | ]
57 | },
58 | "value":{
59 | "en":[
60 | "http://rightsstatements.org/vocab/UND.0/"
61 | ]
62 | }
63 | }
64 | ],
65 | "items":[
66 | {
67 | "type":"Canvas",
68 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1",
69 | "label":{
70 | "en":[
71 | "lunchroom_manners"
72 | ]
73 | },
74 | "thumbnail":[
75 | {
76 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/thumbnail/lunchroom_manners_poster.jpg",
77 | "type":"Image"
78 | }
79 | ],
80 | "items":[
81 | {
82 | "type":"AnnotationPage",
83 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1/annotation_page1",
84 | "items":[
85 | {
86 | "type":"Annotation",
87 | "motivation":"painting",
88 | "target":"http://dlib.indiana.edu/iiif_av/canvas/1",
89 | "body":{
90 | "type":"Choice",
91 | "choiceHint":"user",
92 | "items":[
93 | {
94 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/mp4/lunchroom_manners.mp4",
95 | "type":"Video",
96 | "height":360,
97 | "width":480,
98 | "duration":572.034
99 | },
100 | {
101 | "id":"http://dlib.indiana.edu/iiif_av/lunchroom_manners/webm/lunchroom_manners.webm",
102 | "type":"Video",
103 | "height":360,
104 | "width":480,
105 | "duration":572.034
106 | }
107 | ]
108 | }
109 | }
110 | ]
111 | }
112 | ],
113 | "width":480,
114 | "height":360,
115 | "duration":572.034
116 | }
117 | ],
118 | "structures":[
119 | {
120 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/1",
121 | "type":"Range",
122 | "label":{
123 | "en":[
124 | "Movement I"
125 | ]
126 | },
127 | "items":[
128 | {
129 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=0,15",
130 | "type":"Canvas"
131 | },
132 | {
133 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=15,20",
134 | "type":"Canvas"
135 | },
136 | {
137 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=20,32",
138 | "type":"Canvas"
139 | }
140 | ]
141 | },
142 | {
143 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/2",
144 | "type":"Range",
145 | "label":{
146 | "en":[
147 | "Movement II"
148 | ]
149 | },
150 | "items":[
151 | {
152 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=32,54",
153 | "type":"Canvas"
154 | },
155 | {
156 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=54,59",
157 | "type":"Canvas"
158 | },
159 | {
160 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=59,70",
161 | "type":"Canvas"
162 | },
163 | {
164 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=70,140",
165 | "type":"Canvas"
166 | },
167 | {
168 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=140,148",
169 | "type":"Canvas"
170 | },
171 | {
172 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=148,153",
173 | "type":"Canvas"
174 | },
175 | {
176 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=153,154",
177 | "type":"Canvas"
178 | },
179 | {
180 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=154,159",
181 | "type":"Canvas"
182 | },
183 | {
184 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=159,170",
185 | "type":"Canvas"
186 | },
187 | {
188 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=170,200",
189 | "type":"Canvas"
190 | },
191 | {
192 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=200,254",
193 | "type":"Canvas"
194 | },
195 | {
196 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=254,259",
197 | "type":"Canvas"
198 | },
199 | {
200 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=259,323",
201 | "type":"Canvas"
202 | },
203 | {
204 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=323,333",
205 | "type":"Canvas"
206 | },
207 | {
208 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=333,335",
209 | "type":"Canvas"
210 | },
211 | {
212 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=335,340",
213 | "type":"Canvas"
214 | },
215 | {
216 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=340,342",
217 | "type":"Canvas"
218 | },
219 | {
220 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=342,359",
221 | "type":"Canvas"
222 | },
223 | {
224 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=359,361",
225 | "type":"Canvas"
226 | },
227 | {
228 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=361,363",
229 | "type":"Canvas"
230 | },
231 | {
232 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=363,368",
233 | "type":"Canvas"
234 | },
235 | {
236 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=368,371",
237 | "type":"Canvas"
238 | },
239 | {
240 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=371,390",
241 | "type":"Canvas"
242 | },
243 | {
244 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=390,391",
245 | "type":"Canvas"
246 | },
247 | {
248 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=391,395",
249 | "type":"Canvas"
250 | }
251 | ]
252 | },
253 | {
254 | "id":"https://dlib.indiana.edu/iiif_av/lunchroom_manners/range/3",
255 | "type":"Range",
256 | "label":{
257 | "en":[
258 | "Movement III"
259 | ]
260 | },
261 | "items":[
262 | {
263 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=395,400",
264 | "type":"Canvas"
265 | },
266 | {
267 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=400,404",
268 | "type":"Canvas"
269 | },
270 | {
271 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=404,410",
272 | "type":"Canvas"
273 | },
274 | {
275 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=410,416",
276 | "type":"Canvas"
277 | },
278 | {
279 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=416,417",
280 | "type":"Canvas"
281 | },
282 | {
283 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=417,420",
284 | "type":"Canvas"
285 | },
286 | {
287 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=420,424",
288 | "type":"Canvas"
289 | },
290 | {
291 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=424,427",
292 | "type":"Canvas"
293 | },
294 | {
295 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=427,430",
296 | "type":"Canvas"
297 | },
298 | {
299 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=430,438",
300 | "type":"Canvas"
301 | },
302 | {
303 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=438,444",
304 | "type":"Canvas"
305 | },
306 | {
307 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=444,460",
308 | "type":"Canvas"
309 | },
310 | {
311 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=444,450",
312 | "type":"Canvas"
313 | },
314 | {
315 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=450,455",
316 | "type":"Canvas"
317 | },
318 | {
319 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=455,459",
320 | "type":"Canvas"
321 | },
322 | {
323 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=459,462",
324 | "type":"Canvas"
325 | },
326 | {
327 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=462,467",
328 | "type":"Canvas"
329 | },
330 | {
331 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=467,470",
332 | "type":"Canvas"
333 | },
334 | {
335 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=470,471",
336 | "type":"Canvas"
337 | },
338 | {
339 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=471,479",
340 | "type":"Canvas"
341 | },
342 | {
343 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=479,482",
344 | "type":"Canvas"
345 | },
346 | {
347 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=482,489",
348 | "type":"Canvas"
349 | },
350 | {
351 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=489,500",
352 | "type":"Canvas"
353 | },
354 | {
355 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=502,504",
356 | "type":"Canvas"
357 | },
358 | {
359 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=504,508",
360 | "type":"Canvas"
361 | },
362 | {
363 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=508,509",
364 | "type":"Canvas"
365 | },
366 | {
367 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=509,512",
368 | "type":"Canvas"
369 | },
370 | {
371 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=512,515",
372 | "type":"Canvas"
373 | },
374 | {
375 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=515,517",
376 | "type":"Canvas"
377 | },
378 | {
379 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=517,519",
380 | "type":"Canvas"
381 | },
382 | {
383 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=519,522",
384 | "type":"Canvas"
385 | },
386 | {
387 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=522,530",
388 | "type":"Canvas"
389 | },
390 | {
391 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=530,535",
392 | "type":"Canvas"
393 | },
394 | {
395 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=535,540",
396 | "type":"Canvas"
397 | },
398 | {
399 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=540,545",
400 | "type":"Canvas"
401 | },
402 | {
403 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=545,550",
404 | "type":"Canvas"
405 | },
406 | {
407 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=550,557",
408 | "type":"Canvas"
409 | },
410 | {
411 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=557,570",
412 | "type":"Canvas"
413 | },
414 | {
415 | "id":"http://dlib.indiana.edu/iiif_av/canvas/1#t=570,572.034",
416 | "type":"Canvas"
417 | }
418 | ]
419 | }
420 | ]
421 | }
--------------------------------------------------------------------------------
/static/media/Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DDMAL/IIIF-AV-player/dbb539e810ac9f50b56b47f0325b0bec589823e0/static/media/Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.mp4
--------------------------------------------------------------------------------
/static/media/Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DDMAL/IIIF-AV-player/dbb539e810ac9f50b56b47f0325b0bec589823e0/static/media/Chopin_Etude_Op_10_No_9_Valentina_Lisitsa.webm
--------------------------------------------------------------------------------
/static/media/chopin_etude.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DDMAL/IIIF-AV-player/dbb539e810ac9f50b56b47f0325b0bec589823e0/static/media/chopin_etude.mp3
--------------------------------------------------------------------------------
/static/ui.js:
--------------------------------------------------------------------------------
1 | function createUI ()
2 | {
3 | let main = $('', {'class': 'main'});
4 |
5 | // search manifest box
6 | let searchBox = $('