hap-nodejs 1.0.0-beta.1 → 1.0.0-beta.3
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/@types/bonjour-hap.d.ts +4 -3
- package/@types/simple-plist.d.ts +2 -1
- package/README.md +2 -1
- package/dist/BridgedCore.js +6 -5
- package/dist/BridgedCore.js.map +1 -1
- package/dist/Core.js +12 -10
- package/dist/Core.js.map +1 -1
- package/dist/accessories/AirConditioner_accessory.js +27 -27
- package/dist/accessories/AirConditioner_accessory.js.map +1 -1
- package/dist/accessories/AppleTVRemote_accessory.js +17 -16
- package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
- package/dist/accessories/Camera_accessory.js +433 -45
- package/dist/accessories/Camera_accessory.js.map +1 -1
- package/dist/accessories/Fan_accessory.js +8 -13
- package/dist/accessories/Fan_accessory.js.map +1 -1
- package/dist/accessories/GarageDoorOpener_accessory.js +11 -12
- package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
- package/dist/accessories/Light-AdaptiveLighting_accessory.js +5 -6
- package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
- package/dist/accessories/Light_accessory.js +34 -25
- package/dist/accessories/Light_accessory.js.map +1 -1
- package/dist/accessories/Lock_accessory.js +11 -12
- package/dist/accessories/Lock_accessory.js.map +1 -1
- package/dist/accessories/MotionSensor_accessory.js +8 -9
- package/dist/accessories/MotionSensor_accessory.js.map +1 -1
- package/dist/accessories/Outlet_accessory.js +9 -10
- package/dist/accessories/Outlet_accessory.js.map +1 -1
- package/dist/accessories/SmartSpeaker_accessory.js +11 -11
- package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
- package/dist/accessories/Sprinkler_accessory.js +19 -20
- package/dist/accessories/Sprinkler_accessory.js.map +1 -1
- package/dist/accessories/TV_accessory.js +13 -14
- package/dist/accessories/TV_accessory.js.map +1 -1
- package/dist/accessories/TemperatureSensor_accessory.js +7 -8
- package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiRouter_accessory.js +9 -10
- package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.d.ts.map +1 -1
- package/dist/accessories/Wi-FiSatellite_accessory.js +8 -9
- package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.d.ts +2 -2
- package/dist/accessories/gstreamer-audioProducer.d.ts.map +1 -1
- package/dist/accessories/gstreamer-audioProducer.js +31 -32
- package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
- package/dist/index.d.ts +54 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -9
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +65 -124
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/internal-types.js +66 -5
- package/dist/internal-types.js.map +1 -1
- package/dist/lib/Accessory.d.ts +142 -37
- package/dist/lib/Accessory.d.ts.map +1 -1
- package/dist/lib/Accessory.js +539 -451
- package/dist/lib/Accessory.js.map +1 -1
- package/dist/lib/AccessoryLoader.d.ts +20 -8
- package/dist/lib/AccessoryLoader.d.ts.map +1 -1
- package/dist/lib/AccessoryLoader.js +115 -93
- package/dist/lib/AccessoryLoader.js.map +1 -1
- package/dist/lib/Advertiser.d.ts +99 -6
- package/dist/lib/Advertiser.d.ts.map +1 -1
- package/dist/lib/Advertiser.js +558 -21
- package/dist/lib/Advertiser.js.map +1 -1
- package/dist/lib/Bridge.d.ts +3 -1
- package/dist/lib/Bridge.d.ts.map +1 -1
- package/dist/lib/Bridge.js +2 -0
- package/dist/lib/Bridge.js.map +1 -1
- package/dist/lib/Characteristic.d.ts +918 -59
- package/dist/lib/Characteristic.d.ts.map +1 -1
- package/dist/lib/Characteristic.js +308 -257
- package/dist/lib/Characteristic.js.map +1 -1
- package/dist/lib/HAPServer.d.ts +114 -21
- package/dist/lib/HAPServer.d.ts.map +1 -1
- package/dist/lib/HAPServer.js +231 -230
- package/dist/lib/HAPServer.js.map +1 -1
- package/dist/lib/Service.d.ts +339 -15
- package/dist/lib/Service.d.ts.map +1 -1
- package/dist/lib/Service.js +59 -50
- package/dist/lib/Service.js.map +1 -1
- package/dist/lib/camera/Camera.d.ts +15 -6
- package/dist/lib/camera/Camera.d.ts.map +1 -1
- package/dist/lib/camera/Camera.js +6 -3
- package/dist/lib/camera/Camera.js.map +1 -1
- package/dist/lib/camera/RTPProxy.d.ts +24 -19
- package/dist/lib/camera/RTPProxy.d.ts.map +1 -1
- package/dist/lib/camera/RTPProxy.js +230 -207
- package/dist/lib/camera/RTPProxy.js.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.d.ts +202 -43
- package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
- package/dist/lib/camera/RTPStreamManagement.js +303 -189
- package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
- package/dist/lib/camera/RecordingManagement.d.ts +326 -0
- package/dist/lib/camera/RecordingManagement.d.ts.map +1 -0
- package/dist/lib/camera/RecordingManagement.js +833 -0
- package/dist/lib/camera/RecordingManagement.js.map +1 -0
- package/dist/lib/camera/index.d.ts +4 -3
- package/dist/lib/camera/index.d.ts.map +1 -1
- package/dist/lib/camera/index.js +1 -0
- package/dist/lib/camera/index.js.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.d.ts +37 -11
- package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
- package/dist/lib/controller/AdaptiveLightingController.js +101 -86
- package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
- package/dist/lib/controller/CameraController.d.ts +290 -12
- package/dist/lib/controller/CameraController.d.ts.map +1 -1
- package/dist/lib/controller/CameraController.js +403 -47
- package/dist/lib/controller/CameraController.js.map +1 -1
- package/dist/lib/controller/Controller.d.ts +31 -10
- package/dist/lib/controller/Controller.d.ts.map +1 -1
- package/dist/lib/controller/Controller.js +7 -0
- package/dist/lib/controller/Controller.js.map +1 -1
- package/dist/lib/controller/DoorbellController.d.ts +47 -1
- package/dist/lib/controller/DoorbellController.d.ts.map +1 -1
- package/dist/lib/controller/DoorbellController.js +65 -11
- package/dist/lib/controller/DoorbellController.js.map +1 -1
- package/dist/lib/controller/RemoteController.d.ts +111 -42
- package/dist/lib/controller/RemoteController.d.ts.map +1 -1
- package/dist/lib/controller/RemoteController.js +228 -203
- package/dist/lib/controller/RemoteController.js.map +1 -1
- package/dist/lib/controller/index.d.ts +4 -4
- package/dist/lib/datastream/DataStreamManagement.d.ts +25 -19
- package/dist/lib/datastream/DataStreamManagement.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamManagement.js +42 -35
- package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
- package/dist/lib/datastream/DataStreamParser.d.ts +63 -24
- package/dist/lib/datastream/DataStreamParser.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamParser.js +132 -86
- package/dist/lib/datastream/DataStreamParser.js.map +1 -1
- package/dist/lib/datastream/DataStreamServer.d.ts +154 -50
- package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
- package/dist/lib/datastream/DataStreamServer.js +242 -147
- package/dist/lib/datastream/DataStreamServer.js.map +1 -1
- package/dist/lib/datastream/index.d.ts +3 -3
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts +181 -0
- package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/CharacteristicDefinitions.js +968 -499
- package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.d.ts +58 -0
- package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
- package/dist/lib/definitions/ServiceDefinitions.js +173 -6
- package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
- package/dist/lib/definitions/generate-definitions.d.ts +1 -0
- package/dist/lib/definitions/generate-definitions.d.ts.map +1 -1
- package/dist/lib/definitions/generate-definitions.js +29 -21
- package/dist/lib/definitions/generate-definitions.js.map +1 -1
- package/dist/lib/definitions/generator-configuration.d.ts.map +1 -1
- package/dist/lib/definitions/generator-configuration.js +62 -29
- package/dist/lib/definitions/generator-configuration.js.map +1 -1
- package/dist/lib/model/AccessoryInfo.d.ts +16 -10
- package/dist/lib/model/AccessoryInfo.d.ts.map +1 -1
- package/dist/lib/model/AccessoryInfo.js +87 -73
- package/dist/lib/model/AccessoryInfo.js.map +1 -1
- package/dist/lib/model/ControllerStorage.d.ts +3 -0
- package/dist/lib/model/ControllerStorage.d.ts.map +1 -1
- package/dist/lib/model/ControllerStorage.js +7 -4
- package/dist/lib/model/ControllerStorage.js.map +1 -1
- package/dist/lib/model/HAPStorage.d.ts +3 -0
- package/dist/lib/model/HAPStorage.d.ts.map +1 -1
- package/dist/lib/model/HAPStorage.js +4 -0
- package/dist/lib/model/HAPStorage.js.map +1 -1
- package/dist/lib/model/IdentifierCache.d.ts +12 -11
- package/dist/lib/model/IdentifierCache.d.ts.map +1 -1
- package/dist/lib/model/IdentifierCache.js +68 -65
- package/dist/lib/model/IdentifierCache.js.map +1 -1
- package/dist/lib/tv/AccessControlManagement.d.ts +12 -1
- package/dist/lib/tv/AccessControlManagement.d.ts.map +1 -1
- package/dist/lib/tv/AccessControlManagement.js +13 -5
- package/dist/lib/tv/AccessControlManagement.js.map +1 -1
- package/dist/lib/util/clone.d.ts +2 -1
- package/dist/lib/util/clone.d.ts.map +1 -1
- package/dist/lib/util/clone.js +2 -0
- package/dist/lib/util/clone.js.map +1 -1
- package/dist/lib/util/color-utils.d.ts +4 -1
- package/dist/lib/util/color-utils.d.ts.map +1 -1
- package/dist/lib/util/color-utils.js +5 -2
- package/dist/lib/util/color-utils.js.map +1 -1
- package/dist/lib/util/eventedhttp.d.ts +62 -15
- package/dist/lib/util/eventedhttp.d.ts.map +1 -1
- package/dist/lib/util/eventedhttp.js +234 -171
- package/dist/lib/util/eventedhttp.js.map +1 -1
- package/dist/lib/util/hapCrypto.d.ts +35 -7
- package/dist/lib/util/hapCrypto.d.ts.map +1 -1
- package/dist/lib/util/hapCrypto.js +86 -78
- package/dist/lib/util/hapCrypto.js.map +1 -1
- package/dist/lib/util/hapStatusError.d.ts +2 -0
- package/dist/lib/util/hapStatusError.d.ts.map +1 -1
- package/dist/lib/util/hapStatusError.js +5 -3
- package/dist/lib/util/hapStatusError.js.map +1 -1
- package/dist/lib/util/net-utils.d.ts +7 -0
- package/dist/lib/util/net-utils.d.ts.map +1 -1
- package/dist/lib/util/net-utils.js +11 -4
- package/dist/lib/util/net-utils.js.map +1 -1
- package/dist/lib/util/once.d.ts +6 -1
- package/dist/lib/util/once.d.ts.map +1 -1
- package/dist/lib/util/once.js +9 -3
- package/dist/lib/util/once.js.map +1 -1
- package/dist/lib/util/promise-utils.d.ts +15 -0
- package/dist/lib/util/promise-utils.d.ts.map +1 -0
- package/dist/lib/util/promise-utils.js +36 -0
- package/dist/lib/util/promise-utils.js.map +1 -0
- package/dist/lib/util/request-util.d.ts +16 -0
- package/dist/lib/util/request-util.d.ts.map +1 -1
- package/dist/lib/util/request-util.js +43 -27
- package/dist/lib/util/request-util.js.map +1 -1
- package/dist/lib/util/time.d.ts +7 -1
- package/dist/lib/util/time.d.ts.map +1 -1
- package/dist/lib/util/time.js +13 -7
- package/dist/lib/util/time.js.map +1 -1
- package/dist/lib/util/tlv.d.ts +95 -5
- package/dist/lib/util/tlv.d.ts.map +1 -1
- package/dist/lib/util/tlv.js +96 -24
- package/dist/lib/util/tlv.js.map +1 -1
- package/dist/lib/util/uuid.d.ts +2 -3
- package/dist/lib/util/uuid.d.ts.map +1 -1
- package/dist/lib/util/uuid.js +25 -19
- package/dist/lib/util/uuid.js.map +1 -1
- package/dist/types.d.ts +271 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +28 -25
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var
|
|
3
|
+
var tslib_1 = require("tslib");
|
|
4
|
+
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
4
5
|
var child_process_1 = require("child_process");
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
|
|
6
|
+
var events_1 = require("events");
|
|
7
|
+
var net_1 = require("net");
|
|
8
|
+
var __1 = require("..");
|
|
9
|
+
var cameraUUID = __1.uuid.generate("hap-nodejs:accessories:ip-camera");
|
|
10
|
+
var camera = exports.accessory = new __1.Accessory("IPCamera", cameraUUID);
|
|
11
|
+
// @ts-expect-error: Core/BridgeCore API
|
|
8
12
|
camera.username = "9F:B2:46:0C:40:DB";
|
|
9
|
-
// @ts-
|
|
13
|
+
// @ts-expect-error: Core/BridgeCore API
|
|
10
14
|
camera.pincode = "948-23-459";
|
|
11
|
-
camera.category = 17 /* IP_CAMERA */;
|
|
15
|
+
camera.category = 17 /* Categories.IP_CAMERA */;
|
|
12
16
|
var FFMPEGH264ProfileNames = [
|
|
13
17
|
"baseline",
|
|
14
18
|
"main",
|
|
15
|
-
"high"
|
|
19
|
+
"high",
|
|
16
20
|
];
|
|
17
21
|
var FFMPEGH264LevelNames = [
|
|
18
22
|
"3.1",
|
|
19
23
|
"3.2",
|
|
20
|
-
"4.0"
|
|
24
|
+
"4.0",
|
|
21
25
|
];
|
|
22
26
|
var ports = new Set();
|
|
23
27
|
function getPort() {
|
|
@@ -34,25 +38,26 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
34
38
|
// keep track of sessions
|
|
35
39
|
this.pendingSessions = {};
|
|
36
40
|
this.ongoingSessions = {};
|
|
41
|
+
this.handlingStreamingRequest = false;
|
|
37
42
|
}
|
|
38
43
|
ExampleCamera.prototype.handleSnapshotRequest = function (request, callback) {
|
|
39
44
|
var _this = this;
|
|
40
|
-
var ffmpegCommand = "-f lavfi -i testsrc=s="
|
|
41
|
-
var ffmpeg = child_process_1.spawn("ffmpeg", ffmpegCommand.split(" "), { env: process.env });
|
|
45
|
+
var ffmpegCommand = "-f lavfi -i testsrc=s=".concat(request.width, "x").concat(request.height, " -vframes 1 -f mjpeg -");
|
|
46
|
+
var ffmpeg = (0, child_process_1.spawn)("ffmpeg", ffmpegCommand.split(" "), { env: process.env });
|
|
42
47
|
var snapshotBuffers = [];
|
|
43
|
-
ffmpeg.stdout.on(
|
|
44
|
-
ffmpeg.stderr.on(
|
|
48
|
+
ffmpeg.stdout.on("data", function (data) { return snapshotBuffers.push(data); });
|
|
49
|
+
ffmpeg.stderr.on("data", function (data) {
|
|
45
50
|
if (_this.ffmpegDebugOutput) {
|
|
46
51
|
console.log("SNAPSHOT: " + String(data));
|
|
47
52
|
}
|
|
48
53
|
});
|
|
49
|
-
ffmpeg.on(
|
|
54
|
+
ffmpeg.on("exit", function (code, signal) {
|
|
50
55
|
if (signal) {
|
|
51
56
|
console.log("Snapshot process was killed with signal: " + signal);
|
|
52
57
|
callback(new Error("killed with signal " + signal));
|
|
53
58
|
}
|
|
54
59
|
else if (code === 0) {
|
|
55
|
-
console.log("Successfully captured snapshot at "
|
|
60
|
+
console.log("Successfully captured snapshot at ".concat(request.width, "x").concat(request.height));
|
|
56
61
|
callback(undefined, Buffer.concat(snapshotBuffers));
|
|
57
62
|
}
|
|
58
63
|
else {
|
|
@@ -96,7 +101,7 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
96
101
|
var _this = this;
|
|
97
102
|
var sessionId = request.sessionID;
|
|
98
103
|
switch (request.type) {
|
|
99
|
-
case "start" /* START */: {
|
|
104
|
+
case "start" /* StreamRequestTypes.START */: {
|
|
100
105
|
var sessionInfo = this.pendingSessions[sessionId];
|
|
101
106
|
var video = request.video;
|
|
102
107
|
var profile = FFMPEGH264ProfileNames[video.profile];
|
|
@@ -106,6 +111,7 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
106
111
|
var fps = video.fps;
|
|
107
112
|
var payloadType = video.pt;
|
|
108
113
|
var maxBitrate = video.max_bit_rate;
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
115
|
var rtcpInterval = video.rtcp_interval; // usually 0.5
|
|
110
116
|
var mtu = video.mtu; // maximum transmission unit
|
|
111
117
|
var address = sessionInfo.address;
|
|
@@ -114,30 +120,30 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
114
120
|
var ssrc = sessionInfo.videoSSRC;
|
|
115
121
|
var cryptoSuite = sessionInfo.videoCryptoSuite;
|
|
116
122
|
var videoSRTP = sessionInfo.videoSRTP.toString("base64");
|
|
117
|
-
console.log("Starting video stream ("
|
|
118
|
-
var videoffmpegCommand = "-re -f lavfi -i testsrc=s="
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (cryptoSuite !== 2 /* NONE */) {
|
|
123
|
+
console.log("Starting video stream (".concat(width, "x").concat(height, ", ").concat(fps, " fps, ").concat(maxBitrate, " kbps, ").concat(mtu, " mtu)..."));
|
|
124
|
+
var videoffmpegCommand = "-re -f lavfi -i testsrc=s=".concat(width, "x").concat(height, ":r=").concat(fps, " -map 0:0 ") +
|
|
125
|
+
"-c:v h264 -pix_fmt yuv420p -r ".concat(fps, " -an -sn -dn -b:v ").concat(maxBitrate, "k ") +
|
|
126
|
+
"-profile:v ".concat(profile, " -level:v ").concat(level, " ") +
|
|
127
|
+
"-payload_type ".concat(payloadType, " -ssrc ").concat(ssrc, " -f rtp ");
|
|
128
|
+
if (cryptoSuite !== 2 /* SRTPCryptoSuites.NONE */) {
|
|
123
129
|
var suite = void 0;
|
|
124
130
|
switch (cryptoSuite) {
|
|
125
|
-
case 0 /* AES_CM_128_HMAC_SHA1_80 */: // actually ffmpeg just supports AES_CM_128_HMAC_SHA1_80
|
|
131
|
+
case 0 /* SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80 */: // actually ffmpeg just supports AES_CM_128_HMAC_SHA1_80
|
|
126
132
|
suite = "AES_CM_128_HMAC_SHA1_80";
|
|
127
133
|
break;
|
|
128
|
-
case 1 /* AES_CM_256_HMAC_SHA1_80 */:
|
|
134
|
+
case 1 /* SRTPCryptoSuites.AES_CM_256_HMAC_SHA1_80 */:
|
|
129
135
|
suite = "AES_CM_256_HMAC_SHA1_80";
|
|
130
136
|
break;
|
|
131
137
|
}
|
|
132
|
-
videoffmpegCommand += "-srtp_out_suite "
|
|
138
|
+
videoffmpegCommand += "-srtp_out_suite ".concat(suite, " -srtp_out_params ").concat(videoSRTP, " s");
|
|
133
139
|
}
|
|
134
|
-
videoffmpegCommand += "rtp://"
|
|
140
|
+
videoffmpegCommand += "rtp://".concat(address, ":").concat(videoPort, "?rtcpport=").concat(videoPort, "&localrtcpport=").concat(localVideoPort, "&pkt_size=").concat(mtu);
|
|
135
141
|
if (this.ffmpegDebugOutput) {
|
|
136
142
|
console.log("FFMPEG command: ffmpeg " + videoffmpegCommand);
|
|
137
143
|
}
|
|
138
|
-
var ffmpegVideo = child_process_1.spawn(
|
|
144
|
+
var ffmpegVideo = (0, child_process_1.spawn)("ffmpeg", videoffmpegCommand.split(" "), { env: process.env });
|
|
139
145
|
var started_1 = false;
|
|
140
|
-
ffmpegVideo.stderr.on(
|
|
146
|
+
ffmpegVideo.stderr.on("data", function (data) {
|
|
141
147
|
console.log(data.toString("utf8"));
|
|
142
148
|
if (!started_1) {
|
|
143
149
|
started_1 = true;
|
|
@@ -148,11 +154,11 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
148
154
|
console.log("VIDEO: " + String(data));
|
|
149
155
|
}
|
|
150
156
|
});
|
|
151
|
-
ffmpegVideo.on(
|
|
157
|
+
ffmpegVideo.on("error", function (error) {
|
|
152
158
|
console.log("[Video] Failed to start video stream: " + error.message);
|
|
153
159
|
callback(new Error("ffmpeg process creation failed!"));
|
|
154
160
|
});
|
|
155
|
-
ffmpegVideo.on(
|
|
161
|
+
ffmpegVideo.on("exit", function (code, signal) {
|
|
156
162
|
var message = "[Video] ffmpeg exited with code: " + code + " and signal: " + signal;
|
|
157
163
|
if (code == null || code === 255) {
|
|
158
164
|
console.log(message + " (Video stream stopped!)");
|
|
@@ -174,16 +180,20 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
174
180
|
delete this.pendingSessions[sessionId];
|
|
175
181
|
break;
|
|
176
182
|
}
|
|
177
|
-
case "reconfigure" /* RECONFIGURE */:
|
|
183
|
+
case "reconfigure" /* StreamRequestTypes.RECONFIGURE */:
|
|
178
184
|
// not supported by this example
|
|
179
185
|
console.log("Received (unsupported) request to reconfigure to: " + JSON.stringify(request.video));
|
|
180
186
|
callback();
|
|
181
187
|
break;
|
|
182
|
-
case "stop" /* STOP */:
|
|
188
|
+
case "stop" /* StreamRequestTypes.STOP */: {
|
|
183
189
|
var ongoingSession = this.ongoingSessions[sessionId];
|
|
190
|
+
if (!ongoingSession) {
|
|
191
|
+
callback();
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
184
194
|
ports.delete(ongoingSession.localVideoPort);
|
|
185
195
|
try {
|
|
186
|
-
ongoingSession.process.kill(
|
|
196
|
+
ongoingSession.process.kill("SIGKILL");
|
|
187
197
|
}
|
|
188
198
|
catch (e) {
|
|
189
199
|
console.log("Error occurred terminating the video process!");
|
|
@@ -193,21 +203,350 @@ var ExampleCamera = /** @class */ (function () {
|
|
|
193
203
|
console.log("Stopped streaming session!");
|
|
194
204
|
callback();
|
|
195
205
|
break;
|
|
206
|
+
}
|
|
196
207
|
}
|
|
197
208
|
};
|
|
209
|
+
ExampleCamera.prototype.updateRecordingActive = function (active) {
|
|
210
|
+
// we haven't implemented a prebuffer
|
|
211
|
+
console.log("Recording active set to " + active);
|
|
212
|
+
};
|
|
213
|
+
ExampleCamera.prototype.updateRecordingConfiguration = function (configuration) {
|
|
214
|
+
this.configuration = configuration;
|
|
215
|
+
console.log(configuration);
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* This is a very minimal, very experimental example on how to implement fmp4 streaming with a
|
|
219
|
+
* CameraController supporting HomeKit Secure Video.
|
|
220
|
+
*
|
|
221
|
+
* An ideal implementation would diverge from this in the following ways:
|
|
222
|
+
* * It would implement a prebuffer and respect the recording `active` characteristic for that.
|
|
223
|
+
* * It would start to immediately record after a trigger event occurred and not just
|
|
224
|
+
* when the HomeKit Controller requests it (see the documentation of `CameraRecordingDelegate`).
|
|
225
|
+
*/
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
227
|
+
ExampleCamera.prototype.handleRecordingStreamRequest = function (streamId) {
|
|
228
|
+
var _a, _b, _c;
|
|
229
|
+
return tslib_1.__asyncGenerator(this, arguments, function handleRecordingStreamRequest_1() {
|
|
230
|
+
var STOP_AFTER_MOTION_STOP, profile, level, videoArgs, samplerate, audioArgs, pending, _d, _e, _f, box, motionDetected, fragment, isLast, e_1_1, error_1;
|
|
231
|
+
var _g, e_1, _h, _j;
|
|
232
|
+
return tslib_1.__generator(this, function (_k) {
|
|
233
|
+
switch (_k.label) {
|
|
234
|
+
case 0:
|
|
235
|
+
(0, assert_1.default)(!!this.configuration);
|
|
236
|
+
STOP_AFTER_MOTION_STOP = false;
|
|
237
|
+
this.handlingStreamingRequest = true;
|
|
238
|
+
(0, assert_1.default)(this.configuration.videoCodec.type === 0 /* VideoCodecType.H264 */);
|
|
239
|
+
profile = this.configuration.videoCodec.parameters.profile === 2 /* H264Profile.HIGH */ ? "high"
|
|
240
|
+
: this.configuration.videoCodec.parameters.profile === 1 /* H264Profile.MAIN */ ? "main" : "baseline";
|
|
241
|
+
level = this.configuration.videoCodec.parameters.level === 2 /* H264Level.LEVEL4_0 */ ? "4.0"
|
|
242
|
+
: this.configuration.videoCodec.parameters.level === 1 /* H264Level.LEVEL3_2 */ ? "3.2" : "3.1";
|
|
243
|
+
videoArgs = [
|
|
244
|
+
"-an",
|
|
245
|
+
"-sn",
|
|
246
|
+
"-dn",
|
|
247
|
+
"-codec:v",
|
|
248
|
+
"libx264",
|
|
249
|
+
"-pix_fmt",
|
|
250
|
+
"yuv420p",
|
|
251
|
+
"-profile:v", profile,
|
|
252
|
+
"-level:v", level,
|
|
253
|
+
"-b:v",
|
|
254
|
+
"".concat(this.configuration.videoCodec.parameters.bitRate, "k"),
|
|
255
|
+
"-force_key_frames",
|
|
256
|
+
"expr:eq(t,n_forced*".concat(this.configuration.videoCodec.parameters.iFrameInterval / 1000, ")"),
|
|
257
|
+
"-r", this.configuration.videoCodec.resolution[2].toString(),
|
|
258
|
+
];
|
|
259
|
+
switch (this.configuration.audioCodec.samplerate) {
|
|
260
|
+
case 0 /* AudioRecordingSamplerate.KHZ_8 */:
|
|
261
|
+
samplerate = "8";
|
|
262
|
+
break;
|
|
263
|
+
case 1 /* AudioRecordingSamplerate.KHZ_16 */:
|
|
264
|
+
samplerate = "16";
|
|
265
|
+
break;
|
|
266
|
+
case 2 /* AudioRecordingSamplerate.KHZ_24 */:
|
|
267
|
+
samplerate = "24";
|
|
268
|
+
break;
|
|
269
|
+
case 3 /* AudioRecordingSamplerate.KHZ_32 */:
|
|
270
|
+
samplerate = "32";
|
|
271
|
+
break;
|
|
272
|
+
case 4 /* AudioRecordingSamplerate.KHZ_44_1 */:
|
|
273
|
+
samplerate = "44.1";
|
|
274
|
+
break;
|
|
275
|
+
case 5 /* AudioRecordingSamplerate.KHZ_48 */:
|
|
276
|
+
samplerate = "48";
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
throw new Error("Unsupported audio samplerate: " + this.configuration.audioCodec.samplerate);
|
|
280
|
+
}
|
|
281
|
+
audioArgs = ((_b = (_a = this.controller) === null || _a === void 0 ? void 0 : _a.recordingManagement) === null || _b === void 0 ? void 0 : _b.recordingManagementService.getCharacteristic(__1.Characteristic.RecordingAudioActive))
|
|
282
|
+
? tslib_1.__spreadArray(tslib_1.__spreadArray([
|
|
283
|
+
"-acodec", "libfdk_aac"
|
|
284
|
+
], tslib_1.__read((this.configuration.audioCodec.type === 0 /* AudioRecordingCodecType.AAC_LC */ ?
|
|
285
|
+
["-profile:a", "aac_low"] :
|
|
286
|
+
["-profile:a", "aac_eld"])), false), [
|
|
287
|
+
"-ar",
|
|
288
|
+
"".concat(samplerate, "k"),
|
|
289
|
+
"-b:a",
|
|
290
|
+
"".concat(this.configuration.audioCodec.bitrate, "k"),
|
|
291
|
+
"-ac",
|
|
292
|
+
"".concat(this.configuration.audioCodec.audioChannels),
|
|
293
|
+
], false) : [];
|
|
294
|
+
this.server = new MP4StreamingServer("ffmpeg", "-f lavfi -i testsrc=s=".concat(this.configuration.videoCodec.resolution[0], "x").concat(this.configuration.videoCodec.resolution[1], ":r=").concat(this.configuration.videoCodec.resolution[2])
|
|
295
|
+
.split(/ /g), audioArgs, videoArgs);
|
|
296
|
+
return [4 /*yield*/, tslib_1.__await(this.server.start())];
|
|
297
|
+
case 1:
|
|
298
|
+
_k.sent();
|
|
299
|
+
if (!(!this.server || this.server.destroyed)) return [3 /*break*/, 3];
|
|
300
|
+
return [4 /*yield*/, tslib_1.__await(void 0)];
|
|
301
|
+
case 2: return [2 /*return*/, _k.sent()]; // early exit
|
|
302
|
+
case 3:
|
|
303
|
+
pending = [];
|
|
304
|
+
_k.label = 4;
|
|
305
|
+
case 4:
|
|
306
|
+
_k.trys.push([4, 22, , 23]);
|
|
307
|
+
_k.label = 5;
|
|
308
|
+
case 5:
|
|
309
|
+
_k.trys.push([5, 15, 16, 21]);
|
|
310
|
+
_d = true, _e = tslib_1.__asyncValues(this.server.generator());
|
|
311
|
+
_k.label = 6;
|
|
312
|
+
case 6: return [4 /*yield*/, tslib_1.__await(_e.next())];
|
|
313
|
+
case 7:
|
|
314
|
+
if (!(_f = _k.sent(), _g = _f.done, !_g)) return [3 /*break*/, 14];
|
|
315
|
+
_j = _f.value;
|
|
316
|
+
_d = false;
|
|
317
|
+
_k.label = 8;
|
|
318
|
+
case 8:
|
|
319
|
+
_k.trys.push([8, , 12, 13]);
|
|
320
|
+
box = _j;
|
|
321
|
+
pending.push(box.header, box.data);
|
|
322
|
+
motionDetected = (_c = camera.getService(__1.Service.MotionSensor)) === null || _c === void 0 ? void 0 : _c.getCharacteristic(__1.Characteristic.MotionDetected).value;
|
|
323
|
+
console.log("mp4 box type " + box.type + " and length " + box.length);
|
|
324
|
+
if (!(box.type === "moov" || box.type === "mdat")) return [3 /*break*/, 11];
|
|
325
|
+
fragment = Buffer.concat(pending);
|
|
326
|
+
pending.splice(0, pending.length);
|
|
327
|
+
isLast = STOP_AFTER_MOTION_STOP && !motionDetected;
|
|
328
|
+
return [4 /*yield*/, tslib_1.__await({
|
|
329
|
+
data: fragment,
|
|
330
|
+
isLast: isLast,
|
|
331
|
+
})];
|
|
332
|
+
case 9: return [4 /*yield*/, _k.sent()];
|
|
333
|
+
case 10:
|
|
334
|
+
_k.sent();
|
|
335
|
+
if (isLast) {
|
|
336
|
+
console.log("Ending session due to motion stopped!");
|
|
337
|
+
return [3 /*break*/, 14];
|
|
338
|
+
}
|
|
339
|
+
_k.label = 11;
|
|
340
|
+
case 11: return [3 /*break*/, 13];
|
|
341
|
+
case 12:
|
|
342
|
+
_d = true;
|
|
343
|
+
return [7 /*endfinally*/];
|
|
344
|
+
case 13: return [3 /*break*/, 6];
|
|
345
|
+
case 14: return [3 /*break*/, 21];
|
|
346
|
+
case 15:
|
|
347
|
+
e_1_1 = _k.sent();
|
|
348
|
+
e_1 = { error: e_1_1 };
|
|
349
|
+
return [3 /*break*/, 21];
|
|
350
|
+
case 16:
|
|
351
|
+
_k.trys.push([16, , 19, 20]);
|
|
352
|
+
if (!(!_d && !_g && (_h = _e.return))) return [3 /*break*/, 18];
|
|
353
|
+
return [4 /*yield*/, tslib_1.__await(_h.call(_e))];
|
|
354
|
+
case 17:
|
|
355
|
+
_k.sent();
|
|
356
|
+
_k.label = 18;
|
|
357
|
+
case 18: return [3 /*break*/, 20];
|
|
358
|
+
case 19:
|
|
359
|
+
if (e_1) throw e_1.error;
|
|
360
|
+
return [7 /*endfinally*/];
|
|
361
|
+
case 20: return [7 /*endfinally*/];
|
|
362
|
+
case 21: return [3 /*break*/, 23];
|
|
363
|
+
case 22:
|
|
364
|
+
error_1 = _k.sent();
|
|
365
|
+
if (!error_1.message.startsWith("FFMPEG")) { // cheap way of identifying our own emitted errors
|
|
366
|
+
console.error("Encountered unexpected error on generator " + error_1.stack);
|
|
367
|
+
}
|
|
368
|
+
return [3 /*break*/, 23];
|
|
369
|
+
case 23: return [2 /*return*/];
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
375
|
+
ExampleCamera.prototype.closeRecordingStream = function (streamId, reason) {
|
|
376
|
+
if (this.server) {
|
|
377
|
+
this.server.destroy();
|
|
378
|
+
this.server = undefined;
|
|
379
|
+
}
|
|
380
|
+
this.handlingStreamingRequest = false;
|
|
381
|
+
};
|
|
382
|
+
ExampleCamera.prototype.acknowledgeStream = function (streamId) {
|
|
383
|
+
this.closeRecordingStream(streamId);
|
|
384
|
+
};
|
|
198
385
|
return ExampleCamera;
|
|
199
386
|
}());
|
|
387
|
+
var MP4StreamingServer = /** @class */ (function () {
|
|
388
|
+
function MP4StreamingServer(ffmpegPath, ffmpegInput, audioOutputArgs, videoOutputArgs) {
|
|
389
|
+
var _a, _b, _c;
|
|
390
|
+
var _this = this;
|
|
391
|
+
/**
|
|
392
|
+
* This can be configured to output ffmpeg debug output!
|
|
393
|
+
*/
|
|
394
|
+
this.debugMode = false;
|
|
395
|
+
this.destroyed = false;
|
|
396
|
+
this.connectPromise = new Promise(function (resolve) { return _this.connectResolve = resolve; });
|
|
397
|
+
this.server = (0, net_1.createServer)(this.handleConnection.bind(this));
|
|
398
|
+
this.ffmpegPath = ffmpegPath;
|
|
399
|
+
this.args = [];
|
|
400
|
+
(_a = this.args).push.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(ffmpegInput), false));
|
|
401
|
+
(_b = this.args).push.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(audioOutputArgs), false));
|
|
402
|
+
this.args.push("-f", "mp4");
|
|
403
|
+
(_c = this.args).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(videoOutputArgs), false));
|
|
404
|
+
this.args.push("-fflags", "+genpts", "-reset_timestamps", "1");
|
|
405
|
+
this.args.push("-movflags", "frag_keyframe+empty_moov+default_base_moof");
|
|
406
|
+
}
|
|
407
|
+
MP4StreamingServer.prototype.start = function () {
|
|
408
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
409
|
+
var promise, port;
|
|
410
|
+
return tslib_1.__generator(this, function (_a) {
|
|
411
|
+
switch (_a.label) {
|
|
412
|
+
case 0:
|
|
413
|
+
promise = (0, events_1.once)(this.server, "listening");
|
|
414
|
+
this.server.listen(); // listen on random port
|
|
415
|
+
return [4 /*yield*/, promise];
|
|
416
|
+
case 1:
|
|
417
|
+
_a.sent();
|
|
418
|
+
if (this.destroyed) {
|
|
419
|
+
return [2 /*return*/];
|
|
420
|
+
}
|
|
421
|
+
port = this.server.address().port;
|
|
422
|
+
this.args.push("tcp://127.0.0.1:" + port);
|
|
423
|
+
console.log(this.ffmpegPath + " " + this.args.join(" "));
|
|
424
|
+
this.childProcess = (0, child_process_1.spawn)(this.ffmpegPath, this.args, { env: process.env, stdio: this.debugMode ? "pipe" : "ignore" });
|
|
425
|
+
if (!this.childProcess) {
|
|
426
|
+
console.error("ChildProcess is undefined directly after the init!");
|
|
427
|
+
}
|
|
428
|
+
if (this.debugMode) {
|
|
429
|
+
this.childProcess.stdout.on("data", function (data) { return console.log(data.toString()); });
|
|
430
|
+
this.childProcess.stderr.on("data", function (data) { return console.log(data.toString()); });
|
|
431
|
+
}
|
|
432
|
+
return [2 /*return*/];
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
};
|
|
437
|
+
MP4StreamingServer.prototype.destroy = function () {
|
|
438
|
+
var _a, _b;
|
|
439
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
440
|
+
(_b = this.childProcess) === null || _b === void 0 ? void 0 : _b.kill();
|
|
441
|
+
this.socket = undefined;
|
|
442
|
+
this.childProcess = undefined;
|
|
443
|
+
this.destroyed = true;
|
|
444
|
+
};
|
|
445
|
+
MP4StreamingServer.prototype.handleConnection = function (socket) {
|
|
446
|
+
var _a;
|
|
447
|
+
this.server.close(); // don't accept any further clients
|
|
448
|
+
this.socket = socket;
|
|
449
|
+
(_a = this.connectResolve) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* Generator for `MP4Atom`s.
|
|
453
|
+
* Throws error to signal EOF when socket is closed.
|
|
454
|
+
*/
|
|
455
|
+
MP4StreamingServer.prototype.generator = function () {
|
|
456
|
+
return tslib_1.__asyncGenerator(this, arguments, function generator_1() {
|
|
457
|
+
var header, length, type, data;
|
|
458
|
+
return tslib_1.__generator(this, function (_a) {
|
|
459
|
+
switch (_a.label) {
|
|
460
|
+
case 0: return [4 /*yield*/, tslib_1.__await(this.connectPromise)];
|
|
461
|
+
case 1:
|
|
462
|
+
_a.sent();
|
|
463
|
+
if (!this.socket || !this.childProcess) {
|
|
464
|
+
console.log("Socket undefined " + !!this.socket + " childProcess undefined " + !!this.childProcess);
|
|
465
|
+
throw new Error("Unexpected state!");
|
|
466
|
+
}
|
|
467
|
+
_a.label = 2;
|
|
468
|
+
case 2:
|
|
469
|
+
if (!true) return [3 /*break*/, 7];
|
|
470
|
+
return [4 /*yield*/, tslib_1.__await(this.read(8))];
|
|
471
|
+
case 3:
|
|
472
|
+
header = _a.sent();
|
|
473
|
+
length = header.readInt32BE(0) - 8;
|
|
474
|
+
type = header.slice(4).toString();
|
|
475
|
+
return [4 /*yield*/, tslib_1.__await(this.read(length))];
|
|
476
|
+
case 4:
|
|
477
|
+
data = _a.sent();
|
|
478
|
+
return [4 /*yield*/, tslib_1.__await({
|
|
479
|
+
header: header,
|
|
480
|
+
length: length,
|
|
481
|
+
type: type,
|
|
482
|
+
data: data,
|
|
483
|
+
})];
|
|
484
|
+
case 5: return [4 /*yield*/, _a.sent()];
|
|
485
|
+
case 6:
|
|
486
|
+
_a.sent();
|
|
487
|
+
return [3 /*break*/, 2];
|
|
488
|
+
case 7: return [2 /*return*/];
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
MP4StreamingServer.prototype.read = function (length) {
|
|
494
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
495
|
+
var value;
|
|
496
|
+
var _this = this;
|
|
497
|
+
return tslib_1.__generator(this, function (_a) {
|
|
498
|
+
if (!this.socket) {
|
|
499
|
+
throw Error("FFMPEG tried reading from closed socket!");
|
|
500
|
+
}
|
|
501
|
+
if (!length) {
|
|
502
|
+
return [2 /*return*/, Buffer.alloc(0)];
|
|
503
|
+
}
|
|
504
|
+
value = this.socket.read(length);
|
|
505
|
+
if (value) {
|
|
506
|
+
return [2 /*return*/, value];
|
|
507
|
+
}
|
|
508
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
509
|
+
var readHandler = function () {
|
|
510
|
+
var value = _this.socket.read(length);
|
|
511
|
+
if (value) {
|
|
512
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
513
|
+
cleanup();
|
|
514
|
+
resolve(value);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
var endHandler = function () {
|
|
518
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
519
|
+
cleanup();
|
|
520
|
+
reject(new Error("FFMPEG socket closed during read for ".concat(length, " bytes!")));
|
|
521
|
+
};
|
|
522
|
+
var cleanup = function () {
|
|
523
|
+
var _a, _b;
|
|
524
|
+
(_a = _this.socket) === null || _a === void 0 ? void 0 : _a.removeListener("readable", readHandler);
|
|
525
|
+
(_b = _this.socket) === null || _b === void 0 ? void 0 : _b.removeListener("close", endHandler);
|
|
526
|
+
};
|
|
527
|
+
if (!_this.socket) {
|
|
528
|
+
throw new Error("FFMPEG socket is closed now!");
|
|
529
|
+
}
|
|
530
|
+
_this.socket.on("readable", readHandler);
|
|
531
|
+
_this.socket.on("close", endHandler);
|
|
532
|
+
})];
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
return MP4StreamingServer;
|
|
537
|
+
}());
|
|
200
538
|
var streamDelegate = new ExampleCamera();
|
|
201
539
|
var cameraController = new __1.CameraController({
|
|
202
540
|
cameraStreamCount: 2,
|
|
203
541
|
delegate: streamDelegate,
|
|
204
542
|
streamingOptions: {
|
|
205
543
|
// srtp: true, // legacy option which will just enable AES_CM_128_HMAC_SHA1_80 (can still be used though)
|
|
206
|
-
|
|
544
|
+
// NONE is not supported by iOS just there for testing with Wireshark for example
|
|
545
|
+
supportedCryptoSuites: [2 /* SRTPCryptoSuites.NONE */, 0 /* SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80 */],
|
|
207
546
|
video: {
|
|
208
547
|
codec: {
|
|
209
|
-
profiles: [0 /* BASELINE */, 1 /* MAIN */, 2 /* HIGH */],
|
|
210
|
-
levels: [0 /* LEVEL3_1 */, 1 /* LEVEL3_2 */, 2 /* LEVEL4_0 */],
|
|
548
|
+
profiles: [0 /* H264Profile.BASELINE */, 1 /* H264Profile.MAIN */, 2 /* H264Profile.HIGH */],
|
|
549
|
+
levels: [0 /* H264Level.LEVEL3_1 */, 1 /* H264Level.LEVEL3_2 */, 2 /* H264Level.LEVEL4_0 */],
|
|
211
550
|
},
|
|
212
551
|
resolutions: [
|
|
213
552
|
[1920, 1080, 30],
|
|
@@ -224,19 +563,68 @@ var cameraController = new __1.CameraController({
|
|
|
224
563
|
],
|
|
225
564
|
},
|
|
226
565
|
/* audio option is omitted, as it is not supported in this example; HAP-NodeJS will fake an appropriate audio codec
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
566
|
+
audio: {
|
|
567
|
+
comfort_noise: false, // optional, default false
|
|
568
|
+
codecs: [
|
|
569
|
+
{
|
|
570
|
+
type: AudioStreamingCodecType.OPUS,
|
|
571
|
+
audioChannels: 1, // optional, default 1
|
|
572
|
+
samplerate: [AudioStreamingSamplerate.KHZ_16, AudioStreamingSamplerate.KHZ_24], // 16 and 24 must be present for AAC-ELD or OPUS
|
|
573
|
+
},
|
|
574
|
+
],
|
|
575
|
+
},
|
|
576
|
+
// */
|
|
577
|
+
},
|
|
578
|
+
recording: {
|
|
579
|
+
options: {
|
|
580
|
+
prebufferLength: 4000,
|
|
581
|
+
mediaContainerConfiguration: {
|
|
582
|
+
type: 0 /* MediaContainerType.FRAGMENTED_MP4 */,
|
|
583
|
+
fragmentLength: 4000,
|
|
584
|
+
},
|
|
585
|
+
video: {
|
|
586
|
+
type: 0 /* VideoCodecType.H264 */,
|
|
587
|
+
parameters: {
|
|
588
|
+
profiles: [2 /* H264Profile.HIGH */],
|
|
589
|
+
levels: [2 /* H264Level.LEVEL4_0 */],
|
|
234
590
|
},
|
|
235
|
-
|
|
591
|
+
resolutions: [
|
|
592
|
+
[320, 180, 30],
|
|
593
|
+
[320, 240, 15],
|
|
594
|
+
[320, 240, 30],
|
|
595
|
+
[480, 270, 30],
|
|
596
|
+
[480, 360, 30],
|
|
597
|
+
[640, 360, 30],
|
|
598
|
+
[640, 480, 30],
|
|
599
|
+
[1280, 720, 30],
|
|
600
|
+
[1280, 960, 30],
|
|
601
|
+
[1920, 1080, 30],
|
|
602
|
+
[1600, 1200, 30],
|
|
603
|
+
],
|
|
604
|
+
},
|
|
605
|
+
audio: {
|
|
606
|
+
codecs: {
|
|
607
|
+
type: 1 /* AudioRecordingCodecType.AAC_ELD */,
|
|
608
|
+
audioChannels: 1,
|
|
609
|
+
samplerate: 5 /* AudioRecordingSamplerate.KHZ_48 */,
|
|
610
|
+
bitrateMode: 0 /* AudioBitrate.VARIABLE */,
|
|
611
|
+
},
|
|
612
|
+
},
|
|
236
613
|
},
|
|
237
|
-
|
|
238
|
-
}
|
|
614
|
+
delegate: streamDelegate,
|
|
615
|
+
},
|
|
616
|
+
sensors: {
|
|
617
|
+
motion: true,
|
|
618
|
+
occupancy: true,
|
|
619
|
+
},
|
|
239
620
|
});
|
|
240
621
|
streamDelegate.controller = cameraController;
|
|
241
622
|
camera.configureController(cameraController);
|
|
623
|
+
// a service to trigger the motion sensor!
|
|
624
|
+
camera.addService(__1.Service.Switch, "MOTION TRIGGER")
|
|
625
|
+
.getCharacteristic(__1.Characteristic.On)
|
|
626
|
+
.onSet(function (value) {
|
|
627
|
+
var _a;
|
|
628
|
+
(_a = camera.getService(__1.Service.MotionSensor)) === null || _a === void 0 ? void 0 : _a.updateCharacteristic(__1.Characteristic.MotionDetected, value);
|
|
629
|
+
});
|
|
242
630
|
//# sourceMappingURL=Camera_accessory.js.map
|