# OpenIPC Wiki [Table of Content](../README.md) Majestic example config ----------------------- Majestic reads `/etc/majestic.yaml`. A camera only needs the keys it wants to change from the defaults, so a working file is usually much shorter than what follows — this page is a reference of what exists, not a file to paste whole. `/etc/majestic.full` on the camera is a shorter sample of the same thing. Majestic keeps it that way. When it saves the file — from the WebUI, the API, or after a `cli` write — it writes only the keys that differ from the defaults this build carries, so a value you never changed stays absent rather than being frozen at whatever the default happened to be when you last pressed Save. That is deliberate: it is what lets a default corrected in a later version reach a camera that has already been configured. Two ways to check a key against the build you are actually running, which beats trusting any wiki page: ``` curl http://localhost/api/v1/config.json # every key this binary has, with defaults and ranges curl 'http://localhost/api/v1/set?video0.fps=10' # applies live and saves; 404 if the key is unknown ``` Sections marked *(build-dependent)* only exist in some builds — see [Lite, Ultimate and FPV](majestic-streamer.md#lite-ultimate-and-fpv). Sections marked *(platform-dependent)* only exist on the SoCs that can act on them. ``` system: webPort: 80 httpsPort: 443 #httpsCertificate: /etc/ssl/certs/www.example.com.crt #httpsCertificateKey: /etc/ssl/private/www.example.com.key logLevel: debug buffer: 1024 plugins: false # load /usr/lib/.so, see "Majestic plugins" #telemetry: true # anonymous install counter (MAC, uptime, chip, # sensor, flash/SD size) sent as a DNS query #unsafe: false # true disables ALL authentication #staticDir: /var/www # where the web interface is served from # (platform-dependent) Most of this section is per-vendor; the platforms that # read each key are noted. A key your build does not have answers 404. isp: #sensorConfig: /etc/sensors/imx222_1080p_line.ini # path, or just the sensor name antiFlicker: disabled # disabled | 50 | 60 -- match your mains, not # your fps; see "Anti-flicker" in majestic-streamer.md #blkCnt: 4 #drc: 300 # dynamic range compression, 0-255 through # hi3516cv500 and 0-1023 from hi3516ev200 # upwards. Left unset the camera keeps the # sensor profile's own automatic curve, which # is usually the better picture -- set it only # if you have compared. A value above the # range is refused. #rawMode: slow # none | slow | fast #iqProfile: #lowDelay: false #awbMode: auto # auto|manual|day|cloudy|incandescent| # flourescent|twilight|shade|warm|custom #memMode: reduction # normal | reduction (HiSilicon/Goke) #slowShutter: medium # disabled|low|medium|high (HiSilicon/Goke) # medium is the DEFAULT, not disabled: a camera # that sets nothing is already in slow shutter, # which also fills in the exposure and gain # limits below that you did not give #dis: false # digital stabilisation (HiSilicon/Goke, Ingenic) #wdr: 0 # (SigmaStar) #edgeGain: false # (SigmaStar) #iqServer: false # (SigmaStar) #pad: 0 # (SigmaStar) #yuvCompression: auto # HiSilicon gen 3/4 only; saves ~1/3 of the main # frame buffer, ignored with rotate/mirror/masks #suspendWhenIdle: false # HiSilicon/Goke: stop the sensor and ISP when # nothing wants frames -- see majestic-streamer.md #suspendIdleSeconds: 5 # grace period before it does, 1-300 # Exposure and gain. Zero, or absent, leaves the sensor default alone. # The SAME KEY MEANS DIFFERENT THINGS per vendor -- see "Exposure and gain" # in majestic-streamer.md before copying a number between platforms. # # TWO OF THESE NEED A SEPTEMBER 2026 OR NEWER BUILD. aeMode does not exist # before that and is rejected. The three gains were written in the sensor's # own fixed-point units on HiSilicon/Goke, where 8x was 8192 -- on an older # build, 8 asks for 8/1024 of unity and not for eight times. Check with # curl http://localhost/api/v1/config.schema.json if you are unsure. #aeMode: auto # auto | manual (HiSilicon/Goke, 2026-09+) # auto: the four below are limits auto-exposure # works inside. manual: they are the values, and # the picture stops following the light #exposure: 0 # HiSilicon/Goke and SigmaStar: MILLISECONDS, # the longest auto-exposure may use (also caps # the frame rate). Ingenic: MICROSECONDS, and it # is the exposure itself -- setting it stops the # ISP metering # (HiSilicon/Goke, SigmaStar, Ingenic T31) #aGain: 0 # analog gain, as a MULTIPLIER (8 means 8x) on a # 2026-09+ build; see the note above for older # (HiSilicon/Goke, SigmaStar) #dGain: 0 # sensor digital gain, as a multiplier # (HiSilicon/Goke) #ispGain: 0 # ISP digital gain, as a multiplier. Applied # after the raw data is read, so it brightens # the picture and not a RAW snapshot # (HiSilicon/Goke) # Exposure is a DECIMAL on HiSilicon/Goke and SigmaStar, so 0.5 is half a # millisecond -- 1/2000 s. Ingenic rounds to a microsecond. # # WHERE auto-exposure looks, and which end of the histogram it protects. # Both need a September 2026 or newer build, and neither exists on every # part -- an absent key is how a camera says it cannot. See "Telling # auto-exposure where to look" in majestic-streamer.md. #meterRect: "" # XxYxWxH, like motionDetect.roi. Empty meters # the whole picture. Only the FIRST rectangle # is used. The window has a minimum of 256x120 # and a smaller one is grown around its centre # (hi3516cv500/av300/dv300, hi3516ev200/ev300, # gk7205v200/v300/v500) #aeStrategy: default # default | highlight | lowlight # (HiSilicon/Goke, not the oldest hi3518 parts # and not hi3516cv6xx) # Three parts of the picture the camera used to set at every start with no # way to say otherwise. Every default below is what it did before, so # leaving them absent changes nothing. Only dehaze is an off switch: false # on the other two means "stop overriding the sensor's own tuning", which # may itself sharpen or denoise. Changing sharpen or nr restarts the video; # dehaze applies to the running stream. September 2026 or newer. #dehaze: 125 # 0-255; 0 switches dehazing off. Applies # without restarting the video, so it is worth # trying at several values. Automatic image # tuning drives this key -- see image.tuning # (hi3516ev200/ev300, gk7205v200/v300/v500) #sharpen: true # false stops the camera applying its own # (hi3516ev200/ev300, gk7205v200/v300/v500) #nr: true # false leaves the sensor's noise reduction # (hi3516ev200/ev300, gk7205v200/v300/v500) # A motorised lens aperture, and — on the oldest HiSilicon parts — the thing # that decides who owns a PWM channel. See "Iris control" in Majestic # streamer before setting any of it. #iris: # type: none # none | DC | P (HiSilicon/Goke) # P is accepted by the schema and implemented # nowhere; it is refused with a message. # On hi3516cv100/hi3518ev100 this key is the # ONLY one of the group that exists, and it is # what tells a camera with a real iris apart # from one whose PWM belongs to its lamp # manual: false # hold the aperture instead of metering it # The eight keys below exist from hi3516cv200 # upwards, but not on hi3516cv6xx # holdValue: 610 # where to hold it, per-mille, 0-1000 # kp: 7000 # the controller that drives the aperture: # ki: 100 # proportional, integral and derivative terms, # kd: 3000 # 0-100000 / 0-1000 / 0-100000 # minPwmDuty: 250 # how far it may close, per-mille, 0-1000 # maxPwmDuty: 950 # how far it may open, per-mille, 0-1000 # openPwmDuty: 800 # where it parks when opening, 0-1000 image: mirror: false flip: false rotate: 0 # 0 | 90 | 270 # The four below are the picture as you set it. With tuning on they are also # the starting point the camera works from and the values it returns to -- # it never writes them back, so this file keeps saying what you set even # while the camera is running something else. hue is never driven. contrast: 50 saturation: 50 luminance: 50 hue: 50 #tuning: true # follow the scene: adjust contrast, luminance, # saturation and isp.dehaze as the light and # the weather change, and give them back when # the scene no longer needs them. ON BY # DEFAULT from September 2026. Does nothing to # a picture that already uses its range, and # stands down as the sensor gain rises, # because stretching a noisy picture only # amplifies the noise. Watch it on /metrics # (image_tune_*) or on Camera -> Settings -> # Live. Needs an uncompressed main stream to # measure: see isp.yuvCompression. Changing it # restarts the video. # See "Automatic image tuning" # (HiSilicon/Goke) video0: enabled: true codec: h264 # h264 | h265 #size: 1920x1080 fps: 20 bitrate: 4096 rcMode: vbr # cbr | vbr | avbr — cbr holds `bitrate` as a # target, vbr treats it as a ceiling, avbr as a # ceiling it may drift around #profile: main # base | main | high gopSize: 1.0 #gopMode: normal # normal | dual | smart #adjustBitrate: true # may a WebRTC viewer on a thin link lower this # channel's rate; turn off for a channel feeding # an NVR, a recorder or an outgoing publisher #osd: true # draw the overlay on THIS stream. The overlay is # rendered per stream and sized for this stream's # own frame, so turning it off here leaves the # other streams stamped. Privacy masks are not # affected — see "On-screen display and privacy # masks" #svct: off # off | 2x | 4x — see "Majestic encoder tuning" # Encoder reference structure. Every P frame references the keyframe, so # one lost frame costs one frame. Wants a SHORT gopSize (~1.0). See # "Majestic encoder tuning". Each key here is skipped when absent, so # leaving it out changes nothing. #refEnhance: 0 #refPred: false # SigmaStar, video0 only: cyclic intra refresh, 3DNR, ROI and ISP bypass #intraLine: 8 #intraQp: false #noiseLevel: 2 #roiRect: # - 0x0x640x360 #roiQp: "-5" #bypass: 0 #crop: 0x0x960x540 # Split a picture into several NAL slices, so one lost packet costs part of a # frame instead of all of it. #sliceUnits: 4 # macroblock rows per slice (HiSilicon/Goke, SigmaStar) #sliceBytes: 0 # target bytes per slice; wins over sliceUnits # when both are set (HiSilicon/Goke) # Quantiser bounds — how much compression rate control is allowed to use. # maxQp is the important one: set it too low and the encoder runs out of # room to compress and exceeds `bitrate` instead of meeting it. The defaults # are per-vendor and maxQp's rose in September 2026, but a default only # applies to a key you have not set — a config written before then keeps # what it holds, and updating the firmware will not change it. Read them # back from /api/v1/config.json rather than assuming the numbers here. See # "When the camera exceeds the bitrate you set". #minQp: 28 #maxQp: 42 video1: enabled: false codec: h264 size: 704x576 fps: 15 #osd: true # as video0.osd, and on by default here too: a # sub stream carries the overlay unless this is # turned off # video1 takes the same keys as video0 jpeg: enabled: true # JPEG as a whole. false frees the snapshot # channel's frame, but /image.jpg then answers # 503 and /mjpeg is unavailable -- ONVIF # snapshots and the WebUI preview with them qfactor: 50 fps: 5 # MJPEG stream only #size: 160x120 # applies to /mjpeg AND /image.jpg #osd: true # burn the OSD into JPEG output, sized for the # snapshot's own frame rather than the main # stream's rtsp: false # also publish MJPEG over RTSP (max 2040 px/axis) #tuned: off # HiSilicon/Goke only: largest /image.jpg?width=... # to serve, e.g. 1920x1080. Needs a restart. #toProgressive: false # Ultimate only: send /image.jpg progressively, # so a slow link paints a whole coarse picture # first instead of a sharp band at a time. Same # image, ~5% smaller, and costs CPU per snapshot # (build-dependent: on Goke gk7205v200/v500 builds that carry the USB dual-role # package. It is the first platform to get this and is being treated as such; # other SoCs are planned once it has been tested in the field. If your camera # does not have these keys, its build does not have the feature -- a key that is # not there answers 404 to the HTTP API and is ignored in the file.) # # A USB (UVC) webcam plugged into the camera's USB port, published as a SECOND # camera alongside the built-in sensor. # # It publishes ONE stream, and which one depends on `codec` below: MJPEG mode # is /stream=5, and h264 or transcode is /stream=3. There is no sub stream -- # a webcam is one camera sending one thing. The id is 3 * cameraId + subtype, # with subtype 0 for main and 2 for MJPEG, so a different cameraId moves it. # Ask /api/v1/sources rather than working it out; see "A second camera" in # Majestic streamer. # # The port does one job at a time: usbcam consumes a webcam, uvcgadget below # makes this camera BE one. Turning both on is refused. #usbcam: #enabled: false #device: /dev/video0 # the node the webcam appeared as. It is a # per-boot fact, not a fixed name -- the WebUI's # USB page writes whichever one it landed on #codec: auto # auto | mjpeg | h264 | transcode # auto picks what the webcam offers: MJPEG for # most of them, native H.264 for a C920-class # camera. transcode captures raw and re-encodes # on the SoC, which is the only way to get an # H.264 stream out of a webcam that has none #cameraId: 1 # which camera it is published as #size: 1280x720 # capture size. On transcode this is the size # the SoC has to convert every frame at, in # SOFTWARE where the SoC has no converter for # the webcam's pixel format -- 1280x720 at 30fps # saturates a gk7205v200 to the point of losing # the shell. Ask for 640x480 there #fps: 30 #bitrate: 4096 # transcode only #sliceUnits: 0 # transcode only # (build-dependent: the same builds as usbcam above) # # The other direction: the camera IS the USB device, and a computer it is # plugged into sees a webcam. Mutually exclusive with usbcam -- one controller, # one role at a time -- and switching between them is what the WebUI's USB page # is for. #uvcgadget: #enabled: false #device: /dev/video1 # the gadget node, also a per-boot fact #format: mjpeg # mjpeg | h264 -- which encoded stream is fed to # the computer. It has to match a format the # gadget was set up with at boot osd: enabled: false # the TEXT overlay. Privacy masks below are not # part of it and do not need it. Which streams # get the text is then video0.osd / video1.osd / # jpeg.osd, each on by default font: /usr/share/fonts/truetype/UbuntuMono-Regular.ttf template: "%d.%m.%Y %H:%M:%S" #size: "1.0" # font scale factor #weight: normal # normal | thin #outline: true #bgAlpha: 25 # plate opacity, 0-100 # Placement. anchor: proportional (the default) uses posX/posY on their # -16..16 scale; any other anchor uses offsetX/offsetY, measured inward from # that corner or edge. An axis the anchor centres ignores its offset. #anchor: proportional # proportional | top-left | top | top-right | # left | center | right | bottom-left | bottom | # bottom-right #offsetX: "0" #offsetY: "0" posX: 16 posY: 16 # Rectangles of the picture to black out, written against the MAIN stream's # frame and scaled into each of the others. They cover every stream that is # running -- both video channels and the snapshot -- and a rectangle covering # nothing is ignored. See "On-screen display and privacy masks" for what each # SoC family can and cannot do. #privacyMasks: 0x0x234x640,2124x0x468x1300 # (build-dependent: absent from FPV builds) audio: enabled: false volume: 30 # 0 mutes the input #gain: 0 # 0-31, analogue gain srate: 8000 # 8000|16000|32000|48000 codec: opus # opus | aac | pcm | alaw | ulaw (| mp3, Ultimate) outputEnabled: false outputVolume: 30 #outputGain: 0 #speakerPin: 32 #speakerPinInvert: false #speakerPinHoldMs: 2000 # how long the amplifier stays powered after # the last sound; 0 keeps it powered whenever # audio output is on #inputChannel: 0 #jitterBufferMs: 80 # RTSP back-channel: 0 = passthrough (LAN), # 80 helps over Wi-Fi/WAN # (build-dependent: Ultimate, and only on some SoCs — see "Microphone # processing (VQE)" in Majestic streamer). Runs on the capture channel, so one # setting reaches RTSP, SIP, WebRTC, the /audio.* endpoints and recordings # alike. All of it is inside the audio: section above. #vqe: false # master switch for the three stages below #anr: true # noise reduction (8/16 kHz only) #anrIntensity: 25 # 0-25 #anrNoiseThreshold: 41 # 30-60 dB #agc: true # automatic gain control #agcTargetLevel: -1 # -40..-1 dBFS #agcNoiseFloor: -42 # dBFS; -65..-20 at 8/16 kHz, -50..-20 at 48 kHz #agcMaxGain: 20 # 0-30 dB #hpf: true # high-pass filter #hpfFreq: 80 # 80 | 120 | 150 Hz; 48 kHz has 80 only rtsp: enabled: true port: 554 #alias1: cam/realmonitor # extra URL path that selects stream 1 #alias2: cam/substream # extra URL path that selects stream 2 #backchannel: false # ONVIF Profile T talkback (needs audio output) #audioCodec: "" # override audio.codec for RTSP only #naluSize: 1200 # RTP packet size, for RTSP clients and for the # udp:// destinations that do not set their own nightMode: # see en/ircut-filter.md for how the filter is # actually driven, and what the metrics mean lightMonitor: false # on alone = automatic exposure-based day/night # (sensor pin wins if set; both thresholds win # over automatic) irCut: auto # who moves the filter: auto = day and # night do; manual = you do, from the web # interface or /night/ircut; off = nothing # does. manual and off keep the pins #irCutPin1: 1 # the two coils of one H-bridge, not two #irCutPin2: 2 # switches — order decides which way it moves irCutSingleInvert: false # for a board with a single coil pad backlight: auto # the same three for the lamp, with # /night/light as the manual control #backlightPin: 65 backlightInvert: false # true when the lamp lights on a LOW pad; # covers the PWM lamp below as well colorToGray: true #overrideDrc: 300 #minThreshold: 2000 # compared against isp_again, whose units are #maxThreshold: 5000 # per-SoC: read your own before choosing #lightSensorPin: 62 lightSensorInvert: false #monitorDelay: 30 # seconds, 0-60 #autoNightGain: 16 # automatic mode: night at this gain multiple; # unset = night when the exposure runs out #autoDayGain: 2 # automatic mode: day at or below this multiple #autoNightDelay: 15 # seconds of darkness before night, 5-600 #autoDayDelay: 60 # seconds of brightness before day, 5-600 #transitionDelayMs: 150 # pause inside a switch, 0-2000 ms: the gap # between the picture changing and the filter # moving. Board-specific — leave it at 0 unless # a coloured frame shows as day returns #backlightPwmChannel: none # a dimmable lamp on a PWM pad; backlightPin # is then ignored. The channels offered are the # ones your camera's SoC actually brings out — # the WebUI lists them. Where one channel # reaches several pins the others are spelled # pwm2@gpio68 #backlightPwmFreq: 400 # Hz, 50-20000 #backlightPwmMin: 10 # duty floor, % — LEDs have an ignition threshold #backlightPwmMax: 100 # duty ceiling, % #backlightPwmGamma: 1.0 # 1.0 drives the duty asked for. Above it, the # dim end of the range gets finer control, for # an illuminator that is already bright at low # duty. The two limits above do not move, and # nor does off. Range 0.2-4.0 #backlightHighlightPct: 0 # 0 leaves the lamp to the scene's average # brightness alone. Above 0, the lamp dims # while more than this share of the picture has # run out of room — watch isp_highlight to pick # a number # On hi3516cv100/hi3518ev100 setting a channel # here also takes that channel away from the # ISP's own aperture control, unless # isp.iris.type is DC — see isp.iris above if # this camera has a motorised lens # Motion runs /usr/sbin/motion.sh, and — with records.mode below — can record a # clip per event. There is no "exclude" key: roi says where motion counts, and # nothing says where it does not. motionDetect: enabled: false visualize: false # draw a box around what moved. On SigmaStar this # and osd.privacyMasks cannot both be drawn; if # masks are set the masks are kept and the boxes # are not drawn debug: false # a log line per detection — several a second #roi: 1854x1304x216x606,1586x1540x482x622 #sensitivity: 3 # 0-8, higher is more sensitive. Every value is # usable; before September 2026 the top of the # scale reported the whole frame as moving, # for ever, whatever was in front of the camera # What the detectors find, and where it comes out, is in # en/analytics-metadata.md. This applies to every one of those outputs at once # rather than to a single detector. #analytics: #publishFps: 5 # 1-30. How often a detection that is STILL # there is re-sent to the live endpoints, the # browser overlay, the ONVIF metadata stream and # the recording. Movement starting and stopping # always get through whatever this is set to # On-camera face detection. Hi3516CV500 only, and only where the firmware # offers it -- otherwise this section does not exist. Reported only on frames # where motion fired, so motionDetect.enabled must be on too. #faceDetect: #enabled: false #confidence: 50 # 0-100, minimum score to report a face #debug: false # path is a DIRECTORY and filename is the base name; the extension is added by # Majestic. Both are strftime patterns, expanded when a file is opened. Older # configs that put the whole filename in `path` produce a directory of that # name — split them. records: enabled: false # the persistent switch. To stop recording just # long enough to change the card, POST to # /api/v1/records/standdown instead -- it saves # nothing, does not rebuild the pipeline, and # expires after ten minutes. See # en/sd-card-swap.md path: /mnt/mmcblk0p1/%F # -> /mnt/mmcblk0p1/2026-08-27/ filename: "%H-%M" # -> 14-30.mp4. Add %S for second precision maxUsage: 95 # delete the oldest clips above this, % #split: 20 # minutes per file, 1-100. A clip is cut at the # next keyframe after the split falls due, so it # can run up to one gopSize long #substream: false # record video1 instead of video0 #notime: false # ignore filename, number files 00000.mp4 upward #metadata: false # write the detections into each clip as a timed # metadata track, for a player or an analysis # tool to read back -- en/analytics-metadata.md. # Default false because Safari 26.6 refuses such # a clip alongside H.264; this WebUI removes the # track as it plays, an older one cannot. Also # moves live HLS off the card and into memory #audioCodec: "" # mp3 | aac | opus; empty follows audio.codec #encryption: none # none | passphrase | chip | pubkey -- see # en/recording-encryption.md; a mode the camera # cannot honour stops recording, it never falls # back to writing in the clear #key: "" # the passphrase, for encryption: passphrase #publicKey: "" # PEM public key: required by pubkey mode, and a # recovery key in the other two #chipSlot: 1 # which of the chip's key slots to use (1-3) # When to record. "continuous" is the default and records without stopping; # "motion" writes one clip per detection and nothing in between, and needs # motionDetect.enabled. See "Recording on motion" in majestic-streamer.md — # in particular, set video0.gopSize at or below preRollSec or the run-up is # mostly discarded. #mode: continuous # continuous | motion #preRollSec: 5 # seconds kept from BEFORE the trigger, in RAM #postRollSec: 10 # seconds kept after movement stops #minClipSec: 3 # shortest a motion clip may be # Housekeeping and durability. The defaults suit an SD card; there is rarely # a reason to change them. #purgeSeconds: 60 # how often free space is checked and the oldest # clips deleted. Used to follow `split`, so a # camera writing 20-minute files looked three # times an hour #syncSeconds: 30 # how often the open clip is committed to the # card, which bounds what a power cut costs. # 0 disables it; a clip is still committed when # it is closed #fragmentMs: 1000 # how much video one MP4 fragment holds. Also # the unit the recorder buffers and drops #fragmentBytes: 0 # hard size limit for one fragment; 0 derives it # from the bitrate #outgoing: # absent by default: the camera publishes nowhere # Every place the camera publishes to. Editable # in the WebUI under Settings -> Network & Integrations -> Outgoing. Each entry # is its own connection: udp/unix as RTP, rtmp/rtmps as RTMP, http(s) as WHIP. # rtmp/rtmps needs a Lite or Ultimate build; udp/unix work everywhere. #servers: # - udp://IP:port # a bare address is enough # - unix:/tmp/rtpstream.sock # - rtmps://dc4-1.rtmp.t.me/s/mykey # - url: https://mediamtx.lan:8889/cam/whip # WHIP # token: s3cret # bearer credential, if the endpoint asks for one # - url: rtmp://a.example/live/key # enabled: false # keep the destination without dialling it; absent means on # channel: sub # main|sub; absent means main # naluSize: 4000 # RTP packet size for this destination alone # audioSource: auto # auto|mic|silence|file|none; silence/file feed a track when there is no # microphone, and are refused by WHIP, which has no way to carry them # audioCodec: "" # opus|aac|alaw|ulaw|pcm; empty follows audio.codec. WHIP carries # opus or alaw/ulaw, RTMP what FLV can frame; a codec named here # is an instruction, and one the destination cannot carry # means no audio rather than a substitution # audioFile: "" # ADTS .aac looped when audioSource is file #thinEnhance: false # send the SVC-T base layer only. Belongs to the # section, not to an entry: it applies to everything # the camera sends # enabled, server, substream, audioSource, audioCodec and audioFile used to sit # here as ONE value for every destination at once. Each has the per-entry member # above that replaced it. A config still carrying them reads them once and writes # them onto the entries on the next start; writing one through the API answers 404. # outgoing.naluSize went to rtsp.naluSize instead -- the same setting sizes the # packets RTSP clients get. watchdog: enabled: true timeout: 300 # Applies without a restart, and runs alongside records rather than instead of # it — with recording on, the playlist describes byte ranges of the clip on the # card, which costs no memory and puts the live edge about a second behind. hls: enabled: false #adaptive: false # offer both encoder channels as two variants and # let the player choose. Only the recorded channel # comes from the card, so the second one is held in # RAM: this is the setting that costs memory #segments: 4 # finished segments the playlist offers, 2-8. # Only a memory cost when there is no recording # to describe — with records off, or records.key # set, each segment is held in RAM instead. # Nothing is allocated while HLS is off # # records.mode: motion turns this off: nothing # is written between detections, so there would # be no live stream to serve mdns: enabled: true # answers for openipc.local and .local onvif: enabled: true #username: root #password: "" # opt-in CLEARTEXT pair, only for clients that # need WSSE PasswordDigest or HTTP Digest ipeye: enabled: false #model: "" netip: enabled: false #user: admin #password: 6V0Y4HLF #port: 34567 #snapshots: true #ignoreSetTime: false # (build-dependent: Lite and Ultimate) cloud: enabled: false #host: "" # empty keeps the built-in default #port: 0 # (build-dependent: Lite and Ultimate) #sip: #enabled: false #server: pbx.example.com #port: 5060 #username: doorbell #password: secret #localUri: "" #callTarget: sip:100@pbx.example.com # several, comma-separated, are allowed #localIp: "" # goes into Via/Contact; must be routable back #localPort: 5060 #doRegister: true #registerExpires: 3600 # seconds, 60-86400; refreshed at expires-60 #buttonPin: 0 # GPIO wired to the doorbell button #buttonActiveLow: true #rtpPortHint: 5004 # start of the local RTP port scan #ringMode: sequential # several targets: sequential | parallel #ringSeconds: 10 # 1-300 #ringCycles: 3 # 0-100 passes over the target list; 0 = forever # Who may call this camera. A camera that registers already trusts its # registrar and refuses everyone else, so these are for deployments with no # registrar to trust. See "Who may call the camera" in Majestic streamer. #allowedPeers: "" # addresses allowed to call in, e.g. # "192.168.1.50, 192.168.9.0/24" #authInbound: false # ask everyone else for a password instead #inboundUser: "" # falls back to sip.username #inboundPassword: "" # falls back to sip.password # (build-dependent: Lite and Ultimate) #webrtc: # https://www.w3.org/TR/webrtc/#rtciceserver-dictionary with optional # '?transport=udp' or '?transport=tcp'. A list, separated by commas or # spaces. Unset means stun:stun.cloudflare.com:3478, which was measured to # answer from networks where the older Google and AWS defaults stayed silent. # Set it to 'none' to stop the camera contacting anyone. #iceServers: stun:stun.cloudflare.com:3478, turn:relay.example:3478 # Required alongside any turn:/turns: entry. Without both, a browser refuses # to build the connection at all, so an unauthenticated relay is dropped from # the list rather than handed over. #turnUsername: #turnCredential: # (2026-09+ build) Where this camera stands and which other cameras see its # scene. Nothing in the video pipeline reads it; it is kept here so the live # view can draw where a peer looks and lay its picture over this one. Every # key applies on save without a restart. See "Two cameras, one scene". #calibration: #height: 0 # metres above the ground plane; 0 = not said #tilt: 0 # degrees; 0 along the ground, 90 straight down #roll: 0 # degrees; positive = horizon higher on the right #azimuth: 0 # compass bearing of the lens, 0 north, 90 east #latitude: 0 # of the camera; both 0 = not said #longitude: 0 #lens: # focal length in main-stream pixels per zoom # - mag: "2.1" # readout (as GET /zoom reports it); empty # focal: 3487 # for a lens that does not zoom # cx: 1296 # principal point; absent = frame centre # cy: 972 #peers: # cameras that see the same scene # - peer: tele # by the name the camera switcher lists it under # mag: "" # this camera's zoom readout when measured # peerMag: "" # the other camera's; empty for a fixed lens # size: 2592x1944 # the other camera's MAIN stream, WxH, both even # homography: "5.21,-0.87,-2577,1.17,5.03,-5408,0.000186,-0.000156,1" # nine numbers, row by row, the last one 1; # a point on the ground here -> the same # point there, in main-stream pixels # fpv.enabled switches the SigmaStar FPV path on, and also disables # userspace 3A. The encoder knobs it used to gate now live per channel, # under video0/video1 with the rest of them. #fpv: #enabled: false ``` ### See also - [Majestic streamer](majestic-streamer.md) — endpoints, HTTP API, build flavours - [A second camera](majestic-streamer.md#a-second-camera) — what `usbcam` and `uvcgadget` do, stream ids, and how to watch a USB webcam - [Two cameras, one scene](two-cameras-one-scene.md) — what `calibration.peers` is, how to measure a row, and what the live view does with it - [On-screen display and privacy masks](majestic-streamer.md#on-screen-display-and-privacy-masks) — which streams get the overlay, and what masks do on each SoC family - [Majestic encoder tuning](majestic-encoder-tuning.md) — `refEnhance`, `refPred`, `svct`, ROI - [Majestic plugins](majestic-plugins.md) — what `system.plugins` turns on