Compare commits

..

8 Commits

Author SHA1 Message Date
Koushik Dutta
e163aa8153 wyze: cluster mode support 2024-12-30 21:36:52 -08:00
Koushik Dutta
268225647e postbeta 2024-12-30 21:29:24 -08:00
Koushik Dutta
93f94b0b0a server: Fixup casing 2024-12-30 21:29:15 -08:00
Koushik Dutta
db73baf4c1 postbeta 2024-12-30 21:28:28 -08:00
Koushik Dutta
404cf47d2e server: make mediaManager cluster aware 2024-12-30 21:28:06 -08:00
Koushik Dutta
b751f77b0b wyze: require linux 2024-12-30 21:01:08 -08:00
Koushik Dutta
884ce3e175 postbeta 2024-12-30 19:32:23 -08:00
Koushik Dutta
0cb0071874 postrelease 2024-12-30 19:28:35 -08:00
10 changed files with 79 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
{
"scrypted.debugHost": "scrypted-nvr",
"scrypted.debugHost": "127.0.0.1",
"python.analysis.extraPaths": [
"./node_modules/@scrypted/sdk/types/scrypted_python"

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/wyze",
"version": "0.0.54",
"version": "0.0.56",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/wyze",
"version": "0.0.54",
"version": "0.0.56",
"devDependencies": {
"@scrypted/sdk": "file:../../sdk"
}

View File

@@ -28,10 +28,15 @@
],
"pluginDependencies": [
"@scrypted/prebuffer-mixin"
]
],
"labels": {
"require": [
"linux"
]
}
},
"devDependencies": {
"@scrypted/sdk": "file:../../sdk"
},
"version": "0.0.54"
"version": "0.0.56"
}

View File

