homebridge#SnapshotRequest TypeScript Examples

The following examples show how to use homebridge#SnapshotRequest. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: streaming-delegate.ts    From homebridge-nest-cam with GNU General Public License v3.0 6 votes vote down vote up
handleSnapshotRequest(request: SnapshotRequest, callback: SnapshotRequestCallback): void {
    if (this.camera.info.properties['streaming.enabled']) {
      this.camera
        .getSnapshot(request.height)
        .then((snapshot) => {
          callback(undefined, snapshot);
        })
        .catch((error) => {
          handleError(this.log, error, `Error fetching snapshot for ${this.camera.info.name}`);
          callback(error);
        });
    } else {
      this.getOfflineImage(callback);
    }
  }
Example #2
Source File: new-streaming-delegate.ts    From homebridge-plugin-eufy-security with Apache License 2.0 6 votes vote down vote up
private determineResolution(
    request: SnapshotRequest | VideoInfo,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    isSnapshot: boolean,
  ): ResolutionInfo {
    const width = request.width;
    const height = request.height;
    //   if (!isSnapshot) {
    //     if ((this.videoConfig.forceMax && this.videoConfig.maxWidth) ||
    //       (request.width > this.videoConfig.maxWidth)) {
    //       width = this.videoConfig.maxWidth;
    //     }
    //     if ((this.videoConfig.forceMax && this.videoConfig.maxHeight) ||
    //       (request.height > this.videoConfig.maxHeight)) {
    //       height = this.videoConfig.maxHeight;
    //     }
    //   }

    const filters: Array<string> = ['scale=1280:720'];
    const noneFilter = filters.indexOf('none');
    if (noneFilter >= 0) {
      filters.splice(noneFilter, 1);
    }
    if (noneFilter < 0) {
      if (width > 0 || height > 0) {
        //   filters.push('scale=' + (width > 0 ? '\'min(' + width + ',iw)\'' : 'iw') + ':' +
        //     (height > 0 ? '\'min(' + height + ',ih)\'' : 'ih') +
        //     ':force_original_aspect_ratio=decrease');
        //   filters.push('scale=trunc(iw/2)*2:trunc(ih/2)*2'); // Force to fit encoder restrictions
        filters.push('scale=\'trunc(iw/2)*2\':\'trunc(ih/2)*2\''); // Force to fit encoder restrictions
      }
    }

    return {
      width: width,
      height: height,
      videoFilter: filters.join(','),
    };
  }
Example #3
Source File: streamingDelegate.ts    From homebridge-eufy-security with Apache License 2.0 6 votes vote down vote up
private determineResolution(request: SnapshotRequest | VideoInfo, isSnapshot: boolean): ResolutionInfo {
    const resInfo: ResolutionInfo = {
      width: request.width,
      height: request.height
    };
    if (!isSnapshot) {
      if (this.videoConfig.maxWidth !== undefined &&
        (this.videoConfig.forceMax || request.width > this.videoConfig.maxWidth)) {
        resInfo.width = this.videoConfig.maxWidth;
      }
      if (this.videoConfig.maxHeight !== undefined &&
        (this.videoConfig.forceMax || request.height > this.videoConfig.maxHeight)) {
        resInfo.height = this.videoConfig.maxHeight;
      }
    }

    const filters: Array<string> = this.videoConfig.videoFilter?.split(',') || [];
    const noneFilter = filters.indexOf('none');
    if (noneFilter >= 0) {
      filters.splice(noneFilter, 1);
    }
    resInfo.snapFilter = filters.join(',');
    if ((noneFilter < 0) && (resInfo.width > 0 || resInfo.height > 0)) {
      resInfo.resizeFilter = 'scale=' + (resInfo.width > 0 ? '\'min(' + resInfo.width + ',iw)\'' : 'iw') + ':' +
        (resInfo.height > 0 ? '\'min(' + resInfo.height + ',ih)\'' : 'ih') +
        ':force_original_aspect_ratio=decrease';
      filters.push(resInfo.resizeFilter);
      filters.push('scale=trunc(iw/2)*2:trunc(ih/2)*2'); // Force to fit encoder restrictions
    }

    if (filters.length > 0) {
      resInfo.videoFilter = filters.join(',');
    }

    return resInfo;
  }
Example #4
Source File: streamingDelegate.ts    From homebridge-eufy-security with Apache License 2.0 6 votes vote down vote up
async handleSnapshotRequest(request: SnapshotRequest, callback: SnapshotRequestCallback): Promise<void> {
    const resolution = this.determineResolution(request, true);

    try {
      const cachedSnapshot = !!this.snapshotPromise;

      this.log.debug('Snapshot requested: ' + request.width + ' x ' + request.height,
        this.cameraName, this.videoConfig.debug);

      const snapshot = await (this.snapshotPromise || this.fetchSnapshot(resolution.snapFilter));

      this.log.debug('Sending snapshot: ' + (resolution.width > 0 ? resolution.width : 'native') + ' x ' +
        (resolution.height > 0 ? resolution.height : 'native') +
        (cachedSnapshot ? ' (cached)' : ''), this.cameraName, this.videoConfig.debug);

      const resized = await this.resizeSnapshot(snapshot, resolution.resizeFilter);
      callback(undefined, resized);
    } catch (Error) {
      this.log.error(Error as string, this.cameraName);
      callback(Error as Error);
    }
  }
Example #5
Source File: new-streaming-delegate.ts    From homebridge-plugin-eufy-security with Apache License 2.0 5 votes vote down vote up
handleSnapshotRequest(
    request: SnapshotRequest,
    callback: SnapshotRequestCallback,
  ): void {
    const resolution = this.determineResolution(request, true);

    this.log.debug(
      'Snapshot requested: ' + request.width + ' x ' + request.height,
      this.cameraName,
      this.debug,
    );
    this.log.debug(
      'Sending snapshot: ' +
        (resolution.width > 0 ? resolution.width : 'native') +
        ' x ' +
        (resolution.height > 0 ? resolution.height : 'native'),
      this.cameraName,
      this.debug,
    );

    // get device info
    this.platform.httpService
      .listDevices({
        device_sn: this.device.device_sn,
      })
      .then(([device]) => {
        //   let ffmpegArgs = this.videoConfig.stillImageSource || this.videoConfig.source;
        let ffmpegArgs = `-i ${device.cover_path}`;

        ffmpegArgs += // Still
          ' -frames:v 1' +
          (resolution.videoFilter
            ? ' -filter:v ' + resolution.videoFilter
            : '') +
          ' -f image2 -';

        try {
          const ffmpeg = spawn(this.videoProcessor, ffmpegArgs.split(/\s+/), {
            env: process.env,
          });

          let imageBuffer = Buffer.alloc(0);
          this.log.debug(
            'Snapshot command: ' + this.videoProcessor + ' ' + ffmpegArgs,
            this.cameraName,
            this.debug,
          );
          ffmpeg.stdout.on('data', (data: Uint8Array) => {
            imageBuffer = Buffer.concat([imageBuffer, data]);
          });
          const log = this.log;
          ffmpeg.on('error', (error: string) => {
            log.error(
              'An error occurred while making snapshot request: ' + error,
              this.cameraName,
            );
          });
          ffmpeg.on('close', () => {
            callback(undefined, imageBuffer);
          });
        } catch (err) {
          this.log.error(err, this.cameraName);
          callback(err);
        }
      });
  }