@apocaliss92/scrypted-reolink-native 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -1
- package/dist/main.nodejs.js +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/baichuan-base.ts +1 -1
- package/src/camera-battery.ts +16 -12
- package/src/common.ts +1 -1
- package/src/stream-utils.ts +18 -7
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/baichuan-base.ts
CHANGED
|
@@ -35,7 +35,7 @@ export class BaichuanLogger implements Console {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
private formatMessage(level: string, ...args: any[]): string {
|
|
38
|
-
const timestamp = new Date().
|
|
38
|
+
const timestamp = new Date().toLocaleString();
|
|
39
39
|
const prefix = `[${this.deviceName}] [${timestamp}] [${level}]`;
|
|
40
40
|
return `${prefix} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`;
|
|
41
41
|
}
|
package/src/camera-battery.ts
CHANGED
|
@@ -36,16 +36,19 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async takePicture(options?: RequestPictureOptions): Promise<MediaObject> {
|
|
39
|
+
const logger = this.getBaichuanLogger();
|
|
39
40
|
// Allow new snapshot if:
|
|
40
41
|
// 1. forceNewSnapshot is true, OR
|
|
41
42
|
// 2. Camera is awake AND last snapshot was taken at least 10 seconds ago
|
|
42
|
-
const minSnapshotIntervalMs = 10_000; // 10 seconds
|
|
43
|
-
const now = Date.now();
|
|
44
|
-
const shouldTakeNewSnapshot = this.forceNewSnapshot
|
|
45
|
-
|
|
43
|
+
// const minSnapshotIntervalMs = 10_000; // 10 seconds
|
|
44
|
+
// const now = Date.now();
|
|
45
|
+
const shouldTakeNewSnapshot = this.forceNewSnapshot;
|
|
46
|
+
// const now = Date.now();
|
|
47
|
+
// const shouldTakeNewSnapshot = this.forceNewSnapshot ||
|
|
48
|
+
// (!this.sleeping && this.lastPicture && (now - this.lastPicture.atMs >= minSnapshotIntervalMs));
|
|
46
49
|
|
|
47
50
|
if (!shouldTakeNewSnapshot && this.lastPicture) {
|
|
48
|
-
|
|
51
|
+
logger.debug(`Returning cached snapshot, taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
|
|
49
52
|
return this.lastPicture.mo;
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -53,7 +56,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
53
56
|
return await this.takePictureInFlight;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
logger.log(`Taking new snapshot from camera (forceNewSnapshot: ${this.forceNewSnapshot})`);
|
|
57
60
|
this.forceNewSnapshot = false;
|
|
58
61
|
|
|
59
62
|
this.takePictureInFlight = (async () => {
|
|
@@ -63,7 +66,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
63
66
|
});
|
|
64
67
|
const mo = await sdk.mediaManager.createMediaObject(snapshotBuffer, 'image/jpeg');
|
|
65
68
|
this.lastPicture = { mo, atMs: Date.now() };
|
|
66
|
-
|
|
69
|
+
logger.log(`Snapshot taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
|
|
67
70
|
return mo;
|
|
68
71
|
})();
|
|
69
72
|
|
|
@@ -104,9 +107,10 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
104
107
|
|
|
105
108
|
private startPeriodicTasks(): void {
|
|
106
109
|
if (this.periodicStarted) return;
|
|
110
|
+
const logger = this.getBaichuanLogger();
|
|
107
111
|
this.periodicStarted = true;
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
logger.log('Starting periodic tasks for battery camera');
|
|
110
114
|
|
|
111
115
|
// Check sleeping state every 5 seconds (non-blocking)
|
|
112
116
|
if (!this.nvrDevice) {
|
|
@@ -117,7 +121,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
117
121
|
|
|
118
122
|
if (!api) {
|
|
119
123
|
if (!this.sleeping) {
|
|
120
|
-
|
|
124
|
+
logger.log('Camera is sleeping: no active Baichuan client');
|
|
121
125
|
this.sleeping = true;
|
|
122
126
|
}
|
|
123
127
|
return;
|
|
@@ -126,7 +130,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
126
130
|
const sleepStatus = api.getSleepStatus({ channel });
|
|
127
131
|
await this.updateSleepingState(sleepStatus);
|
|
128
132
|
} catch (e) {
|
|
129
|
-
|
|
133
|
+
logger.warn('Error checking sleeping state:', e);
|
|
130
134
|
}
|
|
131
135
|
}, 5_000);
|
|
132
136
|
}
|
|
@@ -138,7 +142,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
138
142
|
this.updateBatteryAndSnapshot().catch(() => { });
|
|
139
143
|
}, updateIntervalMs);
|
|
140
144
|
|
|
141
|
-
|
|
145
|
+
logger.log(`Periodic tasks started: sleep check every 5s, battery update every ${batteryUpdateIntervalMinutes} minutes`);
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
async updateSleepingState(sleepStatus: SleepStatus): Promise<void> {
|
|
@@ -182,7 +186,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
182
186
|
|
|
183
187
|
const batteryInfo = await api.getBatteryInfo(channel);
|
|
184
188
|
if (this.isBatteryInfoLoggingEnabled()) {
|
|
185
|
-
|
|
189
|
+
this.getBaichuanLogger().debug('getBatteryInfo result:', JSON.stringify(batteryInfo));
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
if (batteryInfo.batteryPercent !== undefined) {
|
package/src/common.ts
CHANGED
package/src/stream-utils.ts
CHANGED
|
@@ -12,6 +12,7 @@ import sdk, {
|
|
|
12
12
|
} from "@scrypted/sdk";
|
|
13
13
|
|
|
14
14
|
import type { UrlMediaStreamOptions } from "../../scrypted/plugins/rtsp/src/rtsp";
|
|
15
|
+
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
15
16
|
|
|
16
17
|
export interface StreamManagerOptions {
|
|
17
18
|
/**
|
|
@@ -101,12 +102,12 @@ export async function buildVideoStreamOptionsFromRtspRtmp(
|
|
|
101
102
|
client: ReolinkBaichuanApi,
|
|
102
103
|
ipAddress: string,
|
|
103
104
|
cachedNetPort: { rtsp?: { port?: number; enable?: number }; rtmp?: { port?: number; enable?: number } },
|
|
104
|
-
|
|
105
|
+
nvrDevice?: ReolinkNativeNvrDevice,
|
|
105
106
|
rtspChannel: number,
|
|
106
107
|
logger: Console
|
|
107
108
|
},
|
|
108
109
|
): Promise<UrlMediaStreamOptions[]> {
|
|
109
|
-
const { client, ipAddress, cachedNetPort, rtspChannel, logger } = props;
|
|
110
|
+
const { client, ipAddress, cachedNetPort, rtspChannel, logger, nvrDevice } = props;
|
|
110
111
|
const rtspStreams: UrlMediaStreamOptions[] = [];
|
|
111
112
|
const rtmpStreams: UrlMediaStreamOptions[] = [];
|
|
112
113
|
|
|
@@ -179,11 +180,21 @@ export async function buildVideoStreamOptionsFromRtspRtmp(
|
|
|
179
180
|
|
|
180
181
|
const nativeStreams = await fetchVideoStreamOptionsFromApi(client, rtspChannel, logger);
|
|
181
182
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
let streams: UrlMediaStreamOptions[] = [];
|
|
184
|
+
|
|
185
|
+
if (nvrDevice && nvrDevice.info.model === 'HOMEHUB') {
|
|
186
|
+
streams = [
|
|
187
|
+
...nativeStreams,
|
|
188
|
+
...rtspStreams,
|
|
189
|
+
...rtmpStreams,
|
|
190
|
+
];
|
|
191
|
+
} else {
|
|
192
|
+
streams = [
|
|
193
|
+
...rtspStreams,
|
|
194
|
+
...rtmpStreams,
|
|
195
|
+
...nativeStreams,
|
|
196
|
+
];
|
|
197
|
+
}
|
|
187
198
|
|
|
188
199
|
return streams;
|
|
189
200
|
}
|