الأدلة التقنية

Frigate: تسجيل كاميرات المراقبة على سيرفرك مع كشف الأجسام

كيف تثبت Frigate على سيرفرك، وتسجل به كاميرات المراقبة محلياً، ويكشف لك الأشخاص والسيارات دون أن يخرج الفيديو من بيتك.

Frigate: تسجيل كاميرات المراقبة على سيرفرك مع كشف الأجسام

في مقال أنواع كاميرات المراقبة وكيف تختار بينها وصلنا إلى أن الكاميرا التي تعطيك بث RTSP يمكن أن تسجلها على جهازك دون تطبيق الشركة ودون سحابتها، والسؤال الآن: بأي برنامج؟ والمسجل NVR التجاري يحفظ الفيديو، ولكن أغلبه يكتشف الحركة فقط، فيرسل لك تنبيهاً كلما تحركت شجرة أو مرت قطة أو تغير الضوء، وبعد أسبوع سوف تتجاهل كل التنبيهات، وهذا أسوأ من أن لا تكون هناك تنبيهات أصلاً.

والحل الذي نشرحه هنا هو Frigate، وهو مسجل NVR مفتوح المصدر بترخيص MIT، يسجل كاميراتك على سيرفرك، ويشغل نموذج كشف أجسام Object Detection محلياً على الفيديو، فيفرق بين شخص وسيارة وقطة وظل شجرة، ولا يخرج الفيديو من شبكتك. وهو المقال الثاني في مرحلة كاميرات المراقبة والأمن، وسوف نناقش في هذا المقال ما يلي:

  • كيف يعمل Frigate من الداخل: التسجيل، وكشف الحركة، وكشف الأجسام، والمراجعة.
  • تجربة كاملة على Docker: ملف فيديو في الملكية العامة يلعب دور الكاميرا عبر RTSP، وFrigate يسجله ويكشف ما فيه، مع المخرجات الحقيقية.
  • الاحتفاظ بالتسجيلات Retention وحساب المساحة من تسجيلات حقيقية.
  • نكسر الإعداد عمداً بعنوان RTSP خاطئ ونقرأ الخطأ، ونقارن كاشف المعالج CPU بكاشف OpenVINO على الجهاز نفسه.
  • التسريع بالعتاد Hardware Acceleration، وربط Frigate بال MQTT وHome Assistant باختصار، وأخطاء الأمان الشائعة.

كيف يعمل Frigate؟

الطريقة البسيطة لكشف الأجسام هي أن تمرر كل إطار من كل كاميرا على نموذج الذكاء الاصطناعي، ولكن كاميرا واحدة بخمسة إطارات في الثانية تعني 432 ألف إطار في اليوم، وهذا يحتاج قدرة حساب كبيرة لكاميرا واحدة فقط. لذلك يعمل Frigate بطريقة أذكى، وكما يذكر ملف المشروع فهو يبحث عن الأجسام فقط حين وأين يلزم، ويستخدم كشف حركة رخيصاً جداً ليحدد أين يشغل كشف الأجسام، والصورة التالية تبين المسار بالترتيب:

مخطط مرقم: كاميرا IP ترسل RTSP إلى ffmpeg باتصال واحد، ثم مساران، الأول تسجيل المقاطع دون إعادة ضغط إلى /media/frigate/recordings بحسب أيام الاحتفاظ، والثاني فك الضغط بخمسة إطارات ثم كشف الحركة في كل إطار ثم كاشف الأجسام على مناطق الحركة فقط بالمعالج أو OpenVINO أو Coral أو GPU، ثم الأجسام المتتبعة مثل شخص وسيارة، ومنها إلى صفحة المراجعة وإلى MQTT اختيارياً
مساران من الاتصال نفسه: التسجيل كما هو، وكشف الأجسام في أماكن الحركة فقط
  1. الاتصال بالكاميرا: Frigate يفتح بث RTSP من الكاميرا بأداة ffmpeg، ويمكن أن يأخذ بثين: بثاً رئيسياً للتسجيل وبثاً فرعياً منخفض الدقة للكشف.
  2. التسجيل Record: يكتب الفيديو كما وصل من الكاميرا دون إعادة ضغط، وتوثيق التسجيل يذكر أن الملفات تحفظ في /media/frigate/recordings بمسار YYYY-MM-DD/HH/<camera_name>/MM.SS.mp4 بتوقيت UTC، وأن كل كاميرا لها سياسة احتفاظ خاصة.
  3. فك الضغط Decode: بث الكشف يفك ضغطه إلى صور، وهذه أثقل خطوة على المعالج إذا لم يكن هناك تسريع بالعتاد.
  4. كشف الحركة Motion Detection: مقارنة بسيطة بين الإطار والذي قبله في صورة مصغرة، تحدد المناطق التي تغيرت، وهي رخيصة لدرجة أنها تعمل على كل إطار.
  5. كشف الأجسام Object Detection: النموذج لا يرى الصورة كلها، وإنما المناطق التي فيها حركة، ويعمل على كاشف Detector تختاره: المعالج، أو OpenVINO، أو Coral، أو GPU، أو غيرها مما في صفحة الكواشف.
  6. التتبع Tracking: كل جسم يعطى رقماً ويتبع من إطار إلى إطار، فيعرف Frigate أن السيارة التي وقفت قبل ساعة هي نفسها وليست سيارة جديدة كل ثانية.
  7. المراجعة والإشعارات: الأجسام التي تهمك تصبح عناصر مراجعة Review، إما تنبيهاً Alert أو اكتشافاً Detection، ويمكن أن ترسل عبر MQTT إلى Home Assistant.

