Docker-with-WebCam — الوصول إلى كاميرا المضيف من داخل حاوية Docker
مستودع يوضّح كيف تصل حاوية Docker إلى كاميرا المضيف عبر بثّ FFmpeg بصيغة mpegts فوق UDP بدلاً من تمرير الجهاز مباشرة، مع مثال التقاط بلغة Python و OpenCV.

عن هذا المشروع
دليل عملي لتمرير كاميرا الويب من نظام المضيف إلى داخل حاوية Docker عبر بثّ FFmpeg على UDP، مع مثال التقاط ومعالجة بلغة Python باستخدام OpenCV.
التقنيات
مستودع أدوات عملي — الهدف منه توثيق طريقة تشغيل كاميرا الويب داخل حاوية Docker على أنظمة تشغيل مختلفة، بعد أن ظهرت الحاجة إليها في مشروع رؤية حاسوبية.
نظرة عامة
Docker-with-WebCam ليس مكتبة ولا إطار عمل، بل وصفة تشغيل موثّقة: كيف تحصل حاوية Docker على تدفّق فيديو حيّ من كاميرا متصلة بجهاز المضيف، ثم تعالجه بلغة Python عبر opencv-python.
الفكرة الأساسية بسيطة ومقصودة: بدلاً من محاولة تمرير جهاز الكاميرا نفسه إلى داخل الحاوية، يُحوَّل الفيديو إلى بثّ شبكي على المضيف، ثم تستهلكه الحاوية كأي مصدر شبكي آخر.
ffmpeg -f dshow -framerate 30 -i video="c922 Pro Stream Webcam" \
-vcodec mpeg4 -q 12 -f mpegts udp://127.0.0.1:1235المشكلة
الوصول إلى كاميرا من داخل حاوية يصطدم بثلاثة قيود حقيقية:
- العزل هو الغاية من الحاوية. الحاوية لا ترى
/devالخاص بالمضيف افتراضياً، وهذا سلوك مقصود لا خلل يُصلَح. - الفروق بين أنظمة التشغيل. على Linux يمكن نظرياً تمرير
/dev/video0، لكن هذا الحلّ لا وجود له أصلاً على Windows أو macOS حيث تدير النواة الأجهزة بطريقة مختلفة تماماً. - عرض النتيجة. حتى بعد التقاط الإطارات، فإن نافذة
cv2.imshowتحتاج خادم عرض؛ والحاوية لا تملك واحداً.
التخطيط
قُسّم العمل إلى ثلاث قطع مستقلة، كل واحدة قابلة للاختبار وحدها قبل وصلها بغيرها:
| القطعة | مكانها | مسؤوليتها |
|---|---|---|
| مصدر الفيديو | المضيف | قراءة الكاميرا وبثّها عبر FFmpeg |
| قناة النقل | الشبكة | نقل mpegts فوق UDP إلى منفذ محلي |
| المستهلك | الحاوية | فتح التدفّق بـ OpenCV ومعالجة الإطارات |
هذا التقسيم يسمح بالتحقّق من البثّ بمشغّل فيديو عادي قبل بناء أي صورة Docker، وهو ما يختصر التشخيص لاحقاً إلى نصفين واضحين: هل المشكلة في المصدر أم في المستهلك؟
القرارات المعمارية
البثّ الشبكي بدلاً من تمرير الجهاز. الحل المباشر — --device=/dev/video0 — يعمل على Linux فقط ويربط الوصفة بنظام تشغيل واحد. تحويل الكاميرا إلى تدفّق UDP يجعل الحاوية تتعامل مع عنوان لا مع عتاد، فتصبح نفس صورة Docker صالحة على Windows و macOS و Linux دون تعديل.
mpegts فوق UDP لا TCP. الحاوية تقرأ فيديو حيّاً؛ الإطار المتأخّر لا قيمة له. UDP يُسقط ما يتأخّر بدل أن يعيد إرساله ويراكم التأخير، وmpegts تحتمل فقدان الحزم لأنها مصمَّمة للبثّ لا للتخزين. عامل الجودة -q 12 يوازن بين وضوح الصورة وحجم التدفّق على الشبكة المحلية.
تفويض العرض إلى خادم X على المضيف. بدل حشو الحاوية بمكدّس رسومي كامل، تُوجَّه نافذة العرض إلى خادم X خارجي: Xming على Windows وXQuartz على macOS. تبقى الصورة خفيفة، ويبقى العرض مسؤولية المضيف.
التنفيذ
التوثيق مُنظَّم كمسار لكل نظام تشغيل، لأن الخطوات تختلف فعلياً وليس شكلياً:
- Windows — تثبيت
Xmingوتشغيله بخيارno access control، ثم إضافةffmpegإلى متغيّرPath. يُسرد العتاد المتاح أولاً بـffmpeg -list_devices true -f dshow -i dummy، ويُنسخ اسم الكاميرا حرفياً كما يظهر في المخرجات — وهو أكثر موضع يقع فيه الخطأ. - macOS — يعتمد على
ffmpegعبرbrewوXQuartzللعرض، مع تنبيه صريح في التوثيق: الكاميرا المدمجة غير مدعومة، ويلزم استخدام كاميرا USB. - Linux — ما زال مفتوحاً في التوثيق ومُعلَّماً كعمل قيد الإنجاز.
- الحاوية — سكربت
python/main.pyيفتح عنوان UDP مصدراً للفيديو عبرopencv-pythonويعالج الإطارات كأنها قادمة من كاميرا محلية.
تهيئة الحاوية
لكي يصل التدفّق وتظهر النافذة، تحتاج الحاوية إلى فتح منفذ UDP ومعرفة عنوان خادم العرض على المضيف — عبر devcontainer في VS Code:
{
"runArgs": ["-ti", "-p", "1235:1235/udp", "-e", "DISPLAY=<localhostIp>:0.0"]
}أو مباشرة من سطر الأوامر:
docker run -ti -p 1235:1235/udp -e DISPLAY=<localhostIP>:0.0 vscodeوالمهمّ هنا أن DISPLAY يأخذ عنوان المضيف على الشبكة لا localhost، وإلا لم تجد الحاوية خادم X.
أمّا صورة الحاوية فتحتاج مكتبات الترميز والرسوميات قبل بناء OpenCV — منها libavcodec-dev وlibswscale-dev وlibavformat-dev وحزم GStreamer وlibopencv-dev وqtbase5-dev وffmpeg وusbutils، وجميعها مجموعة في ملف .devcontainer/Dockerfile.
النتيجة والدروس
المستودع يقدّم مساراً يعمل من طرفه إلى طرفه على Windows و macOS، وحصد ⭐ 7 نجوم من مطوّرين واجهوا المشكلة نفسها.
- حوّل مشكلة العتاد إلى مشكلة شبكة. ما إن يصبح المصدر عنواناً بدل جهاز، حتى تختفي فروق أنظمة التشغيل من داخل الحاوية بالكامل.
- الاختلاف بين المنصّات جوهري لا تجميلي.
dshowعلى Windows وavfoundationعلى macOS ليسا اسمين لشيء واحد؛ أي توثيق يتظاهر بأن الخطوات موحّدة سيفشل عند أول مستخدم. - التوثيق الصادق أنفع من التوثيق الكامل. ترك مسار Linux مُعلَّماً كـ 🚧 أوضح للقارئ من إخفائه أو ملئه بخطوات غير مُجرَّبة.
الروابط
- المستودع: github.com/i99dev/Docker-with-WebCam