mirror of
https://github.com/koush/scrypted.git
synced 2026-03-20 16:40:24 +00:00
google-cloud-tts: publish
This commit is contained in:
95
plugins/google-cloud-tts/package-lock.json
generated
95
plugins/google-cloud-tts/package-lock.json
generated
@@ -1,17 +1,18 @@
|
||||
{
|
||||
"name": "@scrypted/google-cloud-tts",
|
||||
"version": "0.0.20",
|
||||
"version": "0.0.21",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/google-cloud-tts",
|
||||
"version": "0.0.20",
|
||||
"version": "0.0.21",
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0"
|
||||
"axios": "^0.24.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^17.0.8"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
@@ -63,38 +64,38 @@
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "17.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
|
||||
"integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410",
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "1.5.10"
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"dependencies": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects/node_modules/debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -127,36 +128,24 @@
|
||||
"webpack": "^5.59.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "17.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.8.tgz",
|
||||
"integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/google-cloud-tts",
|
||||
"version": "0.0.20",
|
||||
"version": "0.0.21",
|
||||
"description": "Google Cloud Text to Speech plugin for Scrypted",
|
||||
"scripts": {
|
||||
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
||||
@@ -27,9 +27,10 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/node": "^17.0.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0"
|
||||
"axios": "^0.24.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,28 @@
|
||||
// https://developer.scrypted.app/#getting-started
|
||||
import axios from 'axios';
|
||||
import sdk, { BufferConverter, ScryptedDeviceBase, Settings, Setting } from "@scrypted/sdk";
|
||||
import { Buffer } from 'buffer';
|
||||
import { title } from 'process';
|
||||
const { log } = sdk;
|
||||
|
||||
const api_key = localStorage.getItem('api_key');
|
||||
|
||||
function alertAndThrow(msg) {
|
||||
log.a(msg);
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
if (!api_key) {
|
||||
alertAndThrow('The "api_key" Script Setting values is missing.');
|
||||
}
|
||||
log.clearAlerts();
|
||||
|
||||
|
||||
var voice_name = localStorage.getItem("voice_name");
|
||||
if (!voice_name) {
|
||||
voice_name = "en-GB-Standard-A";
|
||||
log.i(`Using default voice_name setting: ${voice_name}. See settings for more information.`);
|
||||
}
|
||||
|
||||
var voice_gender = localStorage.getItem("voice_gender");
|
||||
if (!voice_gender) {
|
||||
voice_gender = "FEMALE";
|
||||
log.i(`Using default voice_gender setting: ${voice_gender}. See settings for more information.`);
|
||||
}
|
||||
|
||||
var voice_language_code = localStorage.getItem("voice_language_code");
|
||||
if (!voice_language_code) {
|
||||
voice_language_code = "en-GB";
|
||||
log.i(`Using default voice_language_code setting: ${voice_language_code}. See settings for more information.`);
|
||||
}
|
||||
|
||||
var voices: any = {};
|
||||
axios.get(`https://texttospeech.googleapis.com/v1/voices?key=${api_key}`)
|
||||
.then(response => {
|
||||
log.i(JSON.stringify(response.data, null, 2));
|
||||
voices = response.data;
|
||||
});
|
||||
|
||||
|
||||
class Device extends ScryptedDeviceBase implements BufferConverter, Settings {
|
||||
class GoogleCloudTts extends ScryptedDeviceBase implements BufferConverter, Settings {
|
||||
constructor() {
|
||||
super();
|
||||
this.fromMimeType = 'text/plain';
|
||||
this.toMimeType = 'audio/mpeg';
|
||||
|
||||
if (!this.getApiKey())
|
||||
this.log.a('API key missing.');
|
||||
}
|
||||
async convert(from, fromMimeType) {
|
||||
log.i(from.toString());
|
||||
from = Buffer.from(from);
|
||||
getApiKey() {
|
||||
const apiKey = this.storage.getItem('api_key');
|
||||
return apiKey;
|
||||
}
|
||||
async convert(data: string | Buffer, fromMimeType: string): Promise<Buffer> {
|
||||
const voice_name = this.storage.getItem("voice_name") || "en-GB-Standard-A";
|
||||
const voice_gender = this.storage.getItem("voice_gender") || "FEMALE";
|
||||
const voice_language_code = this.storage.getItem("voice_language_code") || "en-GB";
|
||||
|
||||
const from = Buffer.from(data);
|
||||
var json = {
|
||||
"input": {
|
||||
"text": from.toString()
|
||||
@@ -65,40 +36,62 @@ class Device extends ScryptedDeviceBase implements BufferConverter, Settings {
|
||||
"audioEncoding": "MP3"
|
||||
}
|
||||
};
|
||||
log.i(JSON.stringify(json));
|
||||
|
||||
var result = await axios.post(`https://texttospeech.googleapis.com/v1/text:synthesize?key=${api_key}`, json);
|
||||
log.i(JSON.stringify(result.data, null, 2));
|
||||
var result = await axios.post(`https://texttospeech.googleapis.com/v1/text:synthesize?key=${this.getApiKey()}`, json);
|
||||
console.log(JSON.stringify(result.data, null, 2));
|
||||
const buffer = Buffer.from(result.data.audioContent, 'base64');
|
||||
return buffer;
|
||||
}
|
||||
|
||||
voices: any;
|
||||
async getSettings(): Promise<Setting[]> {
|
||||
return [{
|
||||
const ret: Setting[] = [
|
||||
{
|
||||
title: 'API Key',
|
||||
description: 'API Key used by Google Cloud TTS.',
|
||||
key: 'api_key',
|
||||
value: this.storage.getItem('api_key'),
|
||||
}
|
||||
];
|
||||
|
||||
if (!this.getApiKey())
|
||||
return ret;
|
||||
|
||||
try {
|
||||
if (!this.voices) {
|
||||
const response = await axios.get(`https://texttospeech.googleapis.com/v1/voices?key=${this.getApiKey()}`)
|
||||
this.voices = response.data;
|
||||
}
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
this.log.a('Error retrieving settings from Google Cloud Text to Speech. Is your API Key correct?');
|
||||
return ret;
|
||||
}
|
||||
ret.push({
|
||||
title: "Voice",
|
||||
choices: voices.voices.map(voice => voice.name),
|
||||
choices: this.voices.voices.map(voice => voice.name),
|
||||
key: "voice",
|
||||
value: voice_name,
|
||||
}];
|
||||
value: this.storage.getItem("voice_name"),
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
putSetting(key: string, value: string | number | boolean): void {
|
||||
async putSetting(key: string, value: string | number | boolean) {
|
||||
if (key !== 'voice') {
|
||||
this.storage.setItem(key, value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
var found = voices.voices.find(voice => voice.name === value);
|
||||
const found = this.voices.voices.find((voice: any) => voice.name === value);
|
||||
if (!found) {
|
||||
log.a('Voice not found.');
|
||||
console.error('Voice not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
voice_name = found.name;
|
||||
voice_language_code = found.languageCodes[0];
|
||||
voice_gender = found.ssmlGender;
|
||||
localStorage.setItem('voice_name', voice_name);
|
||||
localStorage.setItem('voice_language_code', voice_language_code);
|
||||
localStorage.setItem('voice_gender', voice_gender);
|
||||
localStorage.setItem('voice_name', found.name);
|
||||
localStorage.setItem('voice_language_code', found.languageCodes[0]);
|
||||
localStorage.setItem('voice_gender', found.ssmlGender);
|
||||
}
|
||||
}
|
||||
|
||||
export default new Device();
|
||||
export default new GoogleCloudTts();
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any, List
|
||||
import numpy as np
|
||||
import cv2
|
||||
import imutils
|
||||
from gi.repository import GLib, Gst
|
||||
from gi.repository import Gst
|
||||
from scrypted_sdk.types import ObjectDetectionModel, ObjectDetectionResult, ObjectsDetected
|
||||
|
||||
class OpenCVDetectionSession(DetectionSession):
|
||||
|
||||
4
plugins/prebuffer-mixin/package-lock.json
generated
4
plugins/prebuffer-mixin/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.116",
|
||||
"version": "0.1.117",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.116",
|
||||
"version": "0.1.117",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.116",
|
||||
"version": "0.1.117",
|
||||
"description": "Rebroadcast and Prebuffer for VideoCameras.",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -307,10 +307,10 @@ class PrebufferSession {
|
||||
// s16le will be a no-op if there's no pcm, no harm.
|
||||
for (const container of ['mpegts', 'mp4', 's16le']) {
|
||||
const eventName = container + '-data';
|
||||
let prebufferContainer: PrebufferStreamChunk[] = this.prebuffers[container];
|
||||
let shifts = 0;
|
||||
|
||||
session.events.on(eventName, (chunk: StreamChunk) => {
|
||||
const prebufferContainer: PrebufferStreamChunk[] = this.prebuffers[container];
|
||||
const now = Date.now();
|
||||
|
||||
if (chunk.type === 'mdat') {
|
||||
@@ -330,7 +330,7 @@ class PrebufferSession {
|
||||
}
|
||||
|
||||
if (shifts > 1000) {
|
||||
prebufferContainer = this.prebuffers[container] = prebufferContainer.slice();
|
||||
this.prebuffers[container] = prebufferContainer.slice();
|
||||
shifts = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ gi.require_version('Gst', '1.0')
|
||||
gi.require_version('GstBase', '1.0')
|
||||
|
||||
from .safe_set_result import safe_set_result
|
||||
from gi.repository import GLib, GObject, Gst
|
||||
from gi.repository import GObject, Gst
|
||||
import math
|
||||
|
||||
GObject.threads_init()
|
||||
@@ -71,8 +71,6 @@ class GstPipelineBase:
|
||||
|
||||
# Clean up.
|
||||
self.gst.set_state(Gst.State.NULL)
|
||||
while GLib.MainContext.default().iteration(False):
|
||||
pass
|
||||
|
||||
class GstPipeline(GstPipelineBase):
|
||||
def __init__(self, finished: Future, appsink_name: str, user_function):
|
||||
|
||||
Reference in New Issue
Block a user