UNPKG

homebridge-eufy-security-mikebcbc

Version:
533 lines 36.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FfmpegOptions = void 0; const settings_js_1 = require("../settings.js"); class FfmpegOptions { // Create an instance of a HomeKit streaming delegate. constructor(camera) { this.camera = camera; this.platform = this.camera.platform; this.log = this.platform.log; this.hwPixelFormat = []; this.log = camera.log; this.platform = camera.platform; this.camera = camera; // Configure our hardware acceleration support. this.configureHwAccel(); } // Determine the video encoder to use when transcoding. configureHwAccel() { let logMessage = ''; // Utility to return which hardware acceleration features are currently available to us. const accelCategories = () => { const categories = []; if (this.camera.hardwareDecoding) { categories.push('decoding'); } if (this.camera.hardwareTranscoding) { categories.push('transcoding'); } return categories.join(' and '); }; // Hardware-accelerated decoding is enabled by default, where supported. Let's select the decoder options accordingly where supported. if (this.camera.hardwareDecoding) { // Utility function to check that we have a specific decoder codec available to us. // eslint-disable-next-line @typescript-eslint/no-unused-vars const validateDecoder = (codec, pixelFormat) => { if (!this.platform.codecSupport.hasDecoder('h264', codec)) { this.log.error('Unable to enable hardware-accelerated decoding. Your video processor does not have support for the ' + codec + ' decoder. ' + 'Using software decoding instead.'); this.camera.hardwareDecoding = false; return false; } this.hwPixelFormat.push(...pixelFormat); return true; }; // Utility function to check that we have a specific decoder codec available to us. const validateHwAccel = (accel, pixelFormat) => { if (!this.platform.codecSupport.hasHwAccel(accel)) { this.log.error('Unable to enable hardware-accelerated decoding. Your video processor does not have support for the ' + accel + ' hardware accelerator. ' + 'Using software decoding instead.'); this.camera.hardwareDecoding = false; return false; } this.hwPixelFormat.push(...pixelFormat); return true; }; switch (this.platform.hostSystem) { case 'macOS.Apple': case 'macOS.Intel': // Verify that we have hardware-accelerated decoding available to us. validateHwAccel('videotoolbox', ['videotoolbox_vld', 'nv12', 'yuv420p']); break; case 'raspbian': // If it's less than the minimum hardware GPU memory we need on an Raspberry Pi, we revert back to our default decoder. if (this.platform.codecSupport.gpuMem < settings_js_1.PROTECT_RPI_GPU_MINIMUM) { this.log.info(`Disabling hardware-accelerated ${accelCategories()}. Adjust the GPU memory configuration on your Raspberry Pi to at least ${settings_js_1.PROTECT_RPI_GPU_MINIMUM} MB to enable it.`); this.camera.hardwareDecoding = false; this.camera.hardwareTranscoding = false; return false; } // Verify that we have the hardware decoder available to us. Unfortunately, at the moment, it seems that hardware decoding is flaky, at best, on Raspberry Pi. // validateDecoder("h264_mmal", [ "mmal", "yuv420p" ]); // validateDecoder("h264_v4l2m2ml", [ "yuv420p" ]); this.camera.hardwareDecoding = false; break; default: // Back to software decoding unless we're on a known system that always supports hardware decoding. this.camera.hardwareDecoding = false; break; } } // If we've enabled hardware-accelerated transcoding, let's select the encoder options accordingly where supported. if (this.camera.hardwareTranscoding) { // Utility function to check that we have a specific encoder codec available to us. const validateEncoder = (codec) => { if (!this.platform.codecSupport.hasEncoder('h264', codec)) { this.log.error('Unable to enable hardware-accelerated transcoding. Your video processor does not have support for the ' + codec + ' encoder. ' + 'Using software transcoding instead.'); this.camera.hardwareTranscoding = false; return false; } return true; }; switch (this.platform.hostSystem) { case 'macOS.Apple': case 'macOS.Intel': // Verify that we have the hardware encoder available to us. validateEncoder('h264_videotoolbox'); // Validate that we have access to the AudioToolbox AAC encoder. if (!this.platform.codecSupport.hasEncoder('aac', 'aac_at')) { this.log.error('Your video processor does not have support for the native macOS AAC encoder, aac_at. Will attempt to use libfdk_aac instead.'); } break; case 'raspbian': // Verify that we have the hardware encoder available to us. validateEncoder('h264_v4l2m2m'); logMessage = 'Raspberry Pi hardware acceleration will be used for livestreaming. ' + 'HomeKit Secure Video recordings are not supported by the hardware encoder and will use software transcoding instead'; // Ensure we have the pixel format the Raspberry Pi GPU is expecting available to us, if it isn't already. if (!this.hwPixelFormat.includes('yuv420p')) { this.hwPixelFormat.push('yuv420p'); } break; default: // Let's see if we have Intel QuickSync hardware decoding available to us. if (this.platform.codecSupport.hasHwAccel('qsv') && this.platform.codecSupport.hasDecoder('h264', 'h264_qsv') && this.platform.codecSupport.hasEncoder('h264', 'h264_qsv')) { this.camera.hardwareDecoding = true; this.hwPixelFormat.push('qsv', 'yuv420p'); logMessage = 'Intel Quick Sync Video'; } else { // Back to software encoding. this.camera.hardwareDecoding = false; this.camera.hardwareTranscoding = false; } break; } } // Inform the user. if (this.camera.hardwareDecoding || this.camera.hardwareTranscoding) { this.log.info(`Hardware-accelerated ${accelCategories()} enabled${logMessage.length ? ': ' + logMessage : ''}.`); } return this.camera.hardwareTranscoding; } // Return the audio encoder options to use when transcoding. get audioEncoder() { // If we don't have libfdk_aac available to us, we're essentially dead in the water. let encoderOptions = []; // Utility function to return a default audio encoder codec. const defaultAudioEncoderOptions = () => { if (this.platform.codecSupport.hasEncoder('aac', 'libfdk_aac')) { // Default to libfdk_aac since FFmpeg doesn't natively support AAC-ELD. We use the following options by default: // // -acodec libfdk_aac Use the libfdk_aac encoder. // -afterburner 1 Increases audio quality at the expense of needing a little bit more computational power in libfdk_aac. // -eld_sbr 1 Use spectral band replication to further enhance audio. // -eld_v2 1 Use the enhanced low delay v2 standard for better audio characteristics. return [ '-acodec', 'libfdk_aac', '-afterburner', '1', '-eld_sbr', '1', '-eld_v2', '1', ]; } else { return []; } }; switch (this.platform.hostSystem) { case 'macOS.Apple': case 'macOS.Intel': // If we don't have audiotoolbox available, let's default back to libfdk_aac. if (!this.platform.codecSupport.hasEncoder('aac', 'aac_at')) { encoderOptions = defaultAudioEncoderOptions(); break; } // aac_at is the macOS audio encoder API. We use the following options: // // -acodec aac_at Use the aac_at encoder on macOS. // -aac_at_mode cvbr Use the constrained variable bitrate setting to allow the encoder to optimize audio, while remaining within the requested bitrates. encoderOptions = [ '-acodec', 'aac_at', '-aac_at_mode', 'cvbr', ]; break; default: encoderOptions = defaultAudioEncoderOptions(); break; } return encoderOptions; } // Return the audio encoder to use when decoding. get audioDecoder() { return 'libfdk_aac'; } // Return the video decoder options to use when decoding video. get videoDecoder() { // Default to no special decoder options for inbound streams. let decoderOptions = []; // If we've enabled hardware-accelerated transcoding, let's select decoder options accordingly where supported. if (this.camera.hardwareDecoding) { switch (this.platform.hostSystem) { case 'macOS.Apple': case 'macOS.Intel': // h264_videotoolbox is the macOS hardware decoder and encoder API. We use the following options for decoding video: // // -hwaccel videotoolbox Select Video Toolbox for hardware-accelerated H.264 decoding. decoderOptions = [ '-hwaccel', 'videotoolbox', ]; break; case 'raspbian': // h264_mmal is the preferred Raspberry Pi hardware decoder codec. We use the following options for decoding video: // // -c:v h264_mmal Select the Multimedia Abstraction Layer codec for hardware-accelerated H.264 processing. decoderOptions = [ // "-c:v", "h264_mmal" ]; break; default: // h264_qsv is the Intel Quick Sync Video hardware encoder and decoder. // // -hwaccel qsv Select Quick Sync Video to enable hardware-accelerated H.264 decoding. // -c:v h264_qsv Select the Quick Sync Video codec for hardware-accelerated H.264 processing. decoderOptions = [ '-hwaccel', 'qsv', '-hwaccel_output_format', 'qsv', '-c:v', 'h264_qsv', ]; break; } } return decoderOptions; } // Utility function to provide our default encoder options. defaultVideoEncoderOptions(width, height, fps, bitrate, profile, level, idrInterval, inputFps, useSmartQuality = true) { var _a; const videoFilters = []; // Set our FFmpeg video filter options: // // format= Set the pixel formats we want to target for output. videoFilters.push('format=' + [...new Set([...this.hwPixelFormat, 'yuvj420p'])].join('|')); // fps=fps= Use the fps filter to provide the frame rate requested by HomeKit. This has better performance characteristics for Protect // rather than using "-r". We only need to apply this filter if our input and output frame rates aren't already identical. if (fps !== inputFps) { videoFilters.push('fps=fps=' + fps.toString()); } // scale=-2:min(ih\,height) Scale the video to the size that's being requested while respecting aspect ratios and ensuring our final dimensions are // a power of two. videoFilters.push('scale=-2:min(ih\\,' + height.toString() + ')'); // Default to the tried-and-true libx264. We use the following options by default: // // -c:v libx264 Use the excellent libx264 H.264 encoder by default, unless the user explicitly overrides it. // -preset veryfast Use the veryfast encoding preset in libx264, which provides a good balance of encoding speed and quality. // -profile:v Use the H.264 profile that HomeKit is requesting when encoding. // -level:v Use the H.264 profile level that HomeKit is requesting when encoding. // -noautoscale Don't attempt to scale the video stream automatically. // -bf 0 Disable B-frames when encoding to increase compatibility against occasionally finicky HomeKit clients. // -filter:v Set the pixel format and scale the video to the size we want while respecting aspect ratios and ensuring our final // dimensions are a power of two. // -g:v Set the group of pictures to the number of frames per second * the interval in between keyframes to ensure a solid // livestreamng exerience. // -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate. // -maxrate bitrate The maximum bitrate tolerance, used with -bufsize. This provides an upper bound on bitrate, with a little bit extra to // allow encoders some variation in order to maximize quality while honoring bandwidth constraints. const encoderOptions = [ // If the user has specified a video encoder, let's use it instead. '-c:v', (_a = this.platform.config.videoEncoder) !== null && _a !== void 0 ? _a : 'libx264', '-preset', 'veryfast', '-profile:v', this.getH264Profile(profile), '-level:v', this.getH264Level(level), '-noautoscale', '-bf', '0', '-filter:v', videoFilters.join(', '), '-g:v', (fps * idrInterval).toString(), '-bufsize', (2 * bitrate).toString() + 'k', '-maxrate', (bitrate + (useSmartQuality ? settings_js_1.PROTECT_HOMEKIT_STREAMING_HEADROOM : 0)).toString() + 'k', ]; // Using libx264's constant rate factor mode produces generally better results across the board. We use a capped CRF approach, allowing libx264 to // make intelligent choices about how to adjust bitrate to achieve a certain quality level depending on the complexity of the scene being encoded, but // constraining it to a maximum bitrate to stay within the bandwidth constraints HomeKit is requesting. if (useSmartQuality) { // -crf 20 Use a constant rate factor of 20, to allow libx264 the ability to vary bitrates to achieve the visual quality we // want, constrained by our maximum bitrate. encoderOptions.push('-crf', '20'); } else { // For recording HKSV, we really want to maintain a tight rein on bitrate and don't want to freelance with perceived quality for two reasons - HKSV // is very latency sensitive and it's also very particular about bitrates and the specific format of the stream it receives. The second reason is that // HKSV typically requests bitrates of around 2000kbps, which results in a reasonably high quality recording, as opposed to the typical 2-300kbps // that livestreaming from the Home app itself generates. Those lower bitrates in livestreaming really benefit from the magic that using a good CRF value // can produce in libx264. encoderOptions.push('-b:v', bitrate.toString() + 'k'); } return encoderOptions; } // Return the video encoder options to use for HKSV. recordEncoder(width, height, fps, bitrate, profile, level, idrInterval, inputFps) { // Generaly, we default to using the same encoding options we use to transcode livestreams, unless we have platform-specific quirks we need to address, // such as where we can have hardware-accelerated transcoded livestreaming, but not hardware-accelerated HKSV event recording. The other noteworthy // aspect here is that HKSV is quite specific in what it wants, and isn't vary tolerant of creative license in how you may choose to alter bitrate to // address quality. When we call our encoders, we also let them know we don't want any additional quality optimizations when transcoding HKSV events. switch (this.platform.hostSystem) { case 'raspbian': // Raspberry Pi struggles with hardware-accelerated HKSV event recording due to issues in the FFmpeg codec driver, currently. We hope this improves // over time and can offer it to Pi users, or develop a workaround. For now, we default to libx264. return this.defaultVideoEncoderOptions(width, height, fps, bitrate, profile, level, idrInterval, inputFps, false); break; default: // By default, we use the same options for HKSV and streaming. return this.streamEncoder(width, height, fps, bitrate, profile, level, idrInterval, inputFps, false); } } // Return the video encoder options to use when transcoding. streamEncoder(width, height, fps, bitrate, profile, level, idrInterval, inputFps, useSmartQuality = true) { // In case we don't have a defined pixel format. if (!this.hwPixelFormat.length) { this.hwPixelFormat.push('yuvj420p'); } // If we aren't hardware-accelerated, we default to libx264. if (!this.camera.hardwareTranscoding) { return this.defaultVideoEncoderOptions(width, height, fps, bitrate, profile, level, idrInterval, inputFps, useSmartQuality); } // If we've enabled hardware-accelerated transcoding, let's select encoder options accordingly. // // We begin by adjusting the maximum bitrate tolerance used with -bufsize. This provides an upper bound on bitrate, with a little bit extra to allow encoders some // variation in order to maximize quality while honoring bandwidth constraints. const adjustedMaxBitrate = bitrate + (useSmartQuality ? settings_js_1.PROTECT_HOMEKIT_STREAMING_HEADROOM : 0); // Check the input and output frame rates to see if we need to change it. const useFpsFilter = fps !== inputFps; // Initialize our options. const encoderOptions = []; let videoFilters = []; // Set our FFmpeg video filter options: // // format= Set the pixel formats we want to target for output. videoFilters.push('format=' + this.hwPixelFormat.join('|')); // fps=fps= Use the fps filter to provide the frame rate requested by HomeKit. This has better performance characteristics for Protect // rather than using "-r". We only need to apply this filter if our input and output frame rates aren't already identical. if (useFpsFilter) { videoFilters.push('fps=fps=' + fps.toString()); } // scale=-2:min(ih\,height) Scale the video to the size that's being requested while respecting aspect ratios and ensuring our final dimensions are // a power of two. videoFilters.push('scale=-2:min(ih\\,' + height.toString() + ')'); switch (this.platform.hostSystem) { case 'macOS.Apple': // h264_videotoolbox is the macOS hardware encoder API. We use the following options on Apple Silicon: // // -c:v Specify the macOS hardware encoder, h264_videotoolbox. // -allow_sw 1 Allow the use of the software encoder if the hardware encoder is occupied or unavailable. // This allows us to scale when we get multiple streaming requests simultaneously that might consume all the available encode engines. // -realtime 1 We prefer speed over quality - if the encoder has to make a choice, sacrifice one for the other. // -coder cabac Use the cabac encoder for better video quality with the encoding profiles we use in HBUP. // -profile:v Use the H.264 profile that HomeKit is requesting when encoding. // -level:v 0 We override what HomeKit requests for the H.264 profile level on macOS when we're using hardware-accelerated transcoding because // the hardware encoder is particular about how to use levels. Setting it to 0 allows the encoder to decide for itself. // -bf 0 Disable B-frames when encoding to increase compatibility against occasionally finicky HomeKit clients. // -noautoscale Don't attempt to scale the video stream automatically. // -filter:v Set the pixel format, adjust the frame rate if needed, and scale the video to the size we want while respecting aspect ratios and // ensuring our final dimensions are a power of two. // -g:v Set the group of pictures to the number of frames per second * the interval in between keyframes to ensure a solid // livestreamng exerience. // -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate. // -maxrate bitrate The maximum bitrate tolerance used in concert with -bufsize to constrain the maximum bitrate permitted. encoderOptions.push('-c:v', 'h264_videotoolbox', '-allow_sw', '1', '-realtime', '1', '-coder', 'cabac', '-profile:v', this.getH264Profile(profile), '-level:v', '0', '-bf', '0', '-noautoscale', '-filter:v', videoFilters.join(', '), '-g:v', (fps * idrInterval).toString(), '-bufsize', (2 * bitrate).toString() + 'k', '-maxrate', adjustedMaxBitrate.toString() + 'k'); if (useSmartQuality) { // -q:v 90 Use a fixed quality scale of 90, to allow videotoolbox the ability to vary bitrates to achieve the visual quality we want, // constrained by our maximum bitrate. This is an Apple Silicon-specific feature. encoderOptions.push('-q:v', '90'); } else { // -b:v Average bitrate that's being requested by HomeKit. encoderOptions.push('-b:v', bitrate.toString() + 'k'); } return encoderOptions; break; case 'macOS.Intel': // h264_videotoolbox is the macOS hardware encoder API. We use the following options on Intel-based Macs: // // -c:v Specify the macOS hardware encoder, h264_videotoolbox. // -allow_sw 1 Allow the use of the software encoder if the hardware encoder is occupied or unavailable. // This allows us to scale when we get multiple streaming requests simultaneously that might consume all the available encode engines. // -realtime 1 We prefer speed over quality - if the encoder has to make a choice, sacrifice one for the other. // -coder cabac Use the cabac encoder for better video quality with the encoding profiles we use in HBUP. // -profile:v Use the H.264 profile that HomeKit is requesting when encoding. // -level:v 0 We override what HomeKit requests for the H.264 profile level on macOS when we're using hardware-accelerated transcoding because // the hardware encoder is particular about how to use levels. Setting it to 0 allows the encoder to decide for itself. // -bf 0 Disable B-frames when encoding to increase compatibility against occasionally finicky HomeKit clients. // -noautoscale Don't attempt to scale the video stream automatically. // -filter:v Set the pixel format, adjust the frame rate if needed, and scale the video to the size we want while respecting aspect ratios and // ensuring our final dimensions are a power of two. // -b:v Average bitrate that's being requested by HomeKit. We can't use a quality constraint and allow for more optimization of the bitrate // on Intel-based Macs due to hardware / API limitations. // -g:v Set the group of pictures to the number of frames per second * the interval in between keyframes to ensure a solid // livestreamng exerience. // -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate. // -maxrate bitrate The maximum bitrate tolerance used in concert with -bufsize to constrain the maximum bitrate permitted. return [ '-c:v', 'h264_videotoolbox', '-allow_sw', '1', '-realtime', '1', '-coder', 'cabac', '-profile:v', this.getH264Profile(profile), '-level:v', '0', '-bf', '0', '-noautoscale', '-filter:v', videoFilters.join(', '), '-b:v', bitrate.toString() + 'k', '-g:v', (fps * idrInterval).toString(), '-bufsize', (2 * bitrate).toString() + 'k', '-maxrate', adjustedMaxBitrate.toString() + 'k', ]; break; case 'raspbian': // h264_v4l2m2m is the preferred interface to the Raspberry Pi hardware encoder API. We use the following options: // // -c:v Specify the Raspberry Pi hardware encoder, h264_v4l2m2m. // -noautoscale Don't attempt to scale the video stream automatically. // -filter:v Set the pixel format, adjust the frame rate if needed, and scale the video to the size we want while respecting aspect ratios and // ensuring our final dimensions are a power of two. // -b:v Average bitrate that's being requested by HomeKit. We can't use a quality constraint and allow for more optimization of the bitrate // due to v4l2m2m limitations. // -g:v Set the group of pictures to the number of frames per second * the interval in between keyframes to ensure a solid // livestreamng exerience. // -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate. // -maxrate bitrate The maximum bitrate tolerance used in concert with -bufsize to constrain the maximum bitrate permitted. return [ '-c:v', 'h264_v4l2m2m', '-profile:v', this.getH264Profile(profile, true), '-bf', '0', '-noautoscale', '-reset_timestamps', '1', '-filter:v', videoFilters.join(', '), '-b:v', bitrate.toString() + 'k', '-g:v', (fps * idrInterval).toString(), '-bufsize', (2 * bitrate).toString() + 'k', '-maxrate', adjustedMaxBitrate.toString() + 'k', ]; break; default: // Clear out any prior video filters. videoFilters = []; // We execute the following GPU-accelerated operations using the Quick Sync Video post-processing filter: // // format=same Set the output pixel format to the same as the input, since it's already in the GPU. // w=...:h... Scale the video to the size that's being requested while respecting aspect ratios. videoFilters.push('vpp_qsv=' + [ 'format=same', 'w=min(iw\\, (iw / ih) * ' + height.toString() + ')', 'h=min(ih\\, ' + height.toString() + ')', ].join(':')); // fps=fps= Use the fps filter to provide the frame rate requested by HomeKit. This has better performance characteristics for Protect // rather than using "-r". We only need to apply this filter if our input and output frame rates aren't already identical. if (useFpsFilter) { videoFilters.push('fps=fps=' + fps.toString()); } // h264_qsv is the Intel Quick Sync Video hardware encoder API. We use the following options: // // -c:v Specify the macOS hardware encoder, h264_videotoolbox. // -profile:v Use the H.264 profile that HomeKit is requesting when encoding. // -level:v 0 We override what HomeKit requests for the H.264 profile level when we're using hardware-accelerated transcoding because // the hardware encoder will determine which levels to use. Setting it to 0 allows the encoder to decide for itself. // -bf 0 Disable B-frames when encoding to increase compatibility against occasionally finicky HomeKit clients. // -noautoscale Don't attempt to scale the video stream automatically. // -init_hw_device Initialize our hardware accelerator and assign it a name to be used in the FFmpeg command line. // -filter_hw_device Specify the hardware accelerator to be used with our video filter pipeline. // -filter:v Set the pixel format, adjust the frame rate if needed, and scale the video to the size we want while respecting aspect ratios and // ensuring our final dimensions are a power of two. // -g:v Set the group of pictures to the number of frames per second * the interval in between keyframes to ensure a solid // livestreamng exerience. // -bufsize size This is the decoder buffer size, which drives the variability / quality of the output bitrate. // -maxrate bitrate The maximum bitrate tolerance used in concert with -bufsize to constrain the maximum bitrate permitted. encoderOptions.push('-c:v', 'h264_qsv', '-profile:v', this.getH264Profile(profile), '-level:v', '0', '-bf', '0', '-noautoscale', '-init_hw_device', 'qsv=hw', '-filter_hw_device', 'hw', '-filter:v', videoFilters.join(', '), '-g:v', (fps * idrInterval).toString(), '-bufsize', (2 * bitrate).toString() + 'k', '-maxrate', adjustedMaxBitrate.toString() + 'k'); if (useSmartQuality) { // -global_quality 20 Use a global quality setting of 20, to allow QSV the ability to vary bitrates to achieve the visual quality we want, // constrained by our maximum bitrate. This leverages a QSV-specific feature known as intelligent constant quality. encoderOptions.push('-global_quality', '20'); } else { // -b:v Average bitrate that's being requested by HomeKit. encoderOptions.push('-b:v', bitrate.toString() + 'k'); } return encoderOptions; break; } } // Return the maximum pixel count supported by a specific hardware encoder on the host system. get hostSystemMaxPixels() { if (this.camera.hardwareTranscoding) { switch (this.platform.hostSystem) { case 'raspbian': // For constrained environments like Raspberry Pi, when hardware transcoding has been selected for a camera, we limit the available source // streams to no more than 1080p. In practice, that means that devices like the G4 Pro can't use their highest quality stream for // transcoding due to the limitations of the Raspberry Pi GPU that cannot support higher pixel counts. return 1920 * 1080; break; default: break; } } return 0; } // Translate HomeKit H.264 level information for FFmpeg. getH264Level(level, numeric = false) { switch (level) { case 0 /* H264Level.LEVEL3_1 */: return numeric ? '31' : '3.1'; break; case 1 /* H264Level.LEVEL3_2 */: return numeric ? '32' : '3.2'; break; case 2 /* H264Level.LEVEL4_0 */: return numeric ? '40' : '4.0'; break; default: return numeric ? '31' : '3.1'; break; } } // Translate HomeKit H.264 profile information for FFmpeg. getH264Profile(profile, numeric = false) { switch (profile) { case 0 /* H264Profile.BASELINE */: return numeric ? '66' : 'baseline'; break; case 2 /* H264Profile.HIGH */: return numeric ? '100' : 'high'; break; case 1 /* H264Profile.MAIN */: return numeric ? '77' : 'main'; break; default: return numeric ? '77' : 'main'; break; } } } exports.FfmpegOptions = FfmpegOptions; //# sourceMappingURL=ffmpeg-options.js.map