قبل أن تبدأ: ما الذي تحتاجه؟

  • سيرفر Linux عليه Docker: كما في تثبيت Docker على Ubuntu، وتوثيق التثبيت يقول إن Frigate يعمل أفضل على Docker مباشرة على توزيعة مبنية على Debian، وإن تشغيله داخل جهاز افتراضي في Proxmox أو غيره غير موصى به وإن نجح عند بعض المستخدمين، والسبب حاجته إلى الوصول المباشر إلى GPU أو Coral، لذلك إذا كان الهوم لاب عندك على Proxmox كما في ما هو الهوم لاب؟، فاقرأ قسم Proxmox في التوثيق قبل أن تقرر.
  • كاميرا تعطي RTSP: وعنوان البث من دليلها، وفي هذا المختبر سوف نصنع كاميرا وهمية من ملف فيديو.
  • مساحة تخزين: وسوف نحسبها من التسجيلات الحقيقية لاحقاً.
  • كاشف أسرع من المعالج إن أمكن: لأن ملف المشروع نفسه يقول إن استخدام GPU أو مسرع ذكاء اصطناعي موصى به بشدة، وسوف نرى السبب بالأرقام.

التجربة العملية: كاميرا وهمية وFrigate على Docker

حتى تكون التجربة قابلة للتكرار على أي جهاز دون كاميرا حقيقية، سوف نصنع الكاميرا من ملف فيديو، فنشغل خادم البث المفتوح المصدر MediaMTX بترخيص MIT، ونجعل ffmpeg داخله يقرأ الملف في حلقة لا تنتهي وينشره بث RTSP، ثم نشغل Frigate ونعطيه عنوان هذا البث كأنه كاميرا. والفيديو هو مقطع مدته 30.73 ثانية لموقف سيارات مزدحم بالسيارات والناس من هيئة المتنزهات الوطنية الأمريكية، وهو في الملكية العامة لأنه من عمل موظف في الحكومة الأمريكية، والصورة التالية تبين شكل المختبر:

مخطط المختبر داخل شبكة Docker باسم lab-frigate_default: ملف towerfall.webm في الملكية العامة يقرأ في حلقة إلى Container باسم lab-frigate-rtsp فيه mediamtx وffmpeg وينشر rtsp://…:8554/parking، ثم Container باسم lab-frigate-nvr فيه Frigate 0.18.0 بكاشف OpenVINO وتسجيل وVolume باسم lab-frigate-media، ثم المتصفح على 127.0.0.1:18971، وتحتها ملاحظة أن البيت الحقيقي يستبدل الخطوتين الأولى والثانية بعنوان RTSP للكاميرا
المختبر: ملف فيديو يلعب دور الكاميرا، وFrigate يسجله ويكشف ما فيه، والمتصفح على 127.0.0.1 فقط

ملفات المختبر

أنشئ مجلداً للمختبر فيه مجلد media تضع فيه ملف الفيديو باسم towerfall.webm، ومجلد config فارغاً، ثم الملف mediamtx.yml الذي يصنع الكاميرا الوهمية:

# a fake camera: ffmpeg reads the sample video in a loop and publishes it as an RTSP stream
paths:
  parking:
    runOnInit: >
      ffmpeg -re -stream_loop -1 -i /samples/towerfall.webm
      -vf scale=1280:720,fps=15 -c:v libx264 -preset veryfast -tune zerolatency
      -g 30 -b:v 2500k -an -f rtsp rtsp://localhost:8554/parking
    runOnInitRestart: yes

في الإعداد أعلاه لاحظ التالي:

  • -re تجعل ffmpeg يقرأ الملف بسرعته الطبيعية كأنه بث حي، و-stream_loop -1 تعيده من البداية كلما انتهى.
  • نحول الفيديو إلى 1280×720 بخمسة عشر إطاراً وضغط H.264 بمعدل 2500 كيلوبت في الثانية، وهي أرقام قريبة مما تعطيه كاميرا منزلية في بثها الرئيسي.
  • runOnInitRestart: yes يعيد تشغيل ffmpeg إذا توقف، فلا تموت الكاميرا الوهمية في منتصف التجربة.

ثم ملف compose.yaml الذي يشغل الحاويتين:

