Add screenshot support.
This commit is contained in:
+30
-25
@@ -5,6 +5,35 @@ import { ViewMedia } from '../view/media';
|
||||
import { errorToConsole } from './basic';
|
||||
import { homeAssistantSignPath } from './ha';
|
||||
|
||||
export const downloadURL = (url: string, filename = 'download'): void => {
|
||||
// The download attribute only works on the same origin.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes
|
||||
const isSameOrigin = new URL(url).origin === window.location.origin;
|
||||
const dataURL = url.startsWith('data:');
|
||||
|
||||
if (
|
||||
navigator.userAgent.startsWith('Home Assistant/') ||
|
||||
navigator.userAgent.startsWith('HomeAssistant/') ||
|
||||
(!isSameOrigin && !dataURL)
|
||||
) {
|
||||
// Home Assistant companion apps cannot download files without opening a
|
||||
// new browser window.
|
||||
//
|
||||
// User-agents are specified here:
|
||||
// - Android: https://github.com/home-assistant/android/blob/b285c9525dd4837a82db931c1b2321c0511494e6/common/src/main/java/io/homeassistant/companion/android/common/data/HomeAssistantApis.kt#L23
|
||||
// - iOS: https://github.com/home-assistant/iOS/blob/master/Sources/Shared/API/HAAPI.swift#L75
|
||||
window.open(url, '_blank');
|
||||
} else {
|
||||
// Use the HTML5 download attribute to prevent a new window from
|
||||
// temporarily opening.
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('download', filename);
|
||||
link.href = url;
|
||||
link.click();
|
||||
link.remove();
|
||||
}
|
||||
};
|
||||
|
||||
export const downloadMedia = async (
|
||||
hass: ExtendedHomeAssistant,
|
||||
cameraManager: CameraManager,
|
||||
@@ -30,29 +59,5 @@ export const downloadMedia = async (
|
||||
finalURL = response;
|
||||
}
|
||||
|
||||
// The download attribute only works on the same origin.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes
|
||||
const isSameOrigin = new URL(finalURL).origin === window.location.origin;
|
||||
|
||||
if (
|
||||
!isSameOrigin ||
|
||||
navigator.userAgent.startsWith('Home Assistant/') ||
|
||||
navigator.userAgent.startsWith('HomeAssistant/')
|
||||
) {
|
||||
// Home Assistant companion apps cannot download files without opening a
|
||||
// new browser window.
|
||||
//
|
||||
// User-agents are specified here:
|
||||
// - Android: https://github.com/home-assistant/android/blob/master/app/src/main/java/io/homeassistant/companion/android/webview/WebViewActivity.kt#L107
|
||||
// - iOS: https://github.com/home-assistant/iOS/blob/master/Sources/Shared/API/HAAPI.swift#L75
|
||||
window.open(finalURL, '_blank');
|
||||
} else {
|
||||
// Use the HTML5 download attribute to prevent a new window from
|
||||
// temporarily opening.
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('download', 'download');
|
||||
link.href = finalURL;
|
||||
link.click();
|
||||
link.remove();
|
||||
}
|
||||
downloadURL(finalURL);
|
||||
};
|
||||
|
||||
@@ -382,6 +382,16 @@ export class MenuButtonController {
|
||||
}
|
||||
}
|
||||
|
||||
if (options?.currentMediaLoadedInfo && options.currentMediaLoadedInfo.player) {
|
||||
buttons.push({
|
||||
icon: 'mdi:monitor-screenshot',
|
||||
...config.menu.buttons.screenshot,
|
||||
type: 'custom:frigate-card-menu-icon',
|
||||
title: localize('config.menu.buttons.screenshot'),
|
||||
tap_action: createFrigateCardCustomAction('screenshot') as FrigateCardCustomAction,
|
||||
});
|
||||
}
|
||||
|
||||
const styledDynamicButtons = this._dynamicMenuButtons.map((button) => ({
|
||||
style: this._getStyleFromActions(config, view, button),
|
||||
...button,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import format from 'date-fns/format';
|
||||
import { View } from '../view/view';
|
||||
|
||||
export const screenshotMedia = (video: HTMLVideoElement): string | null => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) {
|
||||
return null;
|
||||
}
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
return canvas.toDataURL('image/jpeg');
|
||||
};
|
||||
|
||||
export const generateScreenshotTitle = (view?: View): string => {
|
||||
if (view?.is('live') || view?.is('image')) {
|
||||
return `${view.view}-${view.camera}-${format(
|
||||
new Date(),
|
||||
`yyyy-MM-dd-HH-mm-ss`,
|
||||
)}.jpg`;
|
||||
} else if (view?.isViewerView()) {
|
||||
const media = view.queryResults?.getSelectedResult();
|
||||
const id = media?.getID() ?? null;
|
||||
return `${view.view}-${view.camera}${id ? `-${id}` : ''}.jpg`;
|
||||
}
|
||||
return 'screenshot.jpg';
|
||||
};
|
||||
Reference in New Issue
Block a user