Compare commits

...

15 Commits

Author SHA1 Message Date
Koushik Dutta
db03775530 prerelease 2023-03-31 20:37:25 -07:00
Koushik Dutta
cccbc33f1a server: detect 32/64 mixed mode issue and provide hint on how to fix. https://github.com/koush/scrypted/issues/678 2023-03-31 20:37:14 -07:00
Koushik Dutta
5f23873366 videoanalysis: fix bug where motion sensor would stop on invalid condition 2023-03-31 12:37:52 -07:00
Koushik Dutta
e43accae67 Merge branch 'main' of github.com:koush/scrypted 2023-03-31 09:45:02 -07:00
Koushik Dutta
b3a0cda6f9 python-codecs: fix vips/yuv/gray fast path 2023-03-31 09:44:57 -07:00
Alex Leeds
58c3348282 hap: merge in sirens as child devices (#674)
* hap: merge in sirens as child devices

* add subtype to onOff base
2023-03-31 07:44:38 -07:00
Koushik Dutta
a9e6d76e99 python-codecs: fix libav jpeg export 2023-03-30 23:59:05 -07:00
Koushik Dutta
3b58936387 predict: remove dead code 2023-03-30 09:35:47 -07:00
Koushik Dutta
3a14ab81c8 sample: update 2023-03-30 09:35:37 -07:00
Koushik Dutta
291178a7b5 sdk/client: update 2023-03-30 09:34:57 -07:00
Koushik Dutta
b65faf1a79 opencv: add gray toBuffer fast path 2023-03-30 09:34:45 -07:00
Koushik Dutta
9d8a1353c0 opencv: fix motion box translation 2023-03-29 17:25:24 -07:00
Koushik Dutta
b29d793178 ring: remove accidental clearing of clips cache 2023-03-29 16:42:09 -07:00
Koushik Dutta
d8e406d415 webrtc: reduce debug logging 2023-03-29 16:41:16 -07:00
Koushik Dutta
4529872fd6 videoanalysis: make sharp optional 2023-03-29 14:03:35 -07:00
37 changed files with 189 additions and 132 deletions

View File

@@ -250,7 +250,8 @@ export class BrowserSignalingSession implements RTCSignalingSession {
function logSendCandidate(console: Console, type: string, session: RTCSignalingSession): RTCSignalingSendIceCandidate {
return async (candidate) => {
try {
console.log(`${type} trickled candidate:`, candidate.sdpMLineIndex, candidate.candidate);
if (localStorage.getItem('debugLog') === 'true')
console.log(`${type} trickled candidate:`, candidate.sdpMLineIndex, candidate.candidate);
await session.addIceCandidate(candidate);
}
catch (e) {
@@ -308,11 +309,13 @@ export async function connectRTCSignalingClients(
const offer = await offerClient.createLocalDescription('offer', offerSetup as RTCAVSignalingSetup,
disableTrickle ? undefined : answerQueue.queueSendCandidate);
console.log('offer sdp', offer.sdp);
if (localStorage.getItem('debugLog') === 'true')
console.log('offer sdp', offer.sdp);
await answerClient.setRemoteDescription(offer, answerSetup as RTCAVSignalingSetup);
const answer = await answerClient.createLocalDescription('answer', answerSetup as RTCAVSignalingSetup,
disableTrickle ? undefined : offerQueue.queueSendCandidate);
console.log('answer sdp', answer.sdp);
if (localStorage.getItem('debugLog') === 'true')
console.log('answer sdp', answer.sdp);
await offerClient.setRemoteDescription(answer, offerSetup as RTCAVSignalingSetup);
offerQueue.flush();
answerQueue.flush();

View File

@@ -9,7 +9,7 @@
"version": "1.1.43",
"license": "ISC",
"dependencies": {
"@scrypted/types": "^0.2.76",
"@scrypted/types": "^0.2.78",
"axios": "^0.25.0",
"engine.io-client": "^6.4.0",
"rimraf": "^3.0.2"
@@ -21,9 +21,9 @@
}
},
"node_modules/@scrypted/types": {
"version": "0.2.76",
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.2.76.tgz",
"integrity": "sha512-/7n8ICkXj8TGba4cHvckLCgSNsOmOGQ8I+Jd8fX9sxkthgsZhF5At8PHhHdkCDS+yfSmfXHkcqluZZOfYPkpAg=="
"version": "0.2.78",
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.2.78.tgz",
"integrity": "sha512-SiIUh9ph96aZPjt/oO+W/mlJobrP02ADwFDI9jnvw8/UegUti2x/7JE8Pi3kGXOIkN+cX74Qg4xJEMIpdpO1zw=="
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",

View File

@@ -17,7 +17,7 @@
"typescript": "^4.9.5"
},
"dependencies": {
"@scrypted/types": "^0.2.76",
"@scrypted/types": "^0.2.78",
"axios": "^0.25.0",
"engine.io-client": "^6.4.0",
"rimraf": "^3.0.2"

View File

@@ -1,25 +1,25 @@
{
"name": "@scrypted/homekit",
"version": "1.2.21",
"version": "1.2.22",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/homekit",
"version": "1.2.21",
"version": "1.2.22",
"dependencies": {
"@koush/werift-src": "file:../../external/werift",
"check-disk-space": "^3.3.1",
"hap-nodejs": "^0.11.0",
"lodash": "^4.17.21",
"mkdirp": "^2.1.5"
"mkdirp": "^2.1.6"
},
"devDependencies": {
"@scrypted/common": "file:../../common",
"@scrypted/sdk": "file:../../sdk",
"@types/debug": "^4.1.7",
"@types/lodash": "^4.14.191",
"@types/node": "^18.15.5",
"@types/lodash": "^4.14.192",
"@types/node": "^18.15.11",
"@types/url-parse": "^1.4.8"
}
},
@@ -126,7 +126,7 @@
},
"../../sdk": {
"name": "@scrypted/sdk",
"version": "0.2.85",
"version": "0.2.86",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -276,9 +276,9 @@
}
},
"node_modules/@types/lodash": {
"version": "4.14.191",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
"integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
"version": "4.14.192",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz",
"integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==",
"dev": true
},
"node_modules/@types/ms": {
@@ -288,9 +288,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "18.15.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz",
"integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==",
"version": "18.15.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz",
"integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==",
"dev": true
},
"node_modules/@types/url-parse": {
@@ -856,9 +856,9 @@
}
},
"node_modules/mkdirp": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.5.tgz",
"integrity": "sha512-jbjfql+shJtAPrFoKxHOXip4xS+kul9W3OzfzzrqueWK2QMGon2bFH2opl6W9EagBThjEz+iysyi/swOoVfB/w==",
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
"integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
"bin": {
"mkdirp": "dist/cjs/src/bin.js"
},
@@ -1276,9 +1276,9 @@
}
},
"@types/lodash": {
"version": "4.14.191",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
"integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
"version": "4.14.192",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz",
"integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==",
"dev": true
},
"@types/ms": {
@@ -1288,9 +1288,9 @@
"dev": true
},
"@types/node": {
"version": "18.15.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz",
"integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==",
"version": "18.15.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz",
"integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==",
"dev": true
},
"@types/url-parse": {
@@ -1698,9 +1698,9 @@
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
"mkdirp": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.5.tgz",
"integrity": "sha512-jbjfql+shJtAPrFoKxHOXip4xS+kul9W3OzfzzrqueWK2QMGon2bFH2opl6W9EagBThjEz+iysyi/swOoVfB/w=="
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz",
"integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A=="
},
"ms": {
"version": "2.1.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/homekit",
"version": "1.2.21",
"version": "1.2.22",
"description": "HomeKit Plugin for Scrypted",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",
@@ -38,14 +38,14 @@
"check-disk-space": "^3.3.1",
"hap-nodejs": "^0.11.0",
"lodash": "^4.17.21",
"mkdirp": "^2.1.5"
"mkdirp": "^2.1.6"
},
"devDependencies": {
"@scrypted/common": "file:../../common",
"@scrypted/sdk": "file:../../sdk",
"@types/debug": "^4.1.7",
"@types/lodash": "^4.14.191",
"@types/node": "^18.15.5",
"@types/lodash": "^4.14.192",
"@types/node": "^18.15.11",
"@types/url-parse": "^1.4.8"
}
}

