mirror of
https://github.com/koush/scrypted.git
synced 2026-04-26 09:50:21 +01:00
62 lines
2.3 KiB
TypeScript
62 lines
2.3 KiB
TypeScript
|
|
import { MixinProvider, Notifier, ScryptedDevice, MixinDeviceBase, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, MediaObject, MediaPlayer } from '@scrypted/sdk';
|
|
import sdk from '@scrypted/sdk';
|
|
import memoizeOne from 'memoize-one';
|
|
|
|
const { mediaManager, log } = sdk;
|
|
|
|
async function audioFetch(body: string): Promise<string> {
|
|
const buf = Buffer.from(body);
|
|
const mo = mediaManager.createMediaObject(buf, 'text/plain');
|
|
return mediaManager.convertMediaObjectToInsecureLocalUrl(mo, 'audio/*');
|
|
}
|
|
|
|
// memoize this text conversion, as announcements going to multiple speakers will
|
|
// trigger multiple text to speech conversions.
|
|
// this is a simple way to prevent thrashing by waiting for the single promise.
|
|
var memoizedAudioFetch = memoizeOne(audioFetch);
|
|
|
|
class NotifierMixin extends MixinDeviceBase<MediaPlayer> implements Notifier {
|
|
constructor(mixinDevice: MediaPlayer, mixinDeviceInterfaces: ScryptedInterface[], mixinDeviceState: { [key: string]: any }, providerNativeId: string) {
|
|
super(mixinDevice, mixinDeviceInterfaces, mixinDeviceState, providerNativeId);
|
|
}
|
|
|
|
async sendNotification(title: string, body: string, media: string | MediaObject, mimeType: string): Promise<void> {
|
|
if (!media || this.type == 'Speaker') {
|
|
try {
|
|
log.i('fetching audio: ' + body);
|
|
const result = await memoizedAudioFetch(body)
|
|
log.i(`sending audio ${result}`);
|
|
(this.mixinDevice as MediaPlayer).load(result, {
|
|
title,
|
|
})
|
|
}
|
|
catch (e) {
|
|
log.e(`error memoizing audio ${e}`);
|
|
// do not cache errors.
|
|
memoizedAudioFetch = memoizeOne(audioFetch);
|
|
}
|
|
return;
|
|
}
|
|
|
|
(this.mixinDevice as MediaPlayer).load(media, {
|
|
title,
|
|
mimeType,
|
|
});
|
|
}
|
|
}
|
|
|
|
class NotifierProvider extends ScryptedDeviceBase implements MixinProvider {
|
|
canMixin(type: ScryptedDeviceType, interfaces: string[]): string[] {
|
|
if (!interfaces.includes(ScryptedInterface.MediaPlayer))
|
|
return null;
|
|
return [ScryptedInterface.Notifier];
|
|
}
|
|
|
|
getMixin(mixinDevice: MediaPlayer, mixinDeviceInterfaces: ScryptedInterface[], mixinDeviceState: { [key: string]: any }) {
|
|
return new NotifierMixin(mixinDevice, mixinDeviceInterfaces, mixinDeviceState, this.nativeId);
|
|
}
|
|
}
|
|
|
|
export default new NotifierProvider();
|