@apocaliss92/nodelink-js 0.1.7 → 0.1.9
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/README.md +9 -6
- package/dist/{DiagnosticsTools-MTXG65O3.js → DiagnosticsTools-EC7DADEQ.js} +2 -2
- package/dist/{chunk-MC2BRLLE.js → chunk-TZFZ5WJX.js} +71 -9
- package/dist/chunk-TZFZ5WJX.js.map +1 -0
- package/dist/{chunk-JMT75JNG.js → chunk-YUBYINJF.js} +674 -64
- package/dist/chunk-YUBYINJF.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +740 -68
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.d.cts +1 -0
- package/dist/cli/rtsp-server.d.ts +1 -0
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +3293 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8187 -0
- package/dist/index.d.ts +761 -1
- package/dist/index.js +2359 -5
- package/dist/index.js.map +1 -1
- package/package.json +14 -3
- package/dist/chunk-JMT75JNG.js.map +0 -1
- package/dist/chunk-MC2BRLLE.js.map +0 -1
- /package/dist/{DiagnosticsTools-MTXG65O3.js.map → DiagnosticsTools-EC7DADEQ.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -919,6 +919,84 @@ export declare type BaichuanHeader = {
|
|
|
919
919
|
payloadOffset?: number;
|
|
920
920
|
};
|
|
921
921
|
|
|
922
|
+
export declare class BaichuanHlsServer extends EventEmitter {
|
|
923
|
+
private readonly api;
|
|
924
|
+
private readonly channel;
|
|
925
|
+
private readonly profile;
|
|
926
|
+
private readonly variant;
|
|
927
|
+
private readonly segmentDuration;
|
|
928
|
+
private readonly playlistSize;
|
|
929
|
+
private readonly ffmpegPath;
|
|
930
|
+
private readonly log;
|
|
931
|
+
private outputDir;
|
|
932
|
+
private createdTempDir;
|
|
933
|
+
private playlistPath;
|
|
934
|
+
private segmentPattern;
|
|
935
|
+
private state;
|
|
936
|
+
private codec;
|
|
937
|
+
private framesReceived;
|
|
938
|
+
private ffmpeg;
|
|
939
|
+
private nativeStream;
|
|
940
|
+
private pumpPromise;
|
|
941
|
+
private startedAt;
|
|
942
|
+
private lastError;
|
|
943
|
+
constructor(options: BaichuanHlsServerOptions);
|
|
944
|
+
/**
|
|
945
|
+
* Start HLS streaming
|
|
946
|
+
*/
|
|
947
|
+
start(): Promise<void>;
|
|
948
|
+
/**
|
|
949
|
+
* Stop HLS streaming
|
|
950
|
+
*/
|
|
951
|
+
stop(): Promise<void>;
|
|
952
|
+
/**
|
|
953
|
+
* Get current status
|
|
954
|
+
*/
|
|
955
|
+
getStatus(): HlsServerStatus;
|
|
956
|
+
/**
|
|
957
|
+
* Get playlist file path
|
|
958
|
+
*/
|
|
959
|
+
getPlaylistPath(): string | null;
|
|
960
|
+
/**
|
|
961
|
+
* Get output directory
|
|
962
|
+
*/
|
|
963
|
+
getOutputDir(): string | null;
|
|
964
|
+
/**
|
|
965
|
+
* Check if playlist file exists
|
|
966
|
+
*/
|
|
967
|
+
waitForPlaylist(timeoutMs?: number): Promise<boolean>;
|
|
968
|
+
/**
|
|
969
|
+
* Read an HLS asset (playlist or segment)
|
|
970
|
+
*/
|
|
971
|
+
readAsset(assetName: string): Promise<{
|
|
972
|
+
data: Buffer;
|
|
973
|
+
contentType: string;
|
|
974
|
+
} | null>;
|
|
975
|
+
private pumpNativeToFfmpeg;
|
|
976
|
+
private spawnFfmpeg;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
export declare interface BaichuanHlsServerOptions {
|
|
980
|
+
/** API instance (required) */
|
|
981
|
+
api: ReolinkBaichuanApi;
|
|
982
|
+
/** Channel number (required) */
|
|
983
|
+
channel: number;
|
|
984
|
+
/** Stream profile (required) */
|
|
985
|
+
profile: StreamProfile;
|
|
986
|
+
/** Native-only: TrackMix tele/autotrack variants */
|
|
987
|
+
variant?: NativeVideoStreamVariant;
|
|
988
|
+
/** Output directory for HLS segments. If not provided, a temp directory will be created. */
|
|
989
|
+
outputDir?: string;
|
|
990
|
+
/** HLS segment duration in seconds (default: 2) */
|
|
991
|
+
segmentDuration?: number;
|
|
992
|
+
/** Number of segments to keep in playlist (default: 5) */
|
|
993
|
+
playlistSize?: number;
|
|
994
|
+
/** ffmpeg binary path (default: "ffmpeg") */
|
|
995
|
+
ffmpegPath?: string;
|
|
996
|
+
/** Logger callback */
|
|
997
|
+
logger?: (level: "debug" | "info" | "warn" | "error", message: string) => void;
|
|
998
|
+
}
|
|
999
|
+
|
|
922
1000
|
/**
|
|
923
1001
|
* BaichuanHttpStreamServer - HTTP server that serves a Baichuan video stream as MPEG-TS.
|
|
924
1002
|
*
|
|
@@ -980,6 +1058,106 @@ export declare type BaichuanLedState = {
|
|
|
980
1058
|
lightState?: string;
|
|
981
1059
|
};
|
|
982
1060
|
|
|
1061
|
+
/**
|
|
1062
|
+
* BaichuanMjpegServer - MJPEG HTTP server for Baichuan video streams
|
|
1063
|
+
*
|
|
1064
|
+
* Events:
|
|
1065
|
+
* - 'started': Server started
|
|
1066
|
+
* - 'stopped': Server stopped
|
|
1067
|
+
* - 'client-connected': Client connected
|
|
1068
|
+
* - 'client-disconnected': Client disconnected
|
|
1069
|
+
* - 'error': Error occurred
|
|
1070
|
+
*/
|
|
1071
|
+
export declare class BaichuanMjpegServer extends EventEmitter {
|
|
1072
|
+
private readonly options;
|
|
1073
|
+
private readonly clients;
|
|
1074
|
+
private httpServer;
|
|
1075
|
+
private transformer;
|
|
1076
|
+
private nativeStream;
|
|
1077
|
+
private streamPump;
|
|
1078
|
+
private detectedCodec;
|
|
1079
|
+
private started;
|
|
1080
|
+
private clientIdCounter;
|
|
1081
|
+
constructor(options: BaichuanMjpegServerOptions);
|
|
1082
|
+
/**
|
|
1083
|
+
* Start the MJPEG server
|
|
1084
|
+
*/
|
|
1085
|
+
start(): Promise<void>;
|
|
1086
|
+
/**
|
|
1087
|
+
* Stop the MJPEG server
|
|
1088
|
+
*/
|
|
1089
|
+
stop(): Promise<void>;
|
|
1090
|
+
/**
|
|
1091
|
+
* Handle HTTP request
|
|
1092
|
+
*/
|
|
1093
|
+
private handleRequest;
|
|
1094
|
+
/**
|
|
1095
|
+
* Handle new MJPEG client
|
|
1096
|
+
*/
|
|
1097
|
+
private handleMjpegClient;
|
|
1098
|
+
/**
|
|
1099
|
+
* Start the native video stream and MJPEG transformer
|
|
1100
|
+
*/
|
|
1101
|
+
private startStream;
|
|
1102
|
+
/**
|
|
1103
|
+
* Pump native stream and feed to transformer
|
|
1104
|
+
*/
|
|
1105
|
+
private pumpStream;
|
|
1106
|
+
/**
|
|
1107
|
+
* Initialize MJPEG transformer once codec is detected
|
|
1108
|
+
*/
|
|
1109
|
+
private initTransformer;
|
|
1110
|
+
/**
|
|
1111
|
+
* Broadcast JPEG frame to all connected clients
|
|
1112
|
+
*/
|
|
1113
|
+
private broadcastFrame;
|
|
1114
|
+
/**
|
|
1115
|
+
* Stop the stream and transformer
|
|
1116
|
+
*/
|
|
1117
|
+
private stopStream;
|
|
1118
|
+
/**
|
|
1119
|
+
* Get current number of connected clients
|
|
1120
|
+
*/
|
|
1121
|
+
getClientCount(): number;
|
|
1122
|
+
/**
|
|
1123
|
+
* Get server status
|
|
1124
|
+
*/
|
|
1125
|
+
getStatus(): {
|
|
1126
|
+
running: boolean;
|
|
1127
|
+
clients: number;
|
|
1128
|
+
codec: string | null;
|
|
1129
|
+
frames: number;
|
|
1130
|
+
};
|
|
1131
|
+
private log;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
export declare interface BaichuanMjpegServerOptions {
|
|
1135
|
+
/** API instance (required) */
|
|
1136
|
+
api: ReolinkBaichuanApi;
|
|
1137
|
+
/** Channel number (required) */
|
|
1138
|
+
channel: number;
|
|
1139
|
+
/** Stream profile (required) */
|
|
1140
|
+
profile: StreamProfile;
|
|
1141
|
+
/** Native-only: TrackMix tele/autotrack variants */
|
|
1142
|
+
variant?: NativeVideoStreamVariant;
|
|
1143
|
+
/** HTTP server port (default: 8080) */
|
|
1144
|
+
port?: number;
|
|
1145
|
+
/** HTTP server host (default: "0.0.0.0") */
|
|
1146
|
+
host?: string;
|
|
1147
|
+
/** URL path for MJPEG stream (default: "/mjpeg") */
|
|
1148
|
+
path?: string;
|
|
1149
|
+
/** JPEG quality (1-31, lower is better, default: 5) */
|
|
1150
|
+
quality?: number;
|
|
1151
|
+
/** Output width (optional) */
|
|
1152
|
+
width?: number;
|
|
1153
|
+
/** Output height (optional) */
|
|
1154
|
+
height?: number;
|
|
1155
|
+
/** Max FPS (optional) */
|
|
1156
|
+
maxFps?: number;
|
|
1157
|
+
/** Logger callback */
|
|
1158
|
+
logger?: (level: "debug" | "info" | "warn" | "error", message: string) => void;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
983
1161
|
export declare type BaichuanNetInfoPush = {
|
|
984
1162
|
netType?: string;
|
|
985
1163
|
signal?: number;
|
|
@@ -1376,6 +1554,133 @@ export declare interface BaichuanVideoStreamOptions {
|
|
|
1376
1554
|
acceptAnyStreamType?: boolean;
|
|
1377
1555
|
}
|
|
1378
1556
|
|
|
1557
|
+
/**
|
|
1558
|
+
* BaichuanWebRTCServer - WebRTC server for Baichuan video streams
|
|
1559
|
+
*
|
|
1560
|
+
* Events:
|
|
1561
|
+
* - 'session-created': New session created
|
|
1562
|
+
* - 'session-connected': Session connected (ICE complete)
|
|
1563
|
+
* - 'session-closed': Session closed
|
|
1564
|
+
* - 'intercom-started': Intercom started for session
|
|
1565
|
+
* - 'intercom-stopped': Intercom stopped for session
|
|
1566
|
+
* - 'error': Error occurred
|
|
1567
|
+
*/
|
|
1568
|
+
export declare class BaichuanWebRTCServer extends EventEmitter {
|
|
1569
|
+
private readonly options;
|
|
1570
|
+
private readonly sessions;
|
|
1571
|
+
private sessionIdCounter;
|
|
1572
|
+
private weriftModule;
|
|
1573
|
+
constructor(options: BaichuanWebRTCServerOptions);
|
|
1574
|
+
/**
|
|
1575
|
+
* Initialize werift module (lazy load to avoid requiring it if not used)
|
|
1576
|
+
*/
|
|
1577
|
+
private loadWerift;
|
|
1578
|
+
/**
|
|
1579
|
+
* Create a new WebRTC session
|
|
1580
|
+
* Returns a session ID and SDP offer to send to the browser
|
|
1581
|
+
*/
|
|
1582
|
+
createSession(): Promise<{
|
|
1583
|
+
sessionId: string;
|
|
1584
|
+
offer: WebRTCOffer;
|
|
1585
|
+
}>;
|
|
1586
|
+
/**
|
|
1587
|
+
* Handle WebRTC answer from browser and start streaming
|
|
1588
|
+
*/
|
|
1589
|
+
handleAnswer(sessionId: string, answer: WebRTCAnswer): Promise<void>;
|
|
1590
|
+
/**
|
|
1591
|
+
* Add ICE candidate from browser
|
|
1592
|
+
*/
|
|
1593
|
+
addIceCandidate(sessionId: string, candidate: WebRTCIceCandidate): Promise<void>;
|
|
1594
|
+
/**
|
|
1595
|
+
* Close a WebRTC session
|
|
1596
|
+
*/
|
|
1597
|
+
closeSession(sessionId: string): Promise<void>;
|
|
1598
|
+
/**
|
|
1599
|
+
* Get information about all active sessions
|
|
1600
|
+
*/
|
|
1601
|
+
getSessions(): WebRTCSessionInfo[];
|
|
1602
|
+
/**
|
|
1603
|
+
* Get information about a specific session
|
|
1604
|
+
*/
|
|
1605
|
+
getSession(sessionId: string): WebRTCSessionInfo | null;
|
|
1606
|
+
/**
|
|
1607
|
+
* Close all sessions and stop the server
|
|
1608
|
+
*/
|
|
1609
|
+
stop(): Promise<void>;
|
|
1610
|
+
/**
|
|
1611
|
+
* Get the number of active sessions
|
|
1612
|
+
*/
|
|
1613
|
+
get sessionCount(): number;
|
|
1614
|
+
/**
|
|
1615
|
+
* Wait for ICE gathering to complete
|
|
1616
|
+
*/
|
|
1617
|
+
private waitForIceGathering;
|
|
1618
|
+
/**
|
|
1619
|
+
* Start native Baichuan stream and pump frames to WebRTC
|
|
1620
|
+
*/
|
|
1621
|
+
private startNativeStream;
|
|
1622
|
+
/**
|
|
1623
|
+
* Pump frames from native stream to WebRTC tracks
|
|
1624
|
+
* H.264 → RTP media track (standard WebRTC)
|
|
1625
|
+
* H.265 → DataChannel with raw Annex-B frames (decoded by WebCodecs in browser)
|
|
1626
|
+
*/
|
|
1627
|
+
private pumpFramesToWebRTC;
|
|
1628
|
+
/**
|
|
1629
|
+
* Send H.264 frame via RTP media track
|
|
1630
|
+
* Returns the number of RTP packets sent
|
|
1631
|
+
*/
|
|
1632
|
+
private sendH264Frame;
|
|
1633
|
+
/**
|
|
1634
|
+
* Send video frame via DataChannel (works for both H.264 and H.265)
|
|
1635
|
+
* Format: 12-byte header + Annex-B data
|
|
1636
|
+
* Header: [frameNum (4)] [timestamp (4)] [flags (1)] [keyframe (1)] [reserved (2)]
|
|
1637
|
+
* Flags: 0x01 = H.265, 0x02 = H.264
|
|
1638
|
+
*/
|
|
1639
|
+
private sendVideoFrameViaDataChannel;
|
|
1640
|
+
/**
|
|
1641
|
+
* Send H.265 frame via DataChannel
|
|
1642
|
+
* Format: 12-byte header + Annex-B data
|
|
1643
|
+
* Header: [frameNum (4)] [timestamp (4)] [flags (1)] [keyframe (1)] [reserved (2)]
|
|
1644
|
+
*/
|
|
1645
|
+
private sendH265Frame;
|
|
1646
|
+
/**
|
|
1647
|
+
* Create RTP packets for H.264 NAL unit
|
|
1648
|
+
* Handles single NAL, STAP-A aggregation, and FU-A fragmentation
|
|
1649
|
+
*/
|
|
1650
|
+
private createH264RtpPackets;
|
|
1651
|
+
/**
|
|
1652
|
+
* Start intercom (two-way audio)
|
|
1653
|
+
*/
|
|
1654
|
+
private startIntercom;
|
|
1655
|
+
/**
|
|
1656
|
+
* Log helper
|
|
1657
|
+
*/
|
|
1658
|
+
private log;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
export declare interface BaichuanWebRTCServerOptions {
|
|
1662
|
+
/** API instance (required) */
|
|
1663
|
+
api: ReolinkBaichuanApi;
|
|
1664
|
+
/** Channel number (required) */
|
|
1665
|
+
channel: number;
|
|
1666
|
+
/** Stream profile (required) */
|
|
1667
|
+
profile: StreamProfile;
|
|
1668
|
+
/** Native-only: TrackMix tele/autotrack variants */
|
|
1669
|
+
variant?: NativeVideoStreamVariant;
|
|
1670
|
+
/** Enable two-way audio intercom (default: false) */
|
|
1671
|
+
enableIntercom?: boolean;
|
|
1672
|
+
/** STUN servers for ICE (default: Google STUN) */
|
|
1673
|
+
stunServers?: string[];
|
|
1674
|
+
/** TURN servers for NAT traversal (optional) */
|
|
1675
|
+
turnServers?: Array<{
|
|
1676
|
+
urls: string;
|
|
1677
|
+
username?: string;
|
|
1678
|
+
credential?: string;
|
|
1679
|
+
}>;
|
|
1680
|
+
/** Logger callback */
|
|
1681
|
+
logger?: (level: "debug" | "info" | "warn" | "error", message: string) => void;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1379
1684
|
export declare type BaichuanWifi = {
|
|
1380
1685
|
protocol?: number;
|
|
1381
1686
|
mode?: string;
|
|
@@ -1959,6 +2264,14 @@ export declare function buildChannelExtensionXml(channelId: number | string | un
|
|
|
1959
2264
|
*/
|
|
1960
2265
|
export declare function buildFloodlightManualXml(channelId: number, status: number, durationSeconds?: number): string;
|
|
1961
2266
|
|
|
2267
|
+
/**
|
|
2268
|
+
* Build the HLS redirect URL from the original request URL.
|
|
2269
|
+
*
|
|
2270
|
+
* @param originalUrl - The original request URL
|
|
2271
|
+
* @returns The URL with ?hls=playlist.m3u8 appended
|
|
2272
|
+
*/
|
|
2273
|
+
export declare function buildHlsRedirectUrl(originalUrl: string): string;
|
|
2274
|
+
|
|
1962
2275
|
export declare function buildLoginXml(userNameHash: string, passwordHash: string): string;
|
|
1963
2276
|
|
|
1964
2277
|
/**
|
|
@@ -2791,6 +3104,25 @@ export declare function createLogger(options?: {
|
|
|
2791
3104
|
tag?: string;
|
|
2792
3105
|
}): Logger_2;
|
|
2793
3106
|
|
|
3107
|
+
/**
|
|
3108
|
+
* Create an MJPEG HTTP response handler
|
|
3109
|
+
*
|
|
3110
|
+
* Usage:
|
|
3111
|
+
* ```ts
|
|
3112
|
+
* const transformer = new MjpegTransformer({ codec: "h264" });
|
|
3113
|
+
* transformer.start();
|
|
3114
|
+
*
|
|
3115
|
+
* // In your stream handler:
|
|
3116
|
+
* stream.on("accessUnit", (au) => transformer.push(au.data, au.timestamp));
|
|
3117
|
+
*
|
|
3118
|
+
* // HTTP handler:
|
|
3119
|
+
* app.get("/mjpeg", (req, res) => {
|
|
3120
|
+
* serveMjpeg(res, transformer);
|
|
3121
|
+
* });
|
|
3122
|
+
* ```
|
|
3123
|
+
*/
|
|
3124
|
+
export declare function createMjpegBoundary(): string;
|
|
3125
|
+
|
|
2794
3126
|
/**
|
|
2795
3127
|
* Stream frame data for rebroadcast.
|
|
2796
3128
|
* Similar to Wyze forkAndStream() implementation.
|
|
@@ -2923,6 +3255,22 @@ export declare type DebugOptions = {
|
|
|
2923
3255
|
};
|
|
2924
3256
|
};
|
|
2925
3257
|
|
|
3258
|
+
/**
|
|
3259
|
+
* Determine if H.265 should be transcoded to H.264 based on client capabilities.
|
|
3260
|
+
*
|
|
3261
|
+
* Decision logic:
|
|
3262
|
+
* - iOS devices (Safari): Need transcoding (no native H.265 in <video> without HLS)
|
|
3263
|
+
* - macOS Safari: Supports H.265 natively
|
|
3264
|
+
* - Chrome/Edge: Limited H.265 support, safer to transcode
|
|
3265
|
+
* - Firefox: No H.265 support, needs transcoding
|
|
3266
|
+
* - Android: Variable support, transcode for safety
|
|
3267
|
+
*
|
|
3268
|
+
* @param headers - HTTP request headers
|
|
3269
|
+
* @param forceMode - Optional override: "passthrough" or "transcode-h264"
|
|
3270
|
+
* @returns Decision with mode, reason, and client info
|
|
3271
|
+
*/
|
|
3272
|
+
export declare function decideVideoclipTranscodeMode(headers: Record<string, string | string[] | undefined>, forceMode?: VideoclipTranscodeMode): VideoclipModeDecision;
|
|
3273
|
+
|
|
2926
3274
|
export declare function decodeHeader(buf: AnyBuffer): {
|
|
2927
3275
|
header: BaichuanHeader;
|
|
2928
3276
|
headerLen: number;
|
|
@@ -2936,6 +3284,18 @@ export declare function decodeHeader(buf: AnyBuffer): {
|
|
|
2936
3284
|
*/
|
|
2937
3285
|
export declare function deriveAesKey(nonce: string, password: string): Buffer;
|
|
2938
3286
|
|
|
3287
|
+
/**
|
|
3288
|
+
* Detect if the request is from an iOS device that needs HLS.
|
|
3289
|
+
*
|
|
3290
|
+
* @param userAgent - The User-Agent header from the request
|
|
3291
|
+
* @returns Object with iOS detection results
|
|
3292
|
+
*/
|
|
3293
|
+
export declare function detectIosClient(userAgent: string | undefined): {
|
|
3294
|
+
isIos: boolean;
|
|
3295
|
+
isIosInstalledApp: boolean;
|
|
3296
|
+
needsHls: boolean;
|
|
3297
|
+
};
|
|
3298
|
+
|
|
2939
3299
|
/**
|
|
2940
3300
|
* Detect the actual video codec from raw NAL data.
|
|
2941
3301
|
* Some cameras report wrong codec (e.g. "H264" but send H.265 data).
|
|
@@ -3350,6 +3710,8 @@ declare interface FloodlightTaskState {
|
|
|
3350
3710
|
detectType?: string;
|
|
3351
3711
|
}
|
|
3352
3712
|
|
|
3713
|
+
export declare function formatMjpegFrame(frame: Buffer, boundary: string): Buffer;
|
|
3714
|
+
|
|
3353
3715
|
/**
|
|
3354
3716
|
* FTP task configuration.
|
|
3355
3717
|
*/
|
|
@@ -3378,6 +3740,8 @@ export declare function getGlobalLogger(): Logger_2;
|
|
|
3378
3740
|
*/
|
|
3379
3741
|
export declare function getH265NalType(nalPayload: Buffer): number | null;
|
|
3380
3742
|
|
|
3743
|
+
export declare function getMjpegContentType(boundary: string): string;
|
|
3744
|
+
|
|
3381
3745
|
/**
|
|
3382
3746
|
* Result of getRecordingVideo() - a fully muxed MP4 with stats.
|
|
3383
3747
|
*/
|
|
@@ -3416,6 +3780,11 @@ export declare interface GetRecordingVideoStats {
|
|
|
3416
3780
|
hasAudio: boolean;
|
|
3417
3781
|
}
|
|
3418
3782
|
|
|
3783
|
+
/**
|
|
3784
|
+
* Extract client info from HTTP request headers.
|
|
3785
|
+
*/
|
|
3786
|
+
export declare function getVideoclipClientInfo(headers: Record<string, string | string[] | undefined>): VideoclipClientInfo;
|
|
3787
|
+
|
|
3419
3788
|
/**
|
|
3420
3789
|
* Parameters for getVideoclips() recording search.
|
|
3421
3790
|
*/
|
|
@@ -3539,6 +3908,145 @@ export declare interface HddInfoListConfig {
|
|
|
3539
3908
|
};
|
|
3540
3909
|
}
|
|
3541
3910
|
|
|
3911
|
+
export declare type HlsCodec = "h264" | "h265";
|
|
3912
|
+
|
|
3913
|
+
/**
|
|
3914
|
+
* HTTP response result.
|
|
3915
|
+
*/
|
|
3916
|
+
export declare interface HlsHttpResponse {
|
|
3917
|
+
/** HTTP status code */
|
|
3918
|
+
statusCode: number;
|
|
3919
|
+
/** Response headers */
|
|
3920
|
+
headers: Record<string, string>;
|
|
3921
|
+
/** Response body (string for playlist, Buffer for segment) */
|
|
3922
|
+
body: string | Buffer;
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
export declare interface HlsServerStatus {
|
|
3926
|
+
state: "idle" | "starting" | "running" | "stopping" | "stopped" | "error";
|
|
3927
|
+
codec: HlsCodec | null;
|
|
3928
|
+
framesReceived: number;
|
|
3929
|
+
ffmpegRunning: boolean;
|
|
3930
|
+
playlistPath: string | null;
|
|
3931
|
+
outputDir: string | null;
|
|
3932
|
+
startedAt: Date | null;
|
|
3933
|
+
error: string | null;
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3936
|
+
/**
|
|
3937
|
+
* HLS session returned by createRecordingReplayHlsSession.
|
|
3938
|
+
*/
|
|
3939
|
+
export declare interface HlsSession {
|
|
3940
|
+
/** Get the current HLS playlist content (.m3u8) */
|
|
3941
|
+
getPlaylist: () => string;
|
|
3942
|
+
/** Get a segment file by name */
|
|
3943
|
+
getSegment: (name: string) => Buffer | undefined;
|
|
3944
|
+
/** List all available segment names */
|
|
3945
|
+
listSegments: () => string[];
|
|
3946
|
+
/** Wait for the HLS session to be ready */
|
|
3947
|
+
waitForReady: () => Promise<void>;
|
|
3948
|
+
/** Stop the HLS session and cleanup */
|
|
3949
|
+
stop: () => Promise<void>;
|
|
3950
|
+
/** Path to the temporary directory */
|
|
3951
|
+
tempDir: string;
|
|
3952
|
+
}
|
|
3953
|
+
|
|
3954
|
+
/**
|
|
3955
|
+
* Manages HLS sessions with caching, TTL, and HTTP response generation.
|
|
3956
|
+
*/
|
|
3957
|
+
export declare class HlsSessionManager {
|
|
3958
|
+
private readonly api;
|
|
3959
|
+
private sessions;
|
|
3960
|
+
private readonly logger;
|
|
3961
|
+
private readonly sessionTtlMs;
|
|
3962
|
+
private cleanupTimer;
|
|
3963
|
+
private creationLocks;
|
|
3964
|
+
constructor(api: ReolinkBaichuanApi, options?: HlsSessionManagerOptions);
|
|
3965
|
+
/**
|
|
3966
|
+
* Handle an HLS request and return the HTTP response.
|
|
3967
|
+
*
|
|
3968
|
+
* @param params - Request parameters
|
|
3969
|
+
* @returns HTTP response ready to be sent
|
|
3970
|
+
*/
|
|
3971
|
+
handleRequest(params: {
|
|
3972
|
+
/** Unique session key (e.g., `${deviceId}:${fileId}`) */
|
|
3973
|
+
sessionKey: string;
|
|
3974
|
+
/** HLS path: "playlist.m3u8" or segment name like "segment_001.ts" */
|
|
3975
|
+
hlsPath: string;
|
|
3976
|
+
/** Full request URL for rewriting playlist URLs */
|
|
3977
|
+
requestUrl: string;
|
|
3978
|
+
/** Function to create session params if session doesn't exist */
|
|
3979
|
+
createSession: () => Promise<HlsSessionParams> | HlsSessionParams;
|
|
3980
|
+
/**
|
|
3981
|
+
* Optional prefix used to ensure only one active HLS session per logical client.
|
|
3982
|
+
* When a new session is created, any other sessions whose keys start with this
|
|
3983
|
+
* prefix will be stopped. This prevents replay/ffmpeg queue starvation when
|
|
3984
|
+
* clients quickly switch clips.
|
|
3985
|
+
*/
|
|
3986
|
+
exclusiveKeyPrefix?: string;
|
|
3987
|
+
}): Promise<HlsHttpResponse>;
|
|
3988
|
+
private withCreationLock;
|
|
3989
|
+
/**
|
|
3990
|
+
* Check if a session exists for the given key.
|
|
3991
|
+
*/
|
|
3992
|
+
hasSession(sessionKey: string): boolean;
|
|
3993
|
+
/**
|
|
3994
|
+
* Stop a specific session.
|
|
3995
|
+
*/
|
|
3996
|
+
stopSession(sessionKey: string): Promise<void>;
|
|
3997
|
+
/**
|
|
3998
|
+
* Stop all sessions and cleanup.
|
|
3999
|
+
*/
|
|
4000
|
+
stopAll(): Promise<void>;
|
|
4001
|
+
/**
|
|
4002
|
+
* Get the number of active sessions.
|
|
4003
|
+
*/
|
|
4004
|
+
get sessionCount(): number;
|
|
4005
|
+
/**
|
|
4006
|
+
* Serve the HLS playlist with rewritten segment URLs.
|
|
4007
|
+
*/
|
|
4008
|
+
private servePlaylist;
|
|
4009
|
+
/**
|
|
4010
|
+
* Serve an HLS segment.
|
|
4011
|
+
*/
|
|
4012
|
+
private serveSegment;
|
|
4013
|
+
/**
|
|
4014
|
+
* Cleanup expired sessions.
|
|
4015
|
+
*/
|
|
4016
|
+
private cleanupExpiredSessions;
|
|
4017
|
+
private stopOtherSessionsWithPrefix;
|
|
4018
|
+
}
|
|
4019
|
+
|
|
4020
|
+
/**
|
|
4021
|
+
* Options for HlsSessionManager constructor.
|
|
4022
|
+
*/
|
|
4023
|
+
export declare interface HlsSessionManagerOptions {
|
|
4024
|
+
/** Logger instance */
|
|
4025
|
+
logger?: Logger_2;
|
|
4026
|
+
/** Session TTL in milliseconds (default: 5 minutes) */
|
|
4027
|
+
sessionTtlMs?: number;
|
|
4028
|
+
/** Cleanup interval in milliseconds (default: 30 seconds) */
|
|
4029
|
+
cleanupIntervalMs?: number;
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
/**
|
|
4033
|
+
* Parameters for creating a new HLS session.
|
|
4034
|
+
*/
|
|
4035
|
+
export declare interface HlsSessionParams {
|
|
4036
|
+
/** Channel number */
|
|
4037
|
+
channel: number;
|
|
4038
|
+
/** Recording file name/path */
|
|
4039
|
+
fileName: string;
|
|
4040
|
+
/** Whether this is an NVR recording */
|
|
4041
|
+
isNvr?: boolean;
|
|
4042
|
+
/** External device ID for dedicated socket */
|
|
4043
|
+
deviceId?: string;
|
|
4044
|
+
/** Transcode H.265 to H.264 */
|
|
4045
|
+
transcodeH265ToH264?: boolean;
|
|
4046
|
+
/** HLS segment duration in seconds */
|
|
4047
|
+
hlsSegmentDuration?: number;
|
|
4048
|
+
}
|
|
4049
|
+
|
|
3542
4050
|
/**
|
|
3543
4051
|
* Intercom - Two-way audio support for Reolink cameras via Baichuan protocol.
|
|
3544
4052
|
*
|
|
@@ -3651,6 +4159,9 @@ declare interface Logger_2 {
|
|
|
3651
4159
|
child?(tag: string): Logger_2;
|
|
3652
4160
|
}
|
|
3653
4161
|
|
|
4162
|
+
/** Logger callback type for MjpegTransformer */
|
|
4163
|
+
export declare type LoggerCallback = (level: "debug" | "info" | "warn" | "error", message: string) => void;
|
|
4164
|
+
|
|
3654
4165
|
declare type LoggerLike = Partial<Logger_2> | Console;
|
|
3655
4166
|
|
|
3656
4167
|
export declare type LoginResponseValue = {
|
|
@@ -3696,6 +4207,74 @@ export declare interface MediaStream {
|
|
|
3696
4207
|
};
|
|
3697
4208
|
}
|
|
3698
4209
|
|
|
4210
|
+
export declare interface MjpegFrame {
|
|
4211
|
+
/** JPEG data */
|
|
4212
|
+
data: Buffer;
|
|
4213
|
+
/** Timestamp in microseconds */
|
|
4214
|
+
timestamp: number;
|
|
4215
|
+
}
|
|
4216
|
+
|
|
4217
|
+
/**
|
|
4218
|
+
* MjpegTransformer - Transforms H.264/H.265 access units to JPEG frames
|
|
4219
|
+
*
|
|
4220
|
+
* Events:
|
|
4221
|
+
* - 'frame': Emitted when a JPEG frame is ready (MjpegFrame)
|
|
4222
|
+
* - 'error': Emitted on error
|
|
4223
|
+
* - 'close': Emitted when transformer is closed
|
|
4224
|
+
*/
|
|
4225
|
+
export declare class MjpegTransformer extends EventEmitter {
|
|
4226
|
+
private readonly options;
|
|
4227
|
+
private ffmpeg;
|
|
4228
|
+
private started;
|
|
4229
|
+
private closed;
|
|
4230
|
+
private jpegBuffer;
|
|
4231
|
+
private frameCount;
|
|
4232
|
+
private lastTimestamp;
|
|
4233
|
+
constructor(options: MjpegTransformerOptions);
|
|
4234
|
+
/**
|
|
4235
|
+
* Start the transformer (spawns FFmpeg process)
|
|
4236
|
+
*/
|
|
4237
|
+
start(): void;
|
|
4238
|
+
/**
|
|
4239
|
+
* Push an H.264/H.265 access unit (Annex-B format with start codes)
|
|
4240
|
+
*/
|
|
4241
|
+
push(accessUnit: Buffer, timestamp?: number): void;
|
|
4242
|
+
/**
|
|
4243
|
+
* Handle JPEG data from FFmpeg stdout
|
|
4244
|
+
* FFmpeg outputs complete JPEG images, each starting with SOI (0xFFD8)
|
|
4245
|
+
* and ending with EOI (0xFFD9)
|
|
4246
|
+
*/
|
|
4247
|
+
private handleJpegData;
|
|
4248
|
+
/**
|
|
4249
|
+
* Stop the transformer
|
|
4250
|
+
*/
|
|
4251
|
+
stop(): Promise<void>;
|
|
4252
|
+
/**
|
|
4253
|
+
* Get frame count
|
|
4254
|
+
*/
|
|
4255
|
+
getFrameCount(): number;
|
|
4256
|
+
/**
|
|
4257
|
+
* Check if running
|
|
4258
|
+
*/
|
|
4259
|
+
isRunning(): boolean;
|
|
4260
|
+
private log;
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
export declare interface MjpegTransformerOptions {
|
|
4264
|
+
/** Video codec (required) */
|
|
4265
|
+
codec: "h264" | "h265";
|
|
4266
|
+
/** JPEG quality (1-31, lower is better, default: 5) */
|
|
4267
|
+
quality?: number | undefined;
|
|
4268
|
+
/** Output width (optional, maintains aspect ratio if only one dimension set) */
|
|
4269
|
+
width?: number | undefined;
|
|
4270
|
+
/** Output height (optional, maintains aspect ratio if only one dimension set) */
|
|
4271
|
+
height?: number | undefined;
|
|
4272
|
+
/** Frame rate limit (optional, e.g., 10 for max 10 fps) */
|
|
4273
|
+
maxFps?: number | undefined;
|
|
4274
|
+
/** Logger callback */
|
|
4275
|
+
logger?: LoggerCallback | undefined;
|
|
4276
|
+
}
|
|
4277
|
+
|
|
3699
4278
|
/**
|
|
3700
4279
|
* Motion alarm configuration (getMotionAlarm response).
|
|
3701
4280
|
* cmdId=46 (GetMdAlarm)
|
|
@@ -3831,6 +4410,8 @@ export declare interface ParsedRecordingFileName {
|
|
|
3831
4410
|
durationMs: number;
|
|
3832
4411
|
/** Frame rate extracted from filename hex flags (if available) */
|
|
3833
4412
|
framerate?: number;
|
|
4413
|
+
/** File size in bytes extracted from filename (last hex field before extension) */
|
|
4414
|
+
sizeBytes?: number;
|
|
3834
4415
|
flags?: RecordingVodFlags;
|
|
3835
4416
|
rawFlags?: Record<string, number>;
|
|
3836
4417
|
animalTypeRaw?: string;
|
|
@@ -4055,6 +4636,8 @@ export declare class ReolinkBaichuanApi {
|
|
|
4055
4636
|
* Value: client, refCount, createdAt
|
|
4056
4637
|
*/
|
|
4057
4638
|
private readonly dedicatedClients;
|
|
4639
|
+
/** Keep replay dedicated sockets warm briefly to reduce clip switch latency. */
|
|
4640
|
+
private static readonly REPLAY_DEDICATED_KEEPALIVE_MS;
|
|
4058
4641
|
/**
|
|
4059
4642
|
* Get a summary of currently active dedicated sessions.
|
|
4060
4643
|
* Useful for debugging/logging to see how many sockets are open.
|
|
@@ -4176,6 +4759,17 @@ export declare class ReolinkBaichuanApi {
|
|
|
4176
4759
|
* This ensures clean teardown at the end of each clip.
|
|
4177
4760
|
*/
|
|
4178
4761
|
private releaseDedicatedClient;
|
|
4762
|
+
/**
|
|
4763
|
+
* Force-close a dedicated client if it exists.
|
|
4764
|
+
* This is called BEFORE entering the queue to immediately terminate any existing stream
|
|
4765
|
+
* for the same sessionKey. The existing stream will receive an error, release its queue slot,
|
|
4766
|
+
* and the new request can then proceed.
|
|
4767
|
+
*
|
|
4768
|
+
* @param sessionKey - The session key to force-close (e.g., `replay:${deviceId}`)
|
|
4769
|
+
* @param logger - Optional logger
|
|
4770
|
+
* @returns true if a client was closed, false if no client existed
|
|
4771
|
+
*/
|
|
4772
|
+
private forceCloseDedicatedClient;
|
|
4179
4773
|
/**
|
|
4180
4774
|
* Create a dedicated Baichuan client session for streaming.
|
|
4181
4775
|
* This is useful for consumers that need isolated socket connections per stream.
|
|
@@ -5417,11 +6011,13 @@ export declare class ReolinkBaichuanApi {
|
|
|
5417
6011
|
* @param settings - Floodlight settings to apply
|
|
5418
6012
|
*
|
|
5419
6013
|
* @example
|
|
6014
|
+
* ```typescript
|
|
5420
6015
|
* await api.setFloodlightSettings(0, {
|
|
5421
6016
|
* duration: 300, // 5 minutes
|
|
5422
6017
|
* detectType: 'people,vehicle',
|
|
5423
6018
|
* brightness: 80,
|
|
5424
6019
|
* });
|
|
6020
|
+
* ```
|
|
5425
6021
|
*/
|
|
5426
6022
|
setFloodlightSettings(channel: number | undefined, settings: {
|
|
5427
6023
|
duration?: number;
|
|
@@ -6024,6 +6620,20 @@ export declare class ReolinkBaichuanApi {
|
|
|
6024
6620
|
* Recommended: pass a unique identifier per logical device/player instance.
|
|
6025
6621
|
*/
|
|
6026
6622
|
deviceId?: string;
|
|
6623
|
+
/**
|
|
6624
|
+
* Transcode H.265/HEVC to H.264/AVC for compatibility with clients that don't support H.265.
|
|
6625
|
+
* When true and the source is H.265, ffmpeg will transcode to H.264 using libx264.
|
|
6626
|
+
* This increases CPU usage but ensures playback on iOS Safari, older browsers, etc.
|
|
6627
|
+
* Default: false (passthrough/copy).
|
|
6628
|
+
*/
|
|
6629
|
+
transcodeH265ToH264?: boolean;
|
|
6630
|
+
/**
|
|
6631
|
+
* Use MPEG-TS muxer to preserve frame timestamps (PTS).
|
|
6632
|
+
* When true, frames are muxed into MPEG-TS before being passed to ffmpeg.
|
|
6633
|
+
* This can help with variable framerate streams but may cause issues with some decoders.
|
|
6634
|
+
* Default: true (MPEG-TS muxing for proper timestamp alignment).
|
|
6635
|
+
*/
|
|
6636
|
+
useMpegTsMuxer?: boolean;
|
|
6027
6637
|
}): Promise<{
|
|
6028
6638
|
mp4: Readable;
|
|
6029
6639
|
stop: () => Promise<void>;
|
|
@@ -6067,6 +6677,98 @@ export declare class ReolinkBaichuanApi {
|
|
|
6067
6677
|
mp4: Readable;
|
|
6068
6678
|
stop: () => Promise<void>;
|
|
6069
6679
|
}>;
|
|
6680
|
+
/**
|
|
6681
|
+
* Create an HLS (HTTP Live Streaming) session for a recording.
|
|
6682
|
+
*
|
|
6683
|
+
* This method creates HLS segments on-the-fly from a recording replay stream.
|
|
6684
|
+
* HLS is required for iOS devices (Safari, Home app) which don't support
|
|
6685
|
+
* fragmented MP4 streaming well and require Range request support.
|
|
6686
|
+
*
|
|
6687
|
+
* The session writes HLS segments (.ts files) and playlist (.m3u8) to a
|
|
6688
|
+
* temporary directory. You must serve these files via HTTP to the client.
|
|
6689
|
+
*
|
|
6690
|
+
* @example
|
|
6691
|
+
* ```ts
|
|
6692
|
+
* const session = await api.createRecordingReplayHlsSession({
|
|
6693
|
+
* channel: 0,
|
|
6694
|
+
* fileName: "/mnt/sda/Mp4Record/2026-01-25/RecS03.mp4",
|
|
6695
|
+
* });
|
|
6696
|
+
*
|
|
6697
|
+
* // Serve playlist
|
|
6698
|
+
* app.get('/clip.m3u8', (req, res) => {
|
|
6699
|
+
* res.type('application/vnd.apple.mpegurl');
|
|
6700
|
+
* res.send(session.getPlaylist());
|
|
6701
|
+
* });
|
|
6702
|
+
*
|
|
6703
|
+
* // Serve segments
|
|
6704
|
+
* app.get('/segment/:name', (req, res) => {
|
|
6705
|
+
* const data = session.getSegment(req.params.name);
|
|
6706
|
+
* if (data) {
|
|
6707
|
+
* res.type('video/mp2t');
|
|
6708
|
+
* res.send(data);
|
|
6709
|
+
* } else {
|
|
6710
|
+
* res.status(404).end();
|
|
6711
|
+
* }
|
|
6712
|
+
* });
|
|
6713
|
+
*
|
|
6714
|
+
* // Cleanup when done
|
|
6715
|
+
* await session.stop();
|
|
6716
|
+
* ```
|
|
6717
|
+
*/
|
|
6718
|
+
createRecordingReplayHlsSession(params: {
|
|
6719
|
+
/** Channel number (0-based). Required. */
|
|
6720
|
+
channel: number;
|
|
6721
|
+
/** Full path to the recording file. Required. */
|
|
6722
|
+
fileName: string;
|
|
6723
|
+
/**
|
|
6724
|
+
* Force NVR mode (uses id-based XML with UID) or standalone mode (name-based XML).
|
|
6725
|
+
* If not specified, the library will detect based on device channel count.
|
|
6726
|
+
*/
|
|
6727
|
+
isNvr?: boolean;
|
|
6728
|
+
/** Optional logger override. If not provided, uses the API's logger. */
|
|
6729
|
+
logger?: Logger;
|
|
6730
|
+
/**
|
|
6731
|
+
* External identifier for the dedicated socket session.
|
|
6732
|
+
* When provided, a dedicated BaichuanClient is created/reused for this deviceId.
|
|
6733
|
+
*/
|
|
6734
|
+
deviceId?: string;
|
|
6735
|
+
/**
|
|
6736
|
+
* Transcode H.265/HEVC to H.264/AVC for compatibility.
|
|
6737
|
+
* Default: false (passthrough).
|
|
6738
|
+
*/
|
|
6739
|
+
transcodeH265ToH264?: boolean;
|
|
6740
|
+
/**
|
|
6741
|
+
* HLS segment duration in seconds. Default: 4.
|
|
6742
|
+
*/
|
|
6743
|
+
hlsSegmentDuration?: number;
|
|
6744
|
+
}): Promise<{
|
|
6745
|
+
/**
|
|
6746
|
+
* Get the current HLS playlist content (.m3u8).
|
|
6747
|
+
* Call this to serve the playlist to the client.
|
|
6748
|
+
*/
|
|
6749
|
+
getPlaylist: () => string;
|
|
6750
|
+
/**
|
|
6751
|
+
* Get a segment file by name.
|
|
6752
|
+
* Returns undefined if the segment doesn't exist yet.
|
|
6753
|
+
*/
|
|
6754
|
+
getSegment: (name: string) => Buffer | undefined;
|
|
6755
|
+
/**
|
|
6756
|
+
* List all available segment names.
|
|
6757
|
+
*/
|
|
6758
|
+
listSegments: () => string[];
|
|
6759
|
+
/**
|
|
6760
|
+
* Wait for the HLS session to be ready (at least one segment available).
|
|
6761
|
+
*/
|
|
6762
|
+
waitForReady: () => Promise<void>;
|
|
6763
|
+
/**
|
|
6764
|
+
* Stop the HLS session and cleanup.
|
|
6765
|
+
*/
|
|
6766
|
+
stop: () => Promise<void>;
|
|
6767
|
+
/**
|
|
6768
|
+
* Path to the temporary directory containing HLS files.
|
|
6769
|
+
*/
|
|
6770
|
+
tempDir: string;
|
|
6771
|
+
}>;
|
|
6070
6772
|
/**
|
|
6071
6773
|
* List recordings from a standalone camera.
|
|
6072
6774
|
*
|
|
@@ -7547,6 +8249,28 @@ export declare interface TwoWayAudioConfig {
|
|
|
7547
8249
|
mode?: "mixAudioStream" | string;
|
|
7548
8250
|
}
|
|
7549
8251
|
|
|
8252
|
+
/**
|
|
8253
|
+
* Client information extracted from HTTP request headers.
|
|
8254
|
+
* Used to determine optimal video delivery format.
|
|
8255
|
+
*/
|
|
8256
|
+
export declare type VideoclipClientInfo = {
|
|
8257
|
+
userAgent: string | undefined;
|
|
8258
|
+
accept: string | undefined;
|
|
8259
|
+
range: string | undefined;
|
|
8260
|
+
secChUa: string | undefined;
|
|
8261
|
+
secChUaMobile: string | undefined;
|
|
8262
|
+
secChUaPlatform: string | undefined;
|
|
8263
|
+
};
|
|
8264
|
+
|
|
8265
|
+
/**
|
|
8266
|
+
* Result of videoclip mode decision.
|
|
8267
|
+
*/
|
|
8268
|
+
export declare type VideoclipModeDecision = {
|
|
8269
|
+
mode: VideoclipTranscodeMode;
|
|
8270
|
+
reason: string;
|
|
8271
|
+
clientInfo: VideoclipClientInfo;
|
|
8272
|
+
};
|
|
8273
|
+
|
|
7550
8274
|
export declare type VideoclipThumbnailResult = {
|
|
7551
8275
|
/** Raw I-frame data (H.264 or H.265) */
|
|
7552
8276
|
frame: Buffer;
|
|
@@ -7560,6 +8284,13 @@ export declare type VideoclipThumbnailResult = {
|
|
|
7560
8284
|
streamInfo: PlaybackSnapshotStreamInfo;
|
|
7561
8285
|
};
|
|
7562
8286
|
|
|
8287
|
+
/**
|
|
8288
|
+
* Videoclip delivery mode.
|
|
8289
|
+
* - `passthrough`: Copy codec as-is (H.264 or H.265)
|
|
8290
|
+
* - `transcode-h264`: Transcode H.265 to H.264 for compatibility
|
|
8291
|
+
*/
|
|
8292
|
+
export declare type VideoclipTranscodeMode = "passthrough" | "transcode-h264";
|
|
8293
|
+
|
|
7563
8294
|
export declare type VideoCodec = "H.264" | "H.265" | "MJPEG" | "MPEG4" | string;
|
|
7564
8295
|
|
|
7565
8296
|
/**
|
|
@@ -7643,7 +8374,8 @@ export declare type VodFile = {
|
|
|
7643
8374
|
sec: number;
|
|
7644
8375
|
};
|
|
7645
8376
|
name: string;
|
|
7646
|
-
size
|
|
8377
|
+
/** File size in bytes - API may return as string or number */
|
|
8378
|
+
size: number | string;
|
|
7647
8379
|
};
|
|
7648
8380
|
|
|
7649
8381
|
export declare type VodSearchResponse = ReolinkCmdResponseExt<VodSearchResult> & {
|
|
@@ -7684,6 +8416,34 @@ export declare type WakeUpOptions = {
|
|
|
7684
8416
|
reconnect?: boolean;
|
|
7685
8417
|
};
|
|
7686
8418
|
|
|
8419
|
+
export declare interface WebRTCAnswer {
|
|
8420
|
+
sdp: string;
|
|
8421
|
+
type: "answer";
|
|
8422
|
+
}
|
|
8423
|
+
|
|
8424
|
+
export declare interface WebRTCIceCandidate {
|
|
8425
|
+
candidate: string;
|
|
8426
|
+
sdpMid?: string;
|
|
8427
|
+
sdpMLineIndex?: number;
|
|
8428
|
+
}
|
|
8429
|
+
|
|
8430
|
+
export declare interface WebRTCOffer {
|
|
8431
|
+
sdp: string;
|
|
8432
|
+
type: "offer";
|
|
8433
|
+
}
|
|
8434
|
+
|
|
8435
|
+
export declare interface WebRTCSessionInfo {
|
|
8436
|
+
id: string;
|
|
8437
|
+
state: "connecting" | "connected" | "disconnected" | "failed";
|
|
8438
|
+
createdAt: Date;
|
|
8439
|
+
stats: {
|
|
8440
|
+
videoFrames: number;
|
|
8441
|
+
audioFrames: number;
|
|
8442
|
+
bytesSent: number;
|
|
8443
|
+
intercomBytesSent: number;
|
|
8444
|
+
};
|
|
8445
|
+
}
|
|
8446
|
+
|
|
7687
8447
|
/**
|
|
7688
8448
|
* White LED state configuration.
|
|
7689
8449
|
*/
|