name: lab-frigate
services:
  rtsp:
    image: bluenviron/mediamtx:1.21.1-ffmpeg
    container_name: lab-frigate-rtsp
    restart: unless-stopped
    volumes:
      - ./mediamtx.yml:/mediamtx.yml:ro
      - ./media:/samples:ro
    ports:
      - "127.0.0.1:18554:8554"

  frigate:
    image: ghcr.io/blakeblackshear/frigate:0.18.0
    container_name: lab-frigate-nvr
    restart: unless-stopped
    stop_grace_period: 30s
    shm_size: "256mb"
    depends_on: [rtsp]
    volumes:
      - ./config:/config
      - lab-frigate-media:/media/frigate
      - type: tmpfs
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "127.0.0.1:18971:8971"
      - "127.0.0.1:15000:5000"

volumes:
  lab-frigate-media:
    name: lab-frigate-media

في الإعداد أعلاه لاحظ التالي:

  • ال Image مثبتة على الإصدار 0.18.0 وليس stable، والسبب أن ملاحظات إصدار 0.18.0 فيها تغييرات تكسر التوافق Breaking Changes، وتنصح بأخذ نسخة من ملف الإعداد وقاعدة البيانات frigate.db قبل كل ترقية، فلا تريد أن تحدث هذه الترقية وحدها في الليل.
  • shm_size هي الذاكرة المشتركة التي يضع فيها Frigate الإطارات المفكوكة، وتوثيق التثبيت يذكر أن 128 ميغابايت تكفي لكاميرتين بدقة 720p، وأن السجلات Logs تأخذ منها حتى 40 ميغابايت، لذلك وضعنا 256 ميغابايت.
  • /tmp/cache على tmpfs في الذاكرة، لأن مقاطع التسجيل تكتب فيه أولاً ثم تفحص وتنقل إلى القرص، والتوثيق يوصي بأن يكون tmpfs، وبهذا لا يكتب كل مقطع على القرص مرتين.
  • المنفذ 8971 هو الواجهة والمنفذ المحمي بتسجيل الدخول، والمنفذ 5000 منفذ داخلي دون أي تسجيل دخول، وتوثيق المصادقة يقول إن كل الطلبات عليه تعامل بصلاحيات المدير admin، لذلك ربطناه ب 127.0.0.1 فقط للتجربة، ولا تنشره في التركيب الحقيقي.

وأخيراً ملف إعداد Frigate في config/config.yml:

mqtt:
  enabled: false

detectors:
  ov:
    type: openvino
    device: CPU

model:
  width: 300
  height: 300
  input_tensor: nhwc
  input_pixel_format: bgr
  path: /openvino-model/ssdlite_mobilenet_v2.xml
  labelmap_path: /openvino-model/coco_91cl_bkgr.txt

record:
  enabled: true
  continuous:
    days: 1
  alerts:
    retain:
      days: 14
  detections:
    retain:
      days: 14

snapshots:
  enabled: true
  retain:
    default: 14

cameras:
  parking:
    ffmpeg:
      inputs:
        - path: rtsp://lab-frigate-rtsp:8554/parking
          roles:
            - detect
            - record
    detect:
      enabled: true
      width: 1280
      height: 720
      fps: 5
    objects:
      track:
        - person
        - car
    review:
      alerts:
        labels:
          - person
      detections:
        labels:
          - car

version: 0.18-0

في الإعداد أعلاه لاحظ التالي:

  • mqtt: enabled: false لأننا لا نحتاج MQTT في هذه التجربة، وسوف نعود إليه في نهاية المقال.
  • الكاشف OpenVINO على المعالج CPU، وصفحة الكواشف تقول إن كاشف المعالج العادي غير موصى به، وإن OpenVINO على المعالج غالباً أكفأ منه، وتعمل OpenVINO على معالجات Intel من الجيل السادس فما بعده وعلى معالجات AMD أيضاً دون دعم رسمي، والنموذج ssdlite_mobilenet_v2 موجود داخل ال Image نفسها في /openvino-model.
  • التسجيل المستمر يحفظ يوماً واحداً، أما المقاطع التي فيها تنبيهات Alerts أو اكتشافات Detections فتحفظ 14 يوماً، وهذا هو الشكل الذي يوفر المساحة كما سنرى.
  • في review جعلنا الشخص تنبيهاً والسيارة اكتشافاً، فالتنبيه هو ما تريد أن تراه فوراً، والاكتشاف شيء تراجعه عند الحاجة.
  • السطر version: 0.18-0 يخبر Frigate أن الملف مكتوب بصيغة هذا الإصدار، وإذا غاب فهو يفترض أن الملف من إصدار قديم ويحاول ترحيله Migration وينشئ نسخة احتياطية منه، كما في كود الترحيل داخل ال Image.

تشغيل المختبر

docker compose up -d
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'

والمخرج سوف يكون كما يلي:

NAME               IMAGE                                    STATUS                            PORTS
lab-frigate-nvr    ghcr.io/blakeblackshear/frigate:0.18.0   Up 9 seconds (health: starting)   127.0.0.1:15000->5000/tcp, 127.0.0.1:18971->8971/tcp
lab-frigate-rtsp   bluenviron/mediamtx:1.21.1-ffmpeg        Up 10 seconds                     127.0.0.1:18554->8554/tcp

