diff --git a/README.md b/README.md index 3a6db85..31df571 100755 --- a/README.md +++ b/README.md @@ -35,8 +35,14 @@ A: Your device running Homebridge must encode the stream into a format that iOS 3. Run [Homebridge](https://github.com/nfarina/homebridge) 4. Add extra camera accessories in Home app using the same setup code as [Homebridge](https://github.com/nfarina/homebridge) +#### Raspberry Pi +You may want to use OMX for transcoding as the CPU on the board can be slow. If so, make sure the ffmpeg installed on your Pi has `h264_omx` support and set the `ffmpegCodec` option below to `h264_omx`. You can always compile ffmpeg from source using [these instructions](https://github.com/legotheboss/YouTube-files/wiki/(RPi)-Compile-FFmpeg-with-the-OpenMAX-H.264-GPU-acceleration). + +#### Mac OS +You may want to use VideoToolbox hardware acceleration for transcoding. If so, make sure the ffmpeg installed on your Mac has `videotoolbox` support and set `ffmpegCodec` option below to `h264_videotoolbox`. + #### Docker -The Homebridge Docker container requires an extra environment variable to install ffmpeg: `PACKAGES=ffmpeg`. +The Homebridge Docker container requires an extra environment variable to install ffmpeg: `PACKAGES=ffmpeg`. The Docker container also requires the `libx264` codec as it uses the ffmpeg inside the container and not the ffmpeg on the device running the container. ### Setting up the Config.json Setting up a Google Account with homebridge-nest is a pain, but only needs to be done once, as long as you do not log out of your Google Account. @@ -46,6 +52,7 @@ Google Accounts are configured using the `"googleAuth"` object in `config.json`, ``` { "platform": "Nest-cam", + "ffmpegCodec": "libx264", "googleAuth": { "issueToken": "https://accounts.google.com/o/oauth2/iframerpc?action=issueToken...", "cookies": "SMSV=ADHTe...", diff --git a/config.schema.json b/config.schema.json index 1d5ada9..8d84c38 100644 --- a/config.schema.json +++ b/config.schema.json @@ -27,6 +27,13 @@ "required": true } } + }, + "ffmpegCodec": { + "title": "ffmpeg Codec", + "type": "string", + "default": "libx264", + "required": true, + "description": "Ensure that the installed ffmpeg binary has support for the specified codec." } } } diff --git a/lib/nestcam.js b/lib/nestcam.js index 98d5c10..a10cf65 100644 --- a/lib/nestcam.js +++ b/lib/nestcam.js @@ -12,6 +12,7 @@ class NestCam { constructor(api, info, log) { let self = this; NestEndpoints.init(api.fieldTest); + self.ffmpegCodec = 'libx264'; self.api = api; self.log = log; self.setAttributes(info); @@ -105,6 +106,9 @@ class NestCam { StreamController = hap.StreamController; let self = this; + if (config.ffmpegCodec) { + self.ffmpegCodec = config.ffmpegCodec; + } self.services = []; self.streamControllers = []; @@ -209,7 +213,7 @@ class NestCam { if (self.enabled) { let sessionID = uuid.unparse(request['sessionID']); - let streamer = new NexusStreamer(self.nexusTalkHost, self.uuid, self.api.accessToken, self.log); + let streamer = new NexusStreamer(self.nexusTalkHost, self.uuid, self.api.accessToken, self.ffmpegCodec, self.log); self.sessions[`${sessionID}`] = streamer; streamer.prepareStream(request, callback); } diff --git a/lib/streamer.js b/lib/streamer.js index d41bd99..f87e91c 100644 --- a/lib/streamer.js +++ b/lib/streamer.js @@ -19,11 +19,12 @@ const AuthorizeRequest = require('./protos/AuthorizeRequest.js').AuthorizeReques const NestEndpoints = require('./nest-endpoints.js'); class NexusStreamer extends EventEmitter { - constructor(host, cameraUUID, accessToken, log) { + constructor(host, cameraUUID, accessToken, ffmpegCodec, log) { super(); let self = this; self.isStreaming = false; self.authorized = false; + self.ffmpegCodec = ffmpegCodec; self.log = log; self.sessionID = Math.floor(Math.random() * 100); self.host = host; @@ -211,8 +212,7 @@ class NexusStreamer extends EventEmitter { StreamProfile.VIDEO_H264_530KBIT_L31, StreamProfile.AVPROFILE_MOBILE_1, StreamProfile.AVPROFILE_HD_MAIN_1 - ], - profile_not_found_action: StartPlayback.ProfileNotFoundAction.REDIRECT + ] }; let pbfContainer = new PBF(); StartPlayback.write(request, pbfContainer); @@ -427,7 +427,12 @@ class NexusStreamer extends EventEmitter { let audioKey = sessionInfo['audio_srtp']; let audioSsrc = sessionInfo['audio_ssrc']; - let ffmpegCommand = '-use_wallclock_as_timestamps 1 -i - -c:v copy -an -payload_type 99 -ssrc ' + videoSsrc + ' -f rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params ' + videoKey.toString('base64') + ' srtp://'+targetAddress+':' + targetVideoPort+'?rtcpport='+targetVideoPort+'&localrtcpport='+targetVideoPort+'&pkt_size=1316'; + let x264Params = ''; + if (self.ffmpegCodec === 'libx264') { + x264Params = '-preset ultrafast -tune zerolatency '; + } + + let ffmpegCommand = '-use_wallclock_as_timestamps 1 -i - -c:v ' + self.ffmpegCodec + ' -an -pix_fmt yuv420p ' + x264Params + '-payload_type 99 -ssrc ' + videoSsrc + ' -f rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params ' + videoKey.toString('base64') + ' srtp://'+targetAddress+':' + targetVideoPort+'?rtcpport='+targetVideoPort+'&localrtcpport='+targetVideoPort+'&pkt_size=1316'; //audio - https://github.com/KhaosT/homebridge-camera-ffmpeg/issues/9 //ffmpegCommand += ' -c:a libfdk_aac -profile:a aac_eld -vn -ac 1 -ar 16000 -b:a 8000 -flags +global_header -payload_type 110 -ssrc ' + audioSsrc + ' -f rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params '+audioKey.toString('base64')+' -rtsp_transport tcp srtp://'+targetAddress+':'+targetAudioPort+'?rtcpport='+targetAudioPort+'&localrtcpport='+targetAudioPort+'&pkt_size=188'; diff --git a/package.json b/package.json index 82134da..399001e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-nest-cam2", - "version": "1.2.0", + "version": "1.1.6", "description": "Nest cam plugin for homebridge: https://homebridge.io/", "license": "ISC", "keywords": [