@@ -305,11 +305,12 @@ class WyzeCamera(scrypted_sdk.ScryptedDeviceBase, VideoCamera, Settings, PanTilt
pkill(aprocess)
async def ensureServer(self, cb) -> int:
server = await asyncio.start_server(cb, "127.0.0.1", 0)
host = os.environ.get("SCRYPTED_CLUSTER_ADDRESS", None) or "127.0.0.1"
server = await asyncio.start_server(cb, host, 0)
sock = server.sockets[0]
host, port = sock.getsockname()
asyncio.ensure_future(server.serve_forever())
return port
return host, port
async def probeCodec(self, substream: bool):
sps: bytes = None
@@ -414,7 +415,7 @@ class WyzeCamera(scrypted_sdk.ScryptedDeviceBase, VideoCamera, Settings, PanTilt
print_exception(self.print, e)
raise
rfcPort = await self.rfcSubServer if substream else await self.rfcServer
rfcHost, rfcPort = await self.rfcSubServer if substream else await self.rfcServer
msos = self.getVideoStreamOptionsInternal()
mso = msos[1] if substream else msos[0]
@@ -441,7 +442,7 @@ b=AS:128
a=rtpmap:97 {audioCodecName}/{info.audioSampleRate}/1
"""
rfc = {
"url": f"tcp://127.0.0.1:{rfcPort}",
"url": f"tcp://{rfcHost}:{rfcPort}",
"sdp": sdp,
"mediaStreamOptions": mso,
}

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/server",
"version": "0.123.73",
"version": "0.125.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@scrypted/server",
"version": "0.123.73",
"version": "0.125.2",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/server",
"version": "0.124.0",
"version": "0.125.3",
"description": "",
"dependencies": {
"@scrypted/ffmpeg-static": "^6.1.0-build3",

View File

@@ -6,6 +6,7 @@ import inspect
import multiprocessing
import multiprocessing.connection
import os
from pathlib import Path
import platform
import random
import sys
@@ -472,11 +473,39 @@ class MediaManager:
) -> scrypted_python.scrypted_sdk.types.MediaObject:
return await self.mediaManager.createMediaObjectFromUrl(data, options)
async def getFFmpegPath(self) -> str:
async def getFFmpegPath(self):
# try to get the ffmpeg path as a value of another variable
# ie, in docker builds:
# export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH
v = os.getenv('SCRYPTED_FFMPEG_PATH_ENV_VARIABLE')
if v:
f = os.getenv(v)
if f and Path(f).exists():
return f
# try to get the ffmpeg path from a variable
# ie:
# export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg
f = os.getenv('SCRYPTED_FFMPEG_PATH')
if f and Path(f).exists():
return f
return await self.mediaManager.getFFmpegPath()
async def getFilesPath(self) -> str:
return await self.mediaManager.getFilesPath()
async def getFilesPath(self):
# Get the value of the SCRYPTED_PLUGIN_VOLUME environment variable
files_path = os.getenv('SCRYPTED_PLUGIN_VOLUME')
if not files_path:
raise ValueError('SCRYPTED_PLUGIN_VOLUME env variable not set?')
# Construct the path for the 'files' directory
ret = Path(files_path) / 'files'
# Ensure the directory exists
await asyncio.to_thread(ret.mkdir, parents=True, exist_ok=True)
# Return the constructed directory path as a string
return str(ret)
class DeviceState(scrypted_python.scrypted_sdk.types.DeviceState):

View File

@@ -0,0 +1,25 @@
import { getFfmpegPath } from '@scrypted/ffmpeg-static';
import fs from 'fs';
import os from 'os';
export async function getScryptedFFmpegPath(): Promise<string> {
// try to get the ffmpeg path as a value of another variable
// ie, in docker builds:
// export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH
const v = process.env.SCRYPTED_FFMPEG_PATH_ENV_VARIABLE;
if (v) {
const f = process.env[v];
if (f && fs.existsSync(f))
return f;
}
// try to get the ffmpeg path from a variable
// ie:
// export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg
const f = process.env.SCRYPTED_FFMPEG_PATH;
if (f && fs.existsSync(f))
return f;
const defaultPath = os.platform() === 'win32' ? 'ffmpeg.exe' : 'ffmpeg';
return getFfmpegPath() || defaultPath;
}

View File

@@ -1,12 +1,11 @@
import { getFfmpegPath } from '@scrypted/ffmpeg-static';
import { BufferConverter, DeviceManager, FFmpegInput, MediaConverter, MediaManager, MediaObjectCreateOptions, MediaObject as MediaObjectInterface, MediaStreamUrl, ScryptedDevice, ScryptedInterface, ScryptedInterfaceProperty, ScryptedMimeTypes, ScryptedNativeId, SystemDeviceState, SystemManager } from "@scrypted/types";
import fs from 'fs';
import https from 'https';
import Graph from 'node-dijkstra';
import os from 'os';
import path from 'path';
import send from 'send';
import MimeType from 'whatwg-mimetype';
import { getScryptedFFmpegPath } from './ffmpeg-path';
import { MediaObject } from "./mediaobject";
import { MediaObjectRemote } from "./plugin-api";
@@ -174,25 +173,7 @@ export abstract class MediaManagerBase implements MediaManager {
abstract getMixinConsole(mixinId: string, nativeId: ScryptedNativeId): Console;
async getFFmpegPath(): Promise<string> {
// try to get the ffmpeg path as a value of another variable
// ie, in docker builds:
// export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH
const v = process.env.SCRYPTED_FFMPEG_PATH_ENV_VARIABLE;
if (v) {
const f = process.env[v];
if (f && fs.existsSync(f))
return f;
}
// try to get the ffmpeg path from a variable
// ie:
// export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg
const f = process.env.SCRYPTED_FFMPEG_PATH;
if (f && fs.existsSync(f))
return f;
const defaultPath = os.platform() === 'win32' ? 'ffmpeg.exe' : 'ffmpeg';
return getFfmpegPath() || defaultPath;
return getScryptedFFmpegPath();
}
async getFilesPath(): Promise<string> {

View File

@@ -23,6 +23,7 @@ import { EnvControl } from './services/env';
import { Info } from './services/info';
import { ServiceControl } from './services/service-control';
import { sleep } from './sleep';
import { getScryptedFFmpegPath } from './plugin/ffmpeg-path';
installSourceMapSupport({
environment: 'node',
@@ -143,6 +144,7 @@ function createClusterForkParam(mainFilename: string, clusterId: string, cluster
...runtimeWorkerOptions.env,
SCRYPTED_VOLUME: volume,
SCRYPTED_PLUGIN_VOLUME: pluginVolume,
SCRYPTED_FFMPEG_PATH: process.env.SCRYPTED_FFMPEG_PATH || await getScryptedFFmpegPath(),
};
runtimeWorker = rt(mainFilename, runtimeWorkerOptions, undefined);