قبل أن ننظر إلى Frigate، نتأكد أن الكاميرا الوهمية تبث فعلاً، فنشغل ffprobe من Container مؤقت على الشبكة نفسها ونطلب منه وصف البث:

docker run --rm --name lab-frigate-probe --network lab-frigate_default --entrypoint ffprobe \
  bluenviron/mediamtx:1.21.1-ffmpeg -v error \
  -show_entries stream=codec_name,profile,width,height,avg_frame_rate -of default=nw=1 \
  rtsp://lab-frigate-rtsp:8554/parking

والمخرج سوف يكون كما يلي:

codec_name=h264
profile=High
width=1280
height=720
avg_frame_rate=15/1

وهذه هي الخطوة نفسها التي تفعلها مع كاميرا حقيقية قبل أن تضعها في Frigate، فإذا لم يعمل ffprobe مع عنوان الكاميرا فلن يعمل Frigate أيضاً. وعند أول تشغيل ينشئ Frigate مستخدماً باسم admin ويطبع كلمة مروره في السجلات، كما يذكر توثيق المصادقة:

docker logs lab-frigate-nvr 2>&1 | grep -E 'User:|Password:'

والمخرج سوف يكون كما يلي (أخفينا كلمة المرور):

2026-10-08 19:33:57.103949442  [2026-10-08 19:33:57] frigate.app                    INFO    : ***    User: admin                                   ***
2026-10-08 19:33:57.142803899  [2026-10-08 19:33:57] frigate.app                    INFO    : ***    Password: ********************************   ***

الآن افتح https://127.0.0.1:18971 في المتصفح، ولاحظ أنه HTTPS بشهادة موقعة ذاتياً Self-signed، لأن توثيق TLS يذكر أن Frigate ينشئ شهادة ذاتية للمنفذ 8971 افتراضياً، فاقبل تحذير المتصفح في هذه التجربة، ثم ادخل بالمستخدم وكلمة المرور، وغير كلمة المرور فوراً من الإعدادات، وتذكر أن Frigate يشترط 12 حرفاً على الأقل. والصورة التالية هي الصفحة الرئيسية وفيها البث الحي للكاميرا:

واجهة Frigate الرئيسية بقائمة أيقونات على اليسار، وفيها بطاقة البث الحي لكاميرا parking تعرض موقف السيارات المزدحم بإطار أحمر، وفي زاويتها أيقونة سيارة لجسم يتتبعه Frigate في تلك اللحظة
البث الحي للكاميرا الوهمية في واجهة Frigate، من تثبيتنا في المختبر

هل يكشف Frigate شيئاً؟

بعد ثلاث دقائق تقريباً نسأل Frigate عن إحصاءاته من داخل ال Container، عبر المنفذ الداخلي 5000 وأداة jq الموجودة فيه:

docker exec lab-frigate-nvr sh -c 'curl -s http://127.0.0.1:5000/api/stats | jq "{camera: .cameras.parking | {camera_fps, process_fps, skipped_fps, detection_fps}, detectors}"'

والمخرج سوف يكون كما يلي:

{
  "camera": {
    "camera_fps": 5.1,
    "process_fps": 1.2,
    "skipped_fps": 4,
    "detection_fps": 19.9
  },
  "detectors": {
    "ov": {
      "inference_speed": 38.96,
      "detection_start": 0,
      "pid": 666,
      "cpu": "240.1",
      "mem": "0.9"
    }
  }
}

في المخرج أعلاه لاحظ التالي:

  • camera_fps قرابة 5، وهي الإطارات التي طلبناها للكشف في detect.fps.
  • process_fps هو 1.2 وskipped_fps هو 4، ومجموعهما قرابة 5، أي أن Frigate لم يلحق بتحليل أغلب الإطارات وتخطاها، والسبب أن جهاز التجربة يفك الضغط على المعالج دون تسريع بالعتاد، وأن الكاميرا الوهمية نفسها تضغط الفيديو على المعالج نفسه في الوقت ذاته، والمشهد فيه حركة في كل مكان تقريباً.
  • detection_fps هو عدد مرات تشغيل النموذج في الثانية، وهو أكبر من عدد الإطارات لأن الإطار الواحد قد يحتوي عدة مناطق حركة، وكل منطقة تمر على النموذج.
  • inference_speed قرابة 39 ملي ثانية لكل مرة في OpenVINO على المعالج، وسوف نقارنه بكاشف المعالج العادي بعد قليل.

ثم نسأل عن الأجسام التي تتبعها Frigate حتى الآن، مجمعة بحسب النوع، ثم تفاصيل آخر شخص:

docker exec lab-frigate-nvr sh -c 'curl -s "http://127.0.0.1:5000/api/events?limit=500" | jq -r "group_by(.label)[] | \"\(.[0].label): \(length)\""'
docker exec lab-frigate-nvr sh -c 'curl -s "http://127.0.0.1:5000/api/events?limit=1&labels=person" | jq ".[0] | {label: .label, top_score: .data.top_score, has_clip: .has_clip, has_snapshot: .has_snapshot}"'

