diff --git a/layers/511mn/layer.js b/layers/511mn/layer.js
index af140b4..0f7cfd7 100644
--- a/layers/511mn/layer.js
+++ b/layers/511mn/layer.js
@@ -2,6 +2,8 @@ import VectorLayer from 'ol/layer/Vector';
import {Vector as VectorSource} from 'ol/source.js';
import GeoJSON from 'ol/format/GeoJSON.js';
+import Hls from 'hls.js';
+
import {Style} from 'ol/style.js';
import Icon from 'ol/style/Icon.js';
@@ -21,4 +23,35 @@ const vectorLayer = new VectorLayer({
}),
});
+vectorLayer.customPopup = function(feature) {
+ const view = feature.values_.originalData.views[0];
+ if (view.category.toLowerCase() == "video") {
+ return ``;
+ } else if (view.category.toLowerCase() == "image") {
+ return ``;
+ } else {
+ throw new Exception(`unknown category ${view.category}`);
+ }
+};
+
+vectorLayer.customPopupCallback = function(feature) {
+ const view = feature.values_.originalData.views[0];
+ if (view.category.toLowerCase() == "video") {
+ const video = document.getElementById('popupVideo');
+
+ const videoID = view.url.split('/').pop();
+
+ const videoSrc = `https://video.dot.state.mn.us/public/${videoID}.stream/playlist.m3u8`;
+ if (Hls.isSupported()) {
+ var hls = new Hls();
+ hls.loadSource(videoSrc);
+ hls.attachMedia(video);
+ }
+ // iDevice support, untested (only works in Safari; required for iPhones)
+ else if (video.canPlayType('application/vnd.apple.mpegurl')) {
+ video.src = videoSrc;
+ }
+ }
+}
+
export default vectorLayer;
diff --git a/main.js b/main.js
index aa623af..7ffa370 100644
--- a/main.js
+++ b/main.js
@@ -96,16 +96,25 @@ function objectToTable(o) {
// from https://openlayers.org/en/latest/examples/icon.html
map.on('click', function (evt) {
- const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
+ let layer;
+ const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, l) {
+ layer = l;
return feature;
});
if (!feature) {
return;
}
+ if (layer.hasOwnProperty('customPopup')) {
+ content.innerHTML = layer.customPopup(feature);
+ if (layer.hasOwnProperty('customPopupCallback')) {
+ layer.customPopupCallback(feature);
+ }
+ } else {
+ // exclude geometry -- https://stackoverflow.com/a/208106
+ const {geometry: _, ...featureData} = feature.values_;
- // exclude geometry -- https://stackoverflow.com/a/208106
- const {geometry: _, ...featureData} = feature.values_;
+ content.innerHTML = objectToTable(featureData);
+ }
- content.innerHTML = objectToTable(featureData);
popupOverlay.setPosition(evt.coordinate);
});
diff --git a/package-lock.json b/package-lock.json
index 280a28c..dd6050d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "maps.chandlerswift.com",
"version": "0.0.0",
"dependencies": {
+ "hls.js": "^1.5.2",
"ol": "latest",
"proj4": "2.9.0"
},
@@ -490,6 +491,11 @@
"node": ">=10.19"
}
},
+ "node_modules/hls.js": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.2.tgz",
+ "integrity": "sha512-MJtx9GbfO1We1N6Zx5JbxdIAGLQWKPss56YzkR45GIdVcz+jBQVbLBZnsANpQpECvRBWZUcg9opEDo1biG/qVA=="
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -1057,6 +1063,11 @@
"xml-utils": "^1.0.2"
}
},
+ "hls.js": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.2.tgz",
+ "integrity": "sha512-MJtx9GbfO1We1N6Zx5JbxdIAGLQWKPss56YzkR45GIdVcz+jBQVbLBZnsANpQpECvRBWZUcg9opEDo1biG/qVA=="
+ },
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
diff --git a/package.json b/package.json
index fe63e78..1933f6b 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"vite": "^4.3.9"
},
"dependencies": {
+ "hls.js": "^1.5.2",
"ol": "latest",
"proj4": "2.9.0"
}