View File

@@ -303,13 +303,19 @@ addSupportedType({
}
}
// if the camera is a device provider, merge in child devices and
// ensure the devices are skipped by the rest of homekit by
// reporting that they've been merged
if (device.interfaces.includes(ScryptedInterface.DeviceProvider)) {
// merge in lights
const { devices } = mergeOnOffDevicesByType(device as ScryptedDevice as ScryptedDevice & DeviceProvider, accessory, ScryptedDeviceType.Light);
mergeOnOffDevicesByType(device as ScryptedDevice as ScryptedDevice & DeviceProvider, accessory, ScryptedDeviceType.Light).devices.forEach(device => {
homekitPlugin.mergedDevices.add(device.id)
});
// ensure child devices are skipped by the rest of homekit by
// reporting that they've been merged
devices.map(device => homekitPlugin.mergedDevices.add(device.id));
// merge in sirens
mergeOnOffDevicesByType(device as ScryptedDevice as ScryptedDevice & DeviceProvider, accessory, ScryptedDeviceType.Siren).devices.forEach(device => {
homekitPlugin.mergedDevices.add(device.id)
});
}
return accessory;

View File

@@ -9,7 +9,7 @@ export function probe(device: DummyDevice): boolean {
}
export function getService(device: ScryptedDevice & OnOff, accessory: Accessory, serviceType: any): Service {
const service = accessory.addService(serviceType, device.name);
const service = accessory.addService(serviceType, device.name, device.nativeId);
service.getCharacteristic(Characteristic.On)
.on(CharacteristicEventTypes.SET, (value: CharacteristicValue, callback: CharacteristicSetCallback) => {
callback();

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/objectdetector",
"version": "0.0.119",
"version": "0.0.121",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/objectdetector",
"version": "0.0.119",
"version": "0.0.121",
"license": "Apache-2.0",
"dependencies": {
"@scrypted/common": "file:../../common",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/objectdetector",
"version": "0.0.119",
"version": "0.0.121",
"description": "Scrypted Video Analysis Plugin. Installed alongside a detection service like OpenCV or TensorFlow.",
"author": "Scrypted",
"license": "Apache-2.0",

View File

@@ -1,12 +1,32 @@
import { Deferred } from "@scrypted/common/src/deferred";
import { addVideoFilterArguments } from "@scrypted/common/src/ffmpeg-helpers";
import { ffmpegLogInitialOutput, safeKillFFmpeg, safePrintFFmpegArguments } from "@scrypted/common/src/media-helpers";
import { readLength, readLine } from "@scrypted/common/src/read-stream";
import { addVideoFilterArguments } from "@scrypted/common/src/ffmpeg-helpers";
import sdk, { FFmpegInput, Image, ImageOptions, MediaObject, ScryptedDeviceBase, ScryptedMimeTypes, VideoFrame, VideoFrameGenerator, VideoFrameGeneratorOptions } from "@scrypted/sdk";
import child_process from 'child_process';
import sharp from 'sharp';
import type sharp from 'sharp';
import { Readable } from 'stream';
export let sharpLib: (input?:
| Buffer
| Uint8Array
| Uint8ClampedArray
| Int8Array
| Uint16Array
| Int16Array
| Uint32Array
| Int32Array
| Float32Array
| Float64Array
| string,
options?: sharp.SharpOptions) => sharp.Sharp;
try {
sharpLib = require('sharp');
}
catch (e) {
console.warn('Sharp failed to load. FFmpeg Frame Generator will not function properly.')
}
async function createVipsMediaObject(image: VipsImage): Promise<VideoFrame & MediaObject> {
const ret = await sdk.mediaManager.createMediaObject(image, ScryptedMimeTypes.Image, {
format: null,
@@ -76,7 +96,20 @@ class VipsImage implements Image {
resolveWithObject: true,
});
const newImage = sharp(data, {
const sharpLib = require('sharp') as (input?:
| Buffer
| Uint8Array
| Uint8ClampedArray
| Int8Array
| Uint16Array
| Int16Array
| Uint32Array
| Int32Array
| Float32Array
| Float64Array
| string,
options?) => sharp.Sharp;
const newImage = sharpLib(data, {
raw: info,
});
@@ -177,7 +210,7 @@ export class FFmpegVideoFrameGenerator extends ScryptedDeviceBase implements Vid
const raw = await frameDeferred.promise;
const { width, height, data } = raw;
const image = sharp(data, {
const image = sharpLib(data, {
raw: {
width,
height,

View File

@@ -4,7 +4,7 @@ import crypto from 'crypto';
import { AutoenableMixinProvider } from "../../../common/src/autoenable-mixin-provider";
import { SettingsMixinDeviceBase } from "../../../common/src/settings-mixin";
import { DenoisedDetectionState } from './denoise';
import { FFmpegVideoFrameGenerator } from './ffmpeg-videoframes';
import { FFmpegVideoFrameGenerator, sharpLib } from './ffmpeg-videoframes';
import { serverSupportsMixinEventMasking } from './server-version';
import { sleep } from './sleep';
import { getAllDevices, safeParseJson } from './util';
@@ -201,7 +201,6 @@ class ObjectDetectionMixin extends SettingsMixinDeviceBase<VideoCamera & Camera
if (this.hasMotionType)
this.motionDetected = false;
this.detectorRunning = false;
this.endObjectDetection();
this.maybeStartMotionDetection();
@@ -333,8 +332,7 @@ class ObjectDetectionMixin extends SettingsMixinDeviceBase<VideoCamera & Camera
if (!this.detectorRunning) {
break;
}
const now = Date.now();
if (now > this.analyzeStop) {
if (!this.hasMotionType && Date.now() > this.analyzeStop) {
break;
}
@@ -820,9 +818,9 @@ class ObjectDetectionPlugin extends AutoenableMixinProvider implements Settings,
{
name: 'FFmpeg Frame Generator',
type: ScryptedDeviceType.Builtin,
interfaces: [
interfaces: sharpLib ? [
ScryptedInterface.VideoFrameGenerator,
],
] : [],
nativeId: 'ffmpeg',
}
]

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/opencv",
"version": "0.0.72",
"version": "0.0.74",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/opencv",
"version": "0.0.72",
"version": "0.0.74",
"devDependencies": {
"@scrypted/sdk": "file:../../sdk"
}

View File

@@ -36,5 +36,5 @@
"devDependencies": {
"@scrypted/sdk": "file:../../sdk"
},
"version": "0.0.72"
"version": "0.0.74"
}

View File

@@ -1,17 +1,42 @@
from __future__ import annotations
import asyncio
import concurrent.futures
from typing import Any, List, Tuple
import cv2
import imutils
import numpy as np
import scrypted_sdk
from PIL import Image
from scrypted_sdk.types import (ObjectDetectionGeneratorSession,
ObjectDetectionResult, ObjectsDetected,
Setting, VideoFrame)
from detect import DetectPlugin
import scrypted_sdk
from scrypted_sdk.types import (ObjectDetectionGeneratorSession,
ObjectDetectionResult,
ObjectsDetected, Setting, VideoFrame)
# vips is already multithreaded, but needs to be kicked off the python asyncio thread.
toThreadExecutor = concurrent.futures.ThreadPoolExecutor(max_workers=2, thread_name_prefix="image")
async def to_thread(f):
loop = asyncio.get_running_loop()
return await loop.run_in_executor(toThreadExecutor, f)
async def ensureGrayData(data: bytes, size: Tuple[int, int], format: str):
if format == 'gray':
return data
def convert():
if format == 'rgba':
image = Image.frombuffer('RGBA', size, data)
else:
image = Image.frombuffer('RGB', size, data)
try:
return image.convert('L').tobytes()
finally:
image.close()
return await to_thread(convert)
class OpenCVDetectionSession:
@@ -34,21 +59,6 @@ defaultBlur = 5
class OpenCVPlugin(DetectPlugin):
def __init__(self, nativeId: str | None = None):
super().__init__(nativeId=nativeId)
self.color2Gray = None
self.pixelFormat = "I420"
self.pixelFormatChannelCount = 1
if True:
self.retainAspectRatio = False
self.color2Gray = None
self.pixelFormat = "I420"
self.pixelFormatChannelCount = 1
else:
self.retainAspectRatio = True
self.color2Gray = cv2.COLOR_BGRA2GRAY
self.pixelFormat = "BGRA"
self.pixelFormatChannelCount = 4
def getClasses(self) -> list[str]:
return ['motion']
@@ -90,9 +100,6 @@ class OpenCVPlugin(DetectPlugin):
]
return settings
def get_pixel_format(self):
return self.pixelFormat
def get_input_format(self) -> str:
return 'gray'
@@ -112,13 +119,7 @@ class OpenCVPlugin(DetectPlugin):
def detect(self, frame, settings: Any, detection_session: OpenCVDetectionSession, src_size, convert_to_src_size) -> ObjectsDetected:
area, threshold, interval, blur = self.parse_settings(settings)
# see get_detection_input_size on undocumented size requirements for GRAY8
if self.color2Gray != None:
detection_session.gray = cv2.cvtColor(
frame, self.color2Gray, dst=detection_session.gray)
gray = detection_session.gray
else:
gray = frame
gray = frame
detection_session.curFrame = cv2.GaussianBlur(
gray, (blur, blur), 0, dst=detection_session.curFrame)
@@ -245,12 +246,26 @@ class OpenCVPlugin(DetectPlugin):
'height': height,
}
format = videoFrame.format or 'gray'
buffer = await videoFrame.toBuffer({
'resize': resize,
'format': format,
})
if format == 'gray':
expectedLength = width * height
# check if resize could not be completed
if expectedLength != len(buffer):
image = Image.frombuffer('L', (videoFrame.width, videoFrame.height), buffer)
try:
buffer = image.resize((width, height), Image.BILINEAR).tobytes()
finally:
image.close()
else:
buffer = await ensureGrayData(buffer, (width, height), format)
def convert_to_src_size(point):
return point[0] * scale, point[1] * scale
mat = np.ndarray((height, width, self.pixelFormatChannelCount), buffer=buffer, dtype=np.uint8)
detections = self.detect(mat, settings, detection_session, (width, height), convert_to_src_size)
mat = np.ndarray((height, width, 1), buffer=buffer, dtype=np.uint8)
detections = self.detect(mat, settings, detection_session, (videoFrame.width, videoFrame.height), convert_to_src_size)
return detections

View File

@@ -5,4 +5,4 @@ Pillow>=5.4.1; sys_platform != 'linux' or platform_machine != 'x86_64'
pillow-simd; sys_platform == 'linux' and platform_machine == 'x86_64'
imutils>=0.5.0
# not available on armhf
opencv-python; sys_platform != 'linux' or platform_machine == 'x86_64'
opencv-python; sys_platform != 'linux' or platform_machine == 'x86_64'

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/python-codecs",
"version": "0.1.25",
"version": "0.1.27",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@scrypted/python-codecs",
"version": "0.1.25",
"version": "0.1.27",
"devDependencies": {
"@scrypted/sdk": "file:../../sdk"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/python-codecs",
"version": "0.1.25",
"version": "0.1.27",
"description": "Python Codecs for Scrypted",
"keywords": [
"scrypted",

View File

@@ -37,7 +37,8 @@ class PILImage(scrypted_sdk.VideoFrame):
def save():
bytesArray = io.BytesIO()
pilImage.pilImage.save(bytesArray, format=options['format'])
pilImage.pilImage.save(bytesArray, format='JPEG')
# pilImage.pilImage.save(bytesArray, format=options['format'])
return bytesArray.getvalue()
return await to_thread(lambda: save())

View File

@@ -31,6 +31,10 @@ class VipsImage(scrypted_sdk.VideoFrame):
mem = memoryview(rgb.write_to_memory())
return mem
return await to_thread(format)
elif options['format'] == 'gray':
def format():
return memoryview(vipsImage.vipsImage.write_to_memory())
return await to_thread(format)
return await to_thread(lambda: vipsImage.vipsImage.write_to_buffer('.' + options['format']))

View File

@@ -1,4 +1,4 @@
{
"scrypted.debugHost": "koushik-ubuntu",
"scrypted.debugHost": "127.0.0.1",
}

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/ring",
"version": "0.0.106",
"version": "0.0.107",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@scrypted/ring",
"version": "0.0.106",
"version": "0.0.107",
"dependencies": {
"@koush/ring-client-api": "file:../../external/ring-client-api",
"@scrypted/common": "file:../../common",

View File

@@ -44,5 +44,5 @@
"got": "11.8.6",
"socket.io-client": "^2.5.0"
},
"version": "0.0.106"
"version": "0.0.107"
}

View File

@@ -702,7 +702,6 @@ export class RingCameraDevice extends ScryptedDeviceBase implements DeviceProvid
}
async getVideoClips(options?: VideoClipOptions): Promise<VideoClip[]> {
this.videoClips = new Map<string, VideoClip>;
const response = await this.camera.videoSearch({
dateFrom: options.startTime,
dateTo: options.endTime,

View File

@@ -75,6 +75,3 @@ class DetectPlugin(scrypted_sdk.ScryptedDeviceBase, ObjectDetection):
vf = await scrypted_sdk.mediaManager.convertMediaObjectToBuffer(mediaObject, ScryptedMimeTypes.Image.value)
return await self.run_detection_videoframe(vf, session)
def get_pixel_format(self):
return 'RGB'

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/webrtc",
"version": "0.1.38",
"version": "0.1.39",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/webrtc",
"version": "0.1.38",
"version": "0.1.39",
"dependencies": {
"@scrypted/common": "file:../../common",
"@scrypted/sdk": "file:../../sdk",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/webrtc",
"version": "0.1.38",
"version": "0.1.39",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",
"prescrypted-setup-project": "scrypted-package-json",

View File

@@ -4,7 +4,7 @@ import { Deferred } from "@scrypted/common/src/deferred";
import sdk, { FFmpegInput, FFmpegTranscodeStream, Intercom, MediaObject, MediaStreamDestination, MediaStreamFeedback, RequestMediaStream, RTCAVSignalingSetup, RTCConnectionManagement, RTCMediaObjectTrack, RTCSignalingOptions, RTCSignalingSession, ScryptedDevice, ScryptedMimeTypes } from "@scrypted/sdk";
import { ScryptedSessionControl } from "./session-control";
import { requiredAudioCodecs, requiredVideoCodec } from "./webrtc-required-codecs";
import { logIsPrivateIceTransport } from "./werift-util";
import { isPrivateIceTransport, logIsPrivateIceTransport } from "./werift-util";
import { addVideoFilterArguments } from "@scrypted/common/src/ffmpeg-helpers";
import { connectRTCSignalingClients } from "@scrypted/common/src/rtc-signaling";
@@ -431,10 +431,6 @@ export class WebRTCConnectionManagement implements RTCConnectionManagement {
waitConnected(this.pc)
.then(() => logIsPrivateIceTransport(this.console, this.pc)).catch(() => {});
this.pc.signalingStateChange.subscribe(() => {
this.console.log('sig change', this.pc.signalingState);
})
this.weriftSignalingSession = new WeriftSignalingSession(console, this.pc);
}
@@ -469,7 +465,7 @@ export class WebRTCConnectionManagement implements RTCConnectionManagement {
createTrackForwarder: async (videoTransceiver: RTCRtpTransceiver, audioTransceiver: RTCRtpTransceiver) => {
const ret = await createTrackForwarder({
timeStart,
...logIsPrivateIceTransport(console, this.pc),
...isPrivateIceTransport(this.pc),
requestMediaStream,
videoTransceiver,
audioTransceiver,
@@ -582,7 +578,7 @@ export async function createRTCPeerConnectionSink(
clientOffer = true,
) {
const clientOptions = await clientSignalingSession.getOptions();
console.log('remote options', clientOptions);
// console.log('remote options', clientOptions);
const connection = new WebRTCConnectionManagement(console, clientSignalingSession, maximumCompatibilityMode, clientOptions, {
configuration,

View File

@@ -223,6 +223,10 @@ export class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreat
type: 'textarea',
description: "RTCConfiguration that can be used to specify custom TURN and STUN servers. https://gist.github.com/koush/631d38ac8647a86baaac7b22d863f010",
},
debugLog: {
title: 'Debug Log',
type: 'boolean',
}
});
bridge: WebRTCBridge;
activeConnections = 0;

View File

@@ -42,20 +42,15 @@ export function getWeriftIceServers(configuration: RTCConfiguration): RTCIceServ
return ret;
}
export function logIsPrivateIceTransport(console: Console, pc: RTCPeerConnection) {
export function isPrivateIceTransport(pc: RTCPeerConnection) {
let isPrivate = true;
let destinationId: string;
for (const ice of pc.iceTransports) {
const [address, port] = (ice.connection as any).nominated[1].remoteAddr;
if (!destinationId)
destinationId = address;
const { turnServer } = ice.connection;
isPrivate = isPrivate && ip.isPrivate(address);
console.log('ice transport ip', {
address,
port,
turnServer: !!turnServer,
});
}
console.log('Connection is local network:', isPrivate);
const ipv4 = ip.isV4Format(destinationId);
@@ -65,3 +60,10 @@ export function logIsPrivateIceTransport(console: Console, pc: RTCPeerConnection
destinationId,
};
}
export function logIsPrivateIceTransport(console: Console, pc: RTCPeerConnection) {
const ret = isPrivateIceTransport(pc);
console.log('ice transport', ret);
console.log('Connection is local network:', ret.isPrivate);
return ret;
}

4
sdk/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/sdk",
"version": "0.2.85",
"version": "0.2.86",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/sdk",
"version": "0.2.85",
"version": "0.2.86",
"license": "ISC",
"dependencies": {
"@babel/preset-typescript": "^7.18.6",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/sdk",
"version": "0.2.85",
"version": "0.2.86",
"description": "",
"main": "dist/src/index.js",
"exports": {

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/types",
"version": "0.2.77",
"version": "0.2.78",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/types",
"version": "0.2.77",
"version": "0.2.78",
"license": "ISC",
"devDependencies": {
"@types/rimraf": "^3.0.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/types",
"version": "0.2.77",
"version": "0.2.78",
"description": "",
"main": "dist/index.js",
"author": "",

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/server",
"version": "0.7.39",
"version": "0.7.41",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/server",
"version": "0.7.39",
"version": "0.7.41",
"license": "ISC",
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.10",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/server",
"version": "0.7.41",
"version": "0.7.42",
"description": "",
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.10",

View File

@@ -384,10 +384,9 @@ class PluginRemote:
if platform.machine() == 'aarch64' and platform.architecture()[0] == '32bit':
print('=============================================')
print('Python machine vs architecture mismatch detected. Plugin installation may fail.')
print('If Scrypted is running in docker, the docker version may be 32bit while the host kernel is 64bit.')
print('This may be resolved by reinstalling a 64bit docker.')
print('The docker architecture can be checked with the command: "file $(which docker)"')
print('The host architecture can be checked with: "uname -m"')
print('This issue occurs if a 32bit system was upgraded to a 64bit kernel.')
print('Reverting to the 32bit kernel (or reflashing as native 64 bit is recommended.')
print('https://github.com/koush/scrypted/issues/678')
print('=============================================')
python_version = 'python%s' % str(