والمخرج سوف يكون كما يلي:

car: 62
person: 5
{
  "label": "person",
  "top_score": 0.726601243019104,
  "has_clip": true,
  "has_snapshot": true
}

وعدد السيارات كبير لأن الفيديو يعود من بدايته كل 30 ثانية، فيرى Frigate السيارات نفسها كأنها وصلت من جديد، وهذا من طبيعة الكاميرا الوهمية وليس خطأ في الكشف. أما top_score فهو أعلى ثقة وصل إليها النموذج في هذا الجسم، ولكل جسم مقطع Clip وصورة Snapshot. والصورة التالية من صفحة المراجعة Review، وفيها تنبيه واحد لأن الشخص في إعدادنا تنبيه، ويضم داخله السيارات والأشخاص في الفترة نفسها:

صفحة Review في Frigate، في أعلاها تبويبات Alerts بعدد 1 وDetections بعدد 0 وMotion، وتحتها بطاقة التنبيه بصورة من موقف السيارات وأيقونتي سيارة وشخص وتاريخ Oct 8، 10:34 PM، وعلى اليمين خط زمني
صفحة المراجعة: تنبيه واحد فيه سيارات وأشخاص، من تثبيتنا في المختبر

وصفحة Explore تعرض كل جسم تتبعه Frigate مصنفاً بحسب نوعه، ويجدر الإشارة هنا إلى أن شريط الحالة أسفل الواجهة أظهر أثناء التجربة التحذير Ov is very slow (115.7 ms)، أي أن Frigate نفسه لاحظ أن الكاشف بطيء في تلك اللحظة، وهو ما رأيناه في الأرقام:

صفحة Explore في Frigate، فيها صف بعنوان Car و50 جسماً متتبعاً بصور مصغرة لسيارات مختلفة من موقف السيارات، وتحته صف بعنوان Person و3 أجسام بصور لأشخاص يمشون بين السيارات
صفحة Explore: الأجسام المتتبعة مجمعة بحسب النوع، من تثبيتنا في المختبر

التسجيلات والمساحة الحقيقية

في مقال أنواع الكاميرات حسبنا المساحة بأرقام توضيحية، والآن نقيسها من تسجيلات حقيقية، فنعرض أول الملفات في مجلد التسجيلات، ثم نجمع مدة المقاطع وحجمها من واجهة Frigate البرمجية API:

docker exec lab-frigate-nvr sh -c 'ls /media/frigate/recordings/*/*/parking | head -6'
docker exec lab-frigate-nvr sh -c 'curl -s "http://127.0.0.1:5000/api/parking/recordings?after=0&before=$(date +%s)" | jq "{segments: length, seconds: (map(.duration) | add), megabytes: (map(.segment_size) | add)}"'
docker exec lab-frigate-nvr sh -c 'du -sh /media/frigate/recordings /media/frigate/clips'

والمخرج سوف يكون كما يلي:

33.57.mp4
34.08.mp4
34.20.mp4
34.28.mp4
34.39.mp4
34.49.mp4
{
  "segments": 33,
  "seconds": 332.4896555555556,
  "megabytes": 100.29000000000002
}
104M	/media/frigate/recordings
5.9M	/media/frigate/clips

في المخرج أعلاه لاحظ التالي:

  • كل ملف مقطع مدته قرابة عشر ثوان، واسمه الدقيقة والثانية التي بدأ فيها، داخل مجلد الساعة واليوم بتوقيت UTC كما يقول التوثيق.
  • 100.29 ميغابايت في 332.49 ثانية تعني قرابة 2.41 ميغابت في الثانية، وهو قريب من 2500 كيلوبت الذي ضبطناه في الكاميرا الوهمية، أي أن Frigate حفظ البث كما وصل دون إعادة ضغط.
  • بهذا المعدل تأخذ الكاميرا قرابة 26 جيجابايت في اليوم من التسجيل المستمر، فإذا احتفظت به يوماً واحداً والمقاطع المهمة 14 يوماً، فالمساحة تحددها كمية النشاط وليس عدد الأيام وحده.
  • مجلد clips فيه الصور والمقاطع المصغرة للأجسام، وهو صغير مقارنة بالتسجيلات.

نكسر الإعداد: عنوان RTSP خاطئ

أشهر مشكلة عند إضافة كاميرا هي عنوان بث خاطئ، لذلك نكسره عمداً ونرى كيف يظهر الخطأ، فنغير المسار في config.yml من /parking إلى /parkin ونعيد تشغيل Frigate:

sed -i 's#rtsp://lab-frigate-rtsp:8554/parking$#rtsp://lab-frigate-rtsp:8554/parkin#' config/config.yml
docker restart lab-frigate-nvr
# بعد دقيقة أو دقيقتين
docker logs --since 4m lab-frigate-nvr 2>&1 | grep -E 'ffmpeg\.parking' | head -3
docker exec lab-frigate-nvr sh -c 'curl -s http://127.0.0.1:5000/api/stats | jq ".cameras.parking | {camera_fps, process_fps, connection_quality, reconnects_last_hour}"'
docker logs --since 3m lab-frigate-rtsp 2>&1 | grep parkin | tail -2

والمخرج سوف يكون كما يلي:

2026-10-08 19:40:44.985840740  [2026-10-08 19:40:44] ffmpeg.parking.detect          ERROR   : [in#0 @ 0x563da7c4ab40] Error opening input: Server returned 400 Bad Request
2026-10-08 19:40:44.986607676  [2026-10-08 19:40:44] ffmpeg.parking.detect          ERROR   : Error opening input file rtsp://lab-frigate-rtsp:8554/parkin.
2026-10-08 19:40:44.987184004  [2026-10-08 19:40:44] ffmpeg.parking.detect          ERROR   : Error opening input files: Server returned 400 Bad Request
{
  "camera_fps": 0,
  "process_fps": 0,
  "connection_quality": "unusable",
  "reconnects_last_hour": 14
}
2026/10/08 19:42:55 INF [RTSP] [conn 192.168.48.3:53060] closed: path 'parkin' is not configured
2026/10/08 19:43:05 INF [RTSP] [conn 192.168.48.3:56980] closed: path 'parkin' is not configured

في المخرج أعلاه لاحظ التالي:

  • Frigate يكتب خطأ ffmpeg نفسه في السجل باسم ffmpeg.parking.detect، أي الكاميرا parking ودور الكشف detect، والرسالة تقول إن الخادم رفض الطلب، وهذا أوضح من أي رسالة في الواجهة.
  • الإحصاءات تعطيك الصورة بسرعة: camera_fps صفر، وجودة الاتصال unusable، وعدد محاولات إعادة الاتصال يزيد كل عشر ثوان تقريباً، فإذا رأيت هذه الثلاثة معاً فابدأ من عنوان RTSP.
  • سجل خادم البث يقول السبب الحقيقي بوضوح: المسار parkin غير موجود، ومع كاميرا حقيقية قد يختلف رمز الخطأ بحسب الشركة وبحسب الخطأ في المسار أو في كلمة المرور، لذلك جرب العنوان بأداة ffprobe أولاً.

ثم نعيد المسار الصحيح ونعيد التشغيل:

sed -i 's#rtsp://lab-frigate-rtsp:8554/parkin$#rtsp://lab-frigate-rtsp:8554/parking#' config/config.yml
docker restart lab-frigate-nvr

كاشف المعالج أم OpenVINO؟

لنرى لماذا ينصح التوثيق بعدم استخدام كاشف المعالج العادي، نستبدل في config.yml كتلة detectors وmodel بالكاشف cpu، وهو يستخدم نموذج TensorFlow Lite الموجود في ال Image في /cpu_model.tflite:

detectors:
  cpu1:
    type: cpu
    num_threads: 3

ثم نعيد التشغيل وننتظر ثلاث دقائق ونقرأ الإحصاءات بالأمر نفسه:

{
  "camera": {
    "camera_fps": 5.1,
    "process_fps": 1.5,
    "skipped_fps": 3.7,
    "detection_fps": 9.9
  },
  "detectors": {
    "cpu1": {
      "inference_speed": 81.27,
      "detection_start": 1791488706.524136,
      "pid": 652,
      "cpu": "204.3",
      "mem": "0.5"
    }
  }
}

في المخرج أعلاه لاحظ التالي:

  • زمن الكشف الواحد inference_speed ارتفع من قرابة 39 ملي ثانية في OpenVINO إلى 81.27 ملي ثانية في كاشف المعالج العادي، على الجهاز نفسه وبالفيديو نفسه، أي أن كل كشف أخذ ضعف الوقت تقريباً.
  • عدد مرات الكشف في الثانية detection_fps انخفض من 19.9 إلى 9.9، أي أن Frigate صار يفحص مناطق أقل في الثانية، وهذا يعني أجساماً قد تفوته في مشهد مزدحم.
  • الأرقام تختلف من دقيقة إلى أخرى ومن جهاز إلى آخر، وجهاز التجربة كان يشغل أعمالاً أخرى في الوقت نفسه، لذلك خذها للمقارنة بين الكاشفين على الجهاز نفسه، وليس كرقم تتوقعه على جهازك.

وصفحة System في واجهة Frigate تعرض الرقم نفسه مع رسم لزمن الكشف واستهلاك المعالج، وهي أول صفحة تفتحها عندما تشعر أن Frigate بطيء، والصورة التالية منها أثناء عمل OpenVINO:

صفحة System في Frigate 0.18.0، فيها رسم Detector Inference Speed للكاشف ov بقيمة 24.42 ملي ثانية مع أعمدة خضراء وبرتقالية وحمراء، ورسم Detector CPU Usage بقيمة 167.6% بأعمدة حمراء، وتحتها استهلاك المعالج والذاكرة لعمليات التسجيل والمراجعة وgo2rtc
صفحة System: زمن الكشف واستهلاك المعالج للكاشف OpenVINO، من تثبيتنا في المختبر

الاحتفاظ بالتسجيلات Retention

إعداد الاحتفاظ هو ما يحول Frigate من جهاز يملأ القرص في أيام إلى جهاز يكفيه قرص واحد لأشهر، وتوثيق التسجيل يعرض ثلاثة أشكال شائعة:

  • الأكثر حذراً: كل الفيديو لعدة أيام، ثم الفيديو الذي فيه حركة لأيام أخرى، ثم المقاطع التي فيها تنبيهات واكتشافات حتى 30 يوماً، وهذا للأماكن التي يجب أن يبقى فيها تسجيل متصل حتى لو لم تكتشف حركة.
  • مساحة أقل: لا يحفظ إلا الفيديو الذي فيه حركة أو نشاط.
  • الحد الأدنى: لا يحفظ إلا التنبيهات.

ويختار Frigate عند الحذف أكبر مدة تنطبق على المقطع بين مدة التسجيل ومدة الأجسام التي فيه، وإذا أردت أن تحفظ مقطعاً معيناً بعد انتهاء مدته فاستخدم التصدير Export، لأن الملفات المصدرة لا تحذفها قواعد الاحتفاظ، كما يذكر التوثيق نفسه.

⚠️
لا تضع التسجيلات على القرص نفسه الذي عليه نظام التشغيل وقاعدة بيانات Frigate، والسبب أن التسجيل يكتب طوال اليوم، فإذا امتلأ القرص توقف النظام كله وليس التسجيل وحده، فاجعل /media/frigate على قرص منفصل أو على NAS، كما ناقشنا في عتاد الهوم لاب.

التسريع بالعتاد: أين يذهب الحمل؟

رأينا في المختبر أن الحمل يأتي من مكانين: فك ضغط الفيديو، وتشغيل نموذج الكشف، ولكل منهما تسريع مختلف:

  • فك الضغط Video Decoding: صفحة تسريع الفيديو تعرض إعدادات جاهزة Presets، مثل preset-vaapi لمعالجات Intel الرسومية المدمجة حتى الجيل 12 ولمعالجات وبطاقات AMD الرسومية، وpreset-intel-qsv-h264 وpreset-intel-qsv-h265 لمعالجات Intel من الجيل 13 فما بعده وبطاقات Arc، وpreset-nvidia لبطاقات NVIDIA، وpreset-rpi-64-h264 لRaspberry Pi، وتضعها في ffmpeg.hwaccel_args. ولاحظ أن ال Container يحتاج أن ترى الجهاز، مثل /dev/dri/renderD128 لبطاقات Intel وAMD كما في مثال Compose في التوثيق.
  • كشف الأجسام: الكواشف في صفحة الكواشف كثيرة، منها OpenVINO لمعالجات Intel وبطاقاتها الرسومية ووحدات NPU، وCoral EdgeTPU من Google، وONNX مع TensorRT على بطاقات NVIDIA وأجهزة Jetson، وHailo، وغيرها، وملف المشروع يقول إن مسرعات الذكاء الاصطناعي تتفوق حتى على أفضل المعالجات.
  • البث الفرعي: أبسط تسريع على الإطلاق هو أن تجعل الكشف يعمل على البث الفرعي للكاميرا بدقة منخفضة، والتسجيل على البث الرئيسي، فيقل حمل فك الضغط كثيراً دون أي عتاد إضافي.

والتعرف على الأشخاص والسيارات بمسرع Coral أو GPU موضوع مقال مخطط في مرحلة الكاميرات.

MQTT وHome Assistant باختصار

إذا كان لديك Home Assistant، فالطريقة التي يوصي بها توثيق التكامل هي التكامل الرسمي frigate-hass-integration، وهو يحتاج أن يعمل Frigate وHome Assistant مع خادم MQTT واحد حتى تعمل كثير من الكيانات التي ينشئها، ثم تصلك الأحداث عبر موضوعات MQTT مثل frigate/events الذي ينشر رسالة لكل تغير في جسم متتبع. وبهذا يمكن أن تشعل إضاءة المدخل عند ظهور شخص بعد منتصف الليل، أو ترسل تنبيهاً إلى هاتفك مع الصورة، وربط الكاميرات بالمنزل الذكي والتنبيهات موضوع مقال مخطط في المرحلة نفسها.

أخطاء أمان شائعة

  • نشر المنفذ 5000: هذا المنفذ دون تسجيل دخول ويعامل كل طلب كمدير، فلا تنشره خارج الجهاز ولا في ال Router.
  • فتح Frigate على الإنترنت مباشرة: ادخل إليه من الخارج عبر VPN كما في WireGuard، وإذا وضعته خلف Reverse Proxy فاستخدم المنفذ 8971 كما يقول التوثيق.
  • ترك الكاميرات على شبكة البيت: ضع الكاميرات في VLAN لا يصل إليها إلا Frigate كما في تقسيم الشبكة، وامنعها من الإنترنت.
  • بث RTSP المعاد دون حماية: المنفذ 8554 في Frigate يعيد بث الكاميرات، وتوثيق التثبيت يذكر أن هذه البثوث دون مصادقة افتراضياً، فلا تنشره إلا إذا ضبطت المصادقة في قسم go2rtc.
  • الترقية دون نسخة احتياطية: خذ نسخة من config وfrigate.db قبل كل ترقية، وافعلها يدوياً بعد قراءة ملاحظات الإصدار.

تنظيف المختبر

من داخل مجلد المختبر، نحذف ال Containers والشبكة وال Volume الذي أنشأناه بالاسم فقط:

docker compose down -v

والمخرج سوف يكون كما يلي:

 Container lab-frigate-nvr Stopping 
 Container lab-frigate-nvr Stopped 
 Container lab-frigate-nvr Removing 
 Container lab-frigate-nvr Removed 
 Container lab-frigate-rtsp Stopping 
 Container lab-frigate-rtsp Stopped 
 Container lab-frigate-rtsp Removing 
 Container lab-frigate-rtsp Removed 
 Volume lab-frigate-media Removing 
 Network lab-frigate_default Removing 
 Volume lab-frigate-media Removed 
 Network lab-frigate_default Removed

تدريب عملي

  • إذا كانت لديك كاميرا حقيقية، تأكد أولاً من عنوان RTSP بالأمر ffprobe كما فعلنا، ثم أضفها إلى config.yml بالبث الفرعي للكشف والرئيسي للتسجيل، وقارن skipped_fps بما رأيناه هنا.
  • غير إعداد الاحتفاظ إلى التسجيل عند الحركة فقط، واترك المختبر يعمل ساعة، ثم قارن حجم /media/frigate/recordings بالحجم في التسجيل المستمر.

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • Frigate مسجل NVR مفتوح المصدر بترخيص MIT، يسجل الكاميرات على سيرفرك ويكشف الأشخاص والسيارات محلياً، ولا يخرج الفيديو من شبكتك.
  • يسجل الفيديو كما وصل دون إعادة ضغط، ويشغل كشف الأجسام فقط في مناطق الحركة، وهذا ما يجعله يعمل على عتاد صغير.
  • في المختبر سجل Frigate بثاً بمعدل 2.41 ميغابت في الثانية، أي قرابة 26 جيجابايت في اليوم للكاميرا، فاضبط الاحتفاظ حتى يحفظ التسجيل المستمر أياماً قليلة والمقاطع المهمة مدة أطول.
  • تحقق من عنوان RTSP بأداة ffprobe قبل أي شيء، وإذا رأيت camera_fps صفراً فابدأ من سجلات ffmpeg.
  • الكاشف على المعالج العادي بطيء، وOpenVINO على المعالج أسرع، والمسرعات وتسريع فك الضغط أفضل منهما.
  • لا تنشر المنفذ 5000، وادخل من الخارج عبر VPN، واعزل الكاميرات في VLAN، وثبت الإصدار وخذ نسخة قبل كل ترقية.
دليلأنواع كاميرات المراقبة وكيف تختار بينهاما الفرق بين أنواع كاميرات المراقبة، وما الذي تحتاجه في الكاميرا حتى تسجلها على جهازك، وكم قرصاً تحتاج للتسجيلات.دليلما هو الهوم لاب Homelab ولماذا تبنيه في بيتك؟كيف تبني مختبراً في بيتك تتعلم عليه ويخدم عائلتك، وما الذي يكلفه فعلاً، وبأي إعداد تبدأ.دليلعتاد الهوم لاب: Mini PC أم NAS أم سيرفر مستعمل؟كيف تختار جهاز الهوم لاب بأرقام الشركة المصنعة وليس بالسعر وحده، وكم يكلفك من الكهرباء في السنة بالتعرفة السعودية.دليلتقسيم الشبكة Network Segmentation بال VLAN وال VPCلماذا تصل كاميرا مخترقة إلى قاعدة بياناتك، وكيف تمنع ذلك بتقسيم الشبكة إلى مناطق لا يمر بينها إلا ما تسمح به.دليلشبكة خاصة مع WireGuard وواجهة wg-easyكيف تنشئ شبكة VPN خاصة مع WireGuard وواجهة wg-easy، فلا يصل إلى لوحات الإدارة على سيرفرك إلا أجهزة فريقك.دليلتثبيت Docker Engine وCompose على Ubuntuكيف تثبت Docker على Ubuntu من المستودع الرسمي، وتضبطه من البداية حتى لا يمتلئ القرص أو تنكشف منافذك للإنترنت.

سجل التحديثات

  • أكتوبر 2026: كتابة المقال، وتنفيذ المختبر على Frigate 0.18.0 وMediaMTX 1.21.1 وDocker Engine 29.8.0 وDocker Compose v5.5.1 على Windows 11 مع Docker Desktop ومعالج Intel Core i7-7700K.
Could not load content
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.