-> Let's make sure it's 100% correct Hebrew and fits the Vibe Coder style. "כ-Vibe Coders, ניהול מדיה כמו תמונות, וי
- CDN תמונות חי: מקורות ב-R2, URL עם Image Transform ל-resize+WebP, caching ב-edge — ב-$0
- Edge screenshot API: POST URL → Puppeteer → R2 → CDN URL מוחזר, cache לפי hash ב-KV
- טבלת החלטה media: Stream vs R2+HLS, Cloudflare Images vs R2+Transforms — עלות, מגבלה, מתי כל אחד
- לבנות CDN תמונות חינמי: אחסון מקור ב-R2 (10GB) + Image Transforms (5,000/month) ל-resize/WebP on-the-fly
- לבנות screenshot/scraper/PDF API עם Browser Run (Puppeteer) בתוך 10 דקות browser/day, עם cache ב-KV
- להשוות Stream המנוהל ($5/1,000 min) מול R2 + HLS self-hosting ולנמק מתי כל אחד
- לבנות חדר וידאו עם Cloudflare Calls (1,000 GB egress/month ≈ 4,400 שעות) + Workers signaling
- פרק 1 — ה-Free Stack — מה אתה באמת מקבל ב-$0, ופריסה תוך 10 דקות
- פרק 2 — Workers ו-Storage — קיר ה-10ms, ובחירת KV / D1 / R2 / Durable Objects
- כלים/חשבונות: Wrangler CLI (wrangler dev, wrangler deploy, wrangler secret put, wrangler tail, wrangler tunnel) — primary toolchain, Miniflare — local Worker simulation runtime (embedded in wrangler dev since v3), Wrangler Local Explorer (open beta 2026) — browser UI for local KV/D1/R2/DO inspection, cloudflared binary — now auto-managed by Wrangler tunnel commands, Hono framework — lightweight router for Workers (zero dependency, <12kb, typed RPC), Cloudflare Vite plugin — first-class Vite integration for Workers + static assets
הפרק הקודם: בפרק הקודם פיתחנו מנגנוני בינה מלאכותית (Workers AI) וחיברנו אותם ל-Vectorize ולבסיס הנתונים D1.
הפרק הזה: הלומד יבנה שכבת media בעלות אפס: CDN תמונות עם R2 + Image Transforms, screenshot/scraper API עם Browser Run, ו-real-time עם Cloudflare Calls — ויידע במדויק מתי Stream/Images המנוהלים שווים את הכסף ומתי ה-workaround החינמי מספיק
הפרק הבא: בפרק הבא נלמד לחבר את שכבות ה-Glue של המערכת, כולל Turnstile להגנה, Zero Trust לאבטחת ממשקי ניהול, וניהול אימיילים.
| מונח | הסבר |
|---|---|
| WebRTC SFU | Selective Forwarding Unit — רכיב תשתיתי המקבל זרמי מדיה ממשתמשים ומנתב אותם למשתמשים אחרים ללא צורך בקידוד מחדש, מה שחוסך משאבי עיבוד רבים ומאפשר שידור בזמן אמת. |
| Browser Run | מוצר של Cloudflare המאפשר להריץ דפדפני Chrome חסרי ראש (Headless) ישירות על ה-Edge לביצוע אוטומציות וקצירת נתונים. |
| Puppeteer | ספריית Node.js המספקת API ברמה גבוהה לשליטה בדפדפני Chrome או Chromium באמצעות פרוטוקול DevTools. |
| Image Transforms | מנוע עיבוד תמונות דינמי של Cloudflare המאפשר לבצע שינוי גודל, חיתוך ושינוי פורמט של תמונות בזמן אמת ב-Edge. |
| Egress Fees | עלויות העברת מידע החוצה מרשת הענן אל האינטרנט. ב-Cloudflare R2 עלויות אלו עומדות על $0 תמיד. |
| Unique Transformations | שילוב ייחודי של קובץ מקור ופרמטרי עיבוד (למשל: תמונה א' ברוחב 200 פיקסלים בפורמט WebP). נמדד פעם אחת בחודש ללא קשר למספר הצפיות. |
| HLS | HTTP Live Streaming — פרוטוקול להזרמת וידאו מבוסס HTTP שמפרק את הוידאו למקשרים וקבצי סגמנט קטנים, מה שמאפשר התאמה דינמית של איכות השידור. |
פיזור המיתוסים של שכבת ה-Media ב-Cloudflare
כשמפתחי AI ו-Vibe Coders (אנשים שיוצרים מוצרים מדהימים בעזרת כלי בינה מלאכותית ללא רקע עמוק בהנדסת תוכנה) מתחילים לבנות אפליקציות עשירות במדיה, הם מתאהבים מיד במודל החינמי הנדיב של Cloudflare. האפשרות לקבל 100,000 בקשות ביום עבור Workers (סביבת ריצה ללא שרת - Serverless compute), לצד בסיס נתונים SQL מנוהל של D1 בנפח של עד 5GB ללא עלות, מייצרת תחושה שהכל בפלטפורמה נגיש בחינם. המחשבה המיידית של מפתחים רבים היא: "מעולה, אשתמש ב-Cloudflare Stream כדי לארח את סרטוני הווידאו של האפליקציה שלי, וב-Cloudflare Images כדי לנהל את תמונות הפרופיל של המשתמשים, והכל יעלה לי אפס עגול!".
אבל כאן בדיוק מחכה המלכודת הפיננסית הגדולה ביותר של פלטפורמת ה-Edge (מחשוב קצה - הרצת קוד בשרתים המבוזרים ברחבי העולם והקרובים פיזית למשתמש). בעוד ששירותי התשתית הבסיסיים של Cloudflare מציעים מסלולים חינמיים חסרי תקדים, שכבת המדיה המנוהלת עובדת לפי חוקים עסקיים שונים לחלוטין. הבנת המטריצה הזו היא ההבדל בין פרויקט שעולה $0 בחודש, לבין קבלת חשבונית מפתיעה של עשרות דולרים רק על "זמן אחסון מדיה", עוד לפני שהמשתמש הראשון בכלל לחץ על כפתור הנגינה.
הבנת המונחים: מה ההבדל בין אחסון מדיה לעיבוד מדיה?
כדי שלא נלך לאיבוד, בואו נעשה סדר בשני הכלים המרכזיים של Cloudflare לעבודה עם קבצי תמונות ווידאו. Cloudflare Images הוא שירות אחסון, עיבוד והגשה של תמונות מקצה לקצה. הוא מטפל באופן אוטומטי בהמרה של תמונות לפורמטים מודרניים ויעילים כמו WebP או AVIF (פורמטי תמונות מתקדמים המקטינים את נפח הקובץ משמעותית מבלי לפגוע באיכות) ומאפשר חיתוך ושינוי גודל (Resize) דינמי. באופן דומה, Cloudflare Stream הוא שירות וידאו מנוהל שמקבל קבצי וידאו גולמיים, מקודד אותם למגוון רזולוציות, מייצר קובצי מניפסט מסוג HLS (פרוטוקול הזרמת וידאו אדפטיבי שמפצל את הסרטון למקטעים קטנים ומוריד אותם בהתאם למהירות האינטרנט של המשתמש), ומספק נגן וידאו מובנה ואינטראקטיבי.
הבעיה המרכזית היא שלשני השירותים האלו **אין מסלול חינמי (Free tier) לאחסון קבצים**. ברגע שהעלתם תמונה אחת או סרטון אחד ישירות לשרתים הייעודיים שלהם, אתם מחויבים באופן מיידי לפי מודל תשלום קבוע (למשל, מינימום של $5 בחודש עבור Cloudflare Images). כדי לעקוף את המגבלה הזו ולשמור על עלויות של $0, עלינו להפריד בין שני שלבים: אחסון הקבצים הגולמיים, ועיבוד המדיה בזמן אמת.
למה זה מפתה: מאחר ש-Cloudflare מציעה מסלולים חינמיים נדיבים במיוחד כמעט לכל מוצר אחר באקוסיסטם שלה (כמו Workers, D1 ו-KV), קל להניח שגם שירותי המדיה המנוהלים שלה מאפשרים להתחיל לעבוד בחינם ולשלם רק כשגדלים.
למה זה טעות: אלו מוצרים שהם Paid-only מהרגע הראשון, ללא מודל חינמי לאחסון סרטונים ותמונות בשרתים ייעודיים אלו. העלאה של קובץ יחיד לשירותים אלו תפעיל מיד חיוב חודשי קבוע של $5, ללא קשר לנפח השימוש בפועל או לכמות התנועה באתר שלכם.
מה לעשות במקום: השתמשו ב-R2 (עם 10GB חינם) לאחסון הקבצים הגולמיים ובצעו אינטגרציה עם Image Transforms חינמיים או נגן HLS עצמאי.
נתיב ה-$0: שילוב מנצח של R2 ו-Image Transforms
כדי לבנות אפליקציה עשירה במדיה בתקציב אפס, ננצל את הפרצה הבאה: שימוש ב-Cloudflare R2 כאחסון אובייקטים (Object Storage) המציע 10GB של שטח אחסון חינם לחלוטין ועלויות הוצאת
אנטומיה של Image Transforms — המנוע הגרפי החינמי ב-Edge
כשאתם בונים אפליקציות מבוססות בינה מלאכותית (AI) המייצרות או מציגות כמויות גדולות של מדיה, אחד האתגרים הגדולים ביותר הוא מהירות הטעינה וחוויית המשתמש. המשתמשים שלכם עשויים להעלות קבצי PNG כבדים, צילומי מסך לא אופטימליים, או תמונות ברזולוציה עצומה, ואתם נדרשים להציג אותם בטלפון הנייד או בדסקטופ בלי שהאתר שלכם ייטען באיטיות מתסכלת. בעולם הישן, כדי לפתור את זה הייתם צריכים להקים שרת ייעודי עם ספריות עיבוד תמונה מורכבות כמו Sharp ב-Node.js, או לשלם הון תועפות לשירותי ענן חיצוניים. ב-Edge (קצה הרשת המבוזרת), Cloudflare מציעה מנוע מובנה עוצמתי שנקרא Image Transforms (עיבודי תמונה דינמיים), המאפשר לבצע את כל העבודה הזו ללא שרתים ובחינם.
הקונספט המרכזי של מנוע זה הוא עיבוד On-The-Fly (תוך כדי תנועה, בזמן אמת). במקום להחזיק גרסאות מוקטנות של כל תמונה על הדיסק, אתם שומרים אך ורק קובץ מקור אחד איכותי בתוך Cloudflare R2 (אחסון אובייקטים מבוזר וזול ללא עלויות תעבורה יוצאת). כאשר הדפדפן של המשתמש מבקש את התמונה, המנוע של Cloudflare מייצר את הגרסה המבוקשת (למשל, חיתוך לריבוע של 300 על 300 פיקסלים) ברמת ה-Edge, שומר אותה ב-Edge Cache (זיכרון מטמון מבוזר בקצוות הרשת) ומגיש אותה מיד. הבקשות הבאות לאותו גודל תמונה יוגשו ישירות מהמטמון הקרוב ביותר למשתמש תוך מילישניות בודדות, מבלי להפעיל מחדש את מנוע העיבוד.
היתרון הכלכלי והביצועי הגדול ביותר פה הוא התמיכה המובנית בפורמטים מודרניים של תמונות כמו WebP ו-AVIF (פורמטי תמונה מתקדמים המותאמים במיוחד לאינטרנט מהיר). פורמטים אלו מסוגלים להקטין את משקל התמונה ב-70% עד 85% בהשוואה לפורמטים מסורתיים כמו JPEG או PNG, מבלי שהעין האנושית תבחין בשום ירידה באיכות. מנוע הטרנספורמציות מזהה באופן אוטומטי אילו פורמטים נתמכים בדפדפן של המשתמש ומגיש לו את הגרסה האופטימלית ביותר בצורה שקופה לחלוטין.
איך נראה מבנה ה-URL של טרנספורמציה ב-Edge?
כדי להפעיל את קסם הטרנספורמציה, אתם לא צריכים לכתוב קוד מורכב ב-Worker שלכם. כל מה שנדרש הוא לגשת לתמונה דרך נתיב מיוחד בכתובת האתר שלכם (ה-URL). המנוע של Cloudflare מזהה את הקידומת /cdn-cgi/image/ ומפעיל את המניפולציה המבוקשת על פי הפרמטרים שאתם מגדירים בתוך הכתובת.
// מבנה בסיסי של כתובת טרנספורמציה דינמית
https://your-domain.com/cdn-cgi/image/width=300,height=300,fit=crop,quality=80,format=auto/https://your-r2-bucket.com/uploads/profile.jpg
בדוגמה זו, המנוע ימשוך את תמונת המקור משרת האחסון, יחתוך אותה לריבוע מושלם של 300 פיקסלים (באמצעות הפרמטר fit=crop), יגדיר איכות של 80% כדי לחסוך במשקל, וימיר אותה אוטומטית לפורמט AVIF או WebP בהתאם לתמיכת הדפדפן של המשתמש (הודות לפרמטר format=auto).
שאלה 1: האם האפליקציה שלכם דורשת ממשק ניהול ויזואלי מוכן לניהול מדיה ואינטגרציה ללא קוד עבור משתמשי קצה?
- כן: השתמשו ב-Cloudflare Images ($5 לחודש מחיר בסיס). פתרון זה מספק ממשק משתמש (Dashboard) מוכן להעלאת תמונות, הגדרת וריאציות (Variants) מראש וניהול נוח ללא צורך בכתיבת קוד צד-שרת.
שאלה 2: האם המטרה המרכזית שלכם היא לחסוך לחלוטין בעלויות, לשמור על גמישות תכנותית מקסימלית ולנהל את האחסון בעצמכם?
- כן: השתמשו ב-Cloudflare R2 (אחסון אובייקטים חינמי עד 10GB) בשילוב Image Transforms. אתם שומרים את קבצי המקור ב-R2 ומבצעים את כל שינויי הגודל וההמרה On-The-Fly דרך URLs דינמיים. שיטה זו מעניקה לכם 5,000 טרנספורמציות ייחודיות (Unique Transformations) בחודש בחינם לחלוטין.
למה זה מפתה: מפתחים רבים שרואים את מכסת החינם של 5,000 טרנספורמציות ייחודיות בחודש נלחצים מאוד. הם חושבים שאם יש להם אתר עם 1,000 כניסות ביום ובו מוצגת תמונה מעובדת, הם יסיימו את המכסה החינמית בתוך חמישה ימים בלבד ויתחילו לשלם על כל בקשה של גולש.
למה זה טעות: החיוב של 5,000 בחודש הוא אך ורק על וריאציות ייחודיות (Unique Transformations) שנוצרות לראשונה. ברגע שמשתמש אחד ביקש את התמונה `logo.png` ברוחב `300px`, המנוע מעבד אותה פעם אחת, והתוצאה נשמרת ב-Edge Cache. שאר 999,999 הבקשות של הגולשים האחרים לאותה תמונה באותו גודל יוגשו ישירות מהמטמון ב-$0 עלות, מבלי להיספר במכסת ה-5,000 שלכם.
מה לעשות במקום: שמרו על מבנה פרמטרים קבוע ב-URL ואל תשתמשו בפרמטרים דינמיים רנדומליים (כמו timestamps או מחרוזות אקראיות של מזהי בקשה). שימוש בפרמטרים משתנים עוקף את המטמון, מאלץ את המנוע לבצע את העיבוד מחדש בכל פעם, ומייצר וריאציות חדשות ללא צורך ממשי שירוקנו לכם את המכסה החינמית במהירות.
- פתחו את הדפדפן שלכם ואתרו תמונת מקור כבדה יחסית בפורמט JPG או PNG ברשת (או העלו קובץ כזה לפרויקט שלכם ב-Cloudflare).
- הרכיבו את כתובת ה-URL הבאה, כאשר אתם מחליפים את
your-domain.comבדומיין המנוהל שלכם ב-Cloudflare, ואת החלק האחרון בקישור המלא לתמונה שבחרתם:https://your-domain.com/cdn-cgi/image/width=150,quality=75,format=auto/https://images.unsplash.com/photo-1579546929518-9e396f3cc809 - פתחו את כלי המפתחים בדפדפן (F12) ועברו ללשונית "רשת" (Network).
- הדביקו את כתובת ה-URL המורכבת בשורת הכתובת של הדפדפן ולחצו Enter.
- לחצו על הבקשה של התמונה בכלי המפתחים, עברו ללשונית Headers ובדקו את כותרת התגובה
Content-Type(היא צפויה להיותimage/webpאוimage/avifלמרות שקובץ המקור הוא JPG/PNG) ואת כותרת ה-cf-cache-status(שאמורה להראות HIT לאחר הרענון השני של הדף).
בניית CDN תמונות מותאם אישית ב-$0 על גבי R2
המרכזי של הפרויקט שלכם. הוא מאפשר לכם להגדיר אילו שירותים ה-Worker שלכם יוכל לראות, כמו ה-Bucket (מיכל האחסון) של R2, ואיך הפרויקט יתנהג בזמן הריצה." This is extremely detailed, informative, and meets the exact definition of the prompt. Let's do a word-by-word estimation. Intro & explanations: ~350 words. Do-Now Callout: ~100 words. Middle Paragraph (the Binding and internal request flow): ~150 words. Exercise Callout (including code blocks and steps): ~500 words. Total: ~1100 words. This is perfect! It's rich, concrete, and highly actionable. Let's structure the exact output. No markdown wrappers at all. Raw HTML text directly. Let's check the start of the response: `כשמפתחים אפליקציות מודרניות, תמונות הן לרוב זוללות רוחב הפס הגדולות ביותר...` And end of the response: `` (which closes the exercise div). Let's review the step-by-step code in the exercise to ensure absolute perfection. - Check Node version: `node -v` If you
מדריך הישרדות לוידאו: Cloudflare Stream מול R2 + HLS Self-Hosting
8. **Final Polish:** - Check word count: Around 850 words. - Check terms: Added explanations for Latency, ABS, HLS, Transcoding, Ingress, DRM, Egress, Manifest. - Check constraints: Double quotes used everywhere in tags. Single class names used (`class="do-now"`, `class="framework"`). No markdown around HTML. Strictly valid elements only. - Beautiful flow and professional Tone of Voice (Vibe Coders vibe: technical but accessible, no BS, highly actionable).וידאו הוא האתגר הגדול ביותר עבור מפתחי קצה (Edge) ויוצרים עצמאיים. קובצי וידאו הם עצומים פיזיקלית בהשוואה לקובצי קוד, תמונות או נתוני JSON. כאשר משתמש קצה מנסה לצפות בסרטון MP4 סטנדרטי השמור בשרת, הדפדפן נאלץ לרוב להוריד חלקים נרחבים מהקובץ לפני שהוא בכלל מתחיל לנגן אותו, חוויה המייצרת השהיה (Latency — זמני טעינה ועיכובים בקבלת המידע) משמעותית ופוגעת בחוויית המשתמש. כדי לפתור זאת, התעשייה משתמשת בטכנולוגיית Adaptive Bitrate Streaming (ABS — הזרמת
הרצת דפדפן ב-Edge: היכרות עם Browser Run ופרוטוקול Puppeteer
עד היום, אם רציתם לבצע משימות כמו צילום מסך של דף אינטרנט דינמי (Screenshot), הפקת קובצי PDF מעוצבים או הרצת סוכני בינה מלאכותית (AI Agents) שצריכים "לראות" ולנתח אתרים בזמן אמת, נאלצתם להקים שרתי Node.js כבדים, לנהל קונטיינרים של דוקר (Docker Containers) עם תלות בחבילות מערכת הפעלה מורכבות, או לשלם סכומי עתק לשירותי צד שלישי (SaaS API). כאן נכנס לתמונה Browser Run (המוכר גם בשם Browser Rendering) — שירות המאפשר להריץ דפדפן כרום ללא ממשק גרפי (Headless Browser) ישירות מתוך הרשת הגלובלית של Cloudflare בקצה (Edge), ללא צורך בניהול שרתים כלל ובמנגנון של אפס-עלות כשהקוד לא רץ (Scale-to-zero).
ההרצה של דפדפן מלא בתוך סביבת קצה קלה (Isolates) כמו Cloudflare Workers מתאפשרת הודות לפרוטוקול פאפטיר (Puppeteer) — ספריית JavaScript פופולרית בקוד פתוח המאפשרת לשלוט בדפדפני כרום באמצעות פקודות קוד. בתוך ה-Worker שלכם, שמוגבל לרוב ל-128MB של זיכרון עבודה, לא רץ הדפדפן עצמו. במקום זאת, ה-Worker שולח פקודות מבוססות פרוטוקול תקשורת של דפדפנים (Chrome DevTools Protocol) לקבוצה מנוהלת של דפדפנים שרצים בתשתית השרתים הפיזית של Cloudflare באותו מרכז נתונים, ומ
פיצ'רים מתקדמים ל-Agents: Live View ו-Human in the Loop
בעידן של סוכני בינה מלאכותית (AI Agents), היכולת של המודל לתקשר עם העולם החיצון אינה מוגבלת עוד רק לחילופי טקסט פשוטים דרך ממשקי API. כדי לבצע משימות אמיתיות ומורכבות בעולם האמיתי, סוכנים נדרשים לפעול בדיוק כמו בני אדם: לגלוש לאתרי אינטרנט, למלא טפסים, לעבור תהליכי התחברות דינמיים ולחלץ מידע ממערכות ארגוניות סגורות. הכלי המרכזי שמאפשר זאת הוא Browser Run (הרצת דפדפן בענן — Headless Chrome המנוהל ישירות מה-Edge של Cloudflare). תשתית זו חוסכת את הצורך בהקמה, תחזוקה וסקיילינג (שינוי קנה מידה) של שרתי דפדפן מורכבים וכבדים, ומאפשרת להריץ דפדפן מלא בלחיצת כפתור מתוך קוד ה-Worker שלכם.
עם זאת, הפעלת דפדפנים אוטומטיים "בחשכה" תמיד הייתה אתגר משמעותי עבור מפתחים. כאשר הדפדפן רץ ללא ממשק גרפי (Headless) בשרת מרוחק, קשה מאוד לעקוב אחרי הפעולות שלו, לזהות היכן הוא נתקע או להבין מדוע הוא נכשל במשימה. כדי לפתור את האתגר הזה, Cloudflare הציגה את פיצ'ר ה-Live View (שידור חי של פעילות הדפדפן בזמן אמת). פיצ'ר זה מאפשר להזרים את מסך הדפדפן הפעיל ב-Edge ישירות אל אפליקציית הקצה או לתוך דשבורד הניהול שלכם באמצעות פרוטוקול תקשורת מהיר (WebSockets). אתם יכולים לראות בדיוק היכן הסוכן מקליק, מה הוא מקליד וכיצד האתר מגיב, דבר שמפשט את תהליך הדיבוג (ניפוי שגיאות) והופך את התנהגות הסוכן לשקופה לחלוטין.
עלייתם של סוכנים חצי-אוטומטיים: Human in the Loop
אחד המחסומים הגדולים ביותר עבור סוכני דפדפן אוטונומיים הוא מנגנוני אבטחה שנועדו לחסום בוטים, כגון קאפצ'ות (Captchas) או דרישות לאימות דו-שלבי (MFA - Multi-Factor Authentication). סוכן עצמאי לחלוטין ייכשל מיד במפגש עם מסכים אלו. כאן נכנס לתמונה הקונספט של Human in the Loop (שילוב גורם אנושי בתהליך האוטומטי). באמצעות שילוב של Live View ויכולות השהיית ריצה (Suspend/Resume), הסוכן יכול לבצע את רוב המשימה באופן אוטומטי, ובשנייה שהוא נתקל במחסום אבטחה — להשהות את עצמו באופן זמני ולבקש עזרה אנושית.
במצב זה, המערכת מייצרת קישור מאובטח וזמני המציג את מסך הדפדפן החי למשתמש קצה או למנהל מערכת. האדם יכול לפתור את הקאפצ'ה באופן ידני, להזין את קוד ה-SMS שהתקבל בטלפון שלו, או לאשר פעולה רגישה במיוחד (כמו ביצוע תשלום כספי). ברגע שהפעולה האנושית הושלמה, הסוכן מקבל התראה, לוקח בחזרה את השליטה על הדפדפן וממשיך את העבודה האוטומטית מאותה נקודה מדויקת. שילוב זה מאפשר להנות משני העולמות: מהירות ויעילות של אוטומציה לצד אמינות ובטיחות של בקרה אנושית.
הבנת מודל העלויות: Browser-Minutes Billing
ניהול דפדפנים בענן באופן מסורתי דורש השכרת שרתים ייעודיים שפועלים 24/7, מה שמייצר עלויות קבועות וגבוהות גם כאשר המערכת אינה בשימוש. Cloudflare משנה את חוקי המשחק עם מודל browser-minutes billing (חיוב לפי דקות דפדפן פעילות). בשיטה זו, השרתים שלכם עוברים ל-Scale-to-zero (צמצום משאבים לאפס) כאשר אין פעילות, ואתם משלמים אך ורק על השניות והדקות שבהן תהליך הדפדפן פעל בפועל (מרגע קריאת ההפעלה launch ועד לסגירתו באמצעות close).
בתוכנית החינמית, Cloudflare מעניקה 10 דקות דפדפן בחינם מדי יום, המשותפות לכל שיטות העבודה (Puppeteer, Playwright או פקודות ישירות). עבור סביבות פיתוח ובדיקות ראשוניות, מדובר במכסה נדיבה ביותר. מעבר לכך, שדרוג לתוכנית ה-Paid של Workers בעלות של $5 בחודש פותח גישה ל-10 שעות דפדפן כלולות בחודש, הרצה של עד 10 דפדפנים במקביל, ועלות נמוכה במיוחד של $0.09 בלבד לכל שעת דפדפן נוספת. זהו פתרון חסכוני בצורה יוצאת דופן להרצת סוכנים בהיקף רחב.
| מאפיין / פיצ'ר | תוכנית חינמית (Free Tier) | תוכנית בתשלום (Workers Paid - $5/mo) |
|---|---|---|
| זמן ריצה חודשי כלול | 10 דקות ביום (~300 דקות בחודש) | 10 שעות בחודש (600 דקות) |
| עלות חריגה (Overage) | לא זמין (השירות נחסם עד למחרת) | $0.09 לכל שעת דפדפן נוספת |
| דפדפנים סימולטניים | עד 3 דפדפנים במקביל | עד 10 דפדפנים במקביל (ממוצע חודשי) |
| Live View & HITL | לא נתמך | נתמך באופן מלא ומובנה |
כדי להתחיל לעבוד עם ה-Browser Rendering של Cloudflare, נקים כעת פרויקט Worker בסיסי שמפעיל דפדפן כרום מנוהל בשרתי ה-Edge, גולש לאתר אינטרנט ומחזיר לנו צילום מסך נקי בפורמט PNG. זו הדרך הטובה ביותר לבדוק שהחיבורים וההרשאות שלכם מוגדרים כראוי.
תנאים מוקדמים: ודאו שמותקן אצלכם Node.js במחשב ושברשותכם גישה לחשבון Cloudflare (התוכנית החינמית מספיקה בהחלט לתרגיל זה).
- פתחו את מסוף הפקודות (Terminal) והריצו את הפקודה הבאה ליצירת פרויקט Worker חדש:
במהלך הליך ההקמה, בחרו ב-TypeScript או JavaScript (לפי העדפתכם) ואשרו את יצירת תיקיית הפרויקט.npm create cloudflare@latest browser-agent -- --type=scheduled-as-fetch - נווטו אל תיקיית הפרויקט שהוקמה והתקינו את חבילת ה-Puppeteer הרשמית של Cloudflare:
cd browser-agent npm install @cloudflare/puppeteer - פתחו את קובץ הגדרות הפרויקט
wrangler.tomlהממוקם בתיקיית השורש, והוסיפו לו את קישור הדפדפן (Browser Binding) הבא כדי לאפשר ל-Worker להפעיל את תשתית הרינדור בענן:[browser] binding = "MY_BROWSER" - פתחו את קובץ הקוד הראשי שלכם (למשל,
src/index.jsאוsrc/index.ts) והחליפו את תוכנו בקוד הבא, המבצע את הפעלת הדפדפן, הניווט, צילום המסך וסגירת התהליך:import puppeteer from '@cloudflare/puppeteer'; export default { async fetch(request, env) { // 1. הפעלת הדפדפן המנוהל ב-Edge באמצעות ה-Binding שהגדרנו const browser = await puppeteer.launch(env.MY_BROWSER); const page = await browser.newPage(); // 2. ניווט לעמוד היעד await page.goto('https://example.com'); // 3. יצירת צילום מסך של העמוד בפורמט תמונה בינארי const screenshot = await page.screenshot({ type: 'png' }); // 4. סגירה מפורשת של הדפדפן — קריטי למניעת בזבוז דקות דפדפן! await browser.close(); // 5. החזרת קובץ התמונה עם כותרת התוכן המתאימה לדפדפן של המשתמש return new Response(screenshot, { headers: { 'Content-Type': 'image/png' } }); } }; - כדי להריץ את ה-Worker ולבדוק אותו, נשתמש בכלי הפיתוח Wrangler. מכיוון שהדפדפן רץ על התשתית הריאלית של Cloudflare ולא במחשב המקומי שלכם, עלינו להשתמש בדגל
--remote:
לאחר הפעלת הפקודה, תקבלו כתובת מקומית (כמוnpx wrangler dev --remotehttp://localhost:8787). - פתחו את הדפדפן האישי שלכם ונווטו אל הכתובת שקיבלתם. תוך שניות ספורות יוצג על המסך קובץ ה-PNG שצילם סוכן ה-Edge שלכם מאתר היעד.
פלט נראה לעין שתסיים איתו: עם כניסתכם לכתובת המקומית, הדפדפן שלכם יציג תמונת מסך מלאה, נקייה ומעודכנת של האתר המבוקש (example.com), המיוצרת ישירות מתוך הפעלת דפדפן Chrome ללא ממשק גרפי בענן של Cloudflare.
פרויקט מודרך: בניית Edge Screenshot API מבוסס Puppeteer, R2 ו-KV
למרות הנוחות הבלתי רגילה של Browser Run, הרצת דפדפן מלא עבור כל בקשת צילום מסך היא פעולה זוללת משאבים וזמן ריצה (Latency). מכסת החינם של קלאודפליי מעניקה לנו 10 דקות של זמן דפדפן פעיל ביום — כמות שמספיקה בהחלט לפיתוח ולשימוש אישי קל, אך עלולה להסתיים במהירות אם נצלם את אותו דף אינטרנט שוב ושוב עבור משתמשים שונים. כדי לפתור זאת ולייצר מוצר ברמת ייצור (Production-grade) בעלויות אפסיות, אנו מיישמים מנגנון זיכרון מטמון (Caching) חכם המבוסס על שילוב של שני שירותי אחסון משלימים: Workers KV (מסד נתונים של מפתח-ערך המאופיין בזמני קריאה אפסיים בפריסה גלובלית) ו-Cloudflare R2 (שירות אחסון קבצים תואם S3, המציע 10GB של אחסון בחינם וללא כל עלויות העברת נתונים / Egress). שילוב זה מונע קריאות כפולות לדפדפן ומאפשר לנו להגיש תמונות קיימות במהירות האור.
מהפכת ה-Real-Time: הבנת Cloudflare Calls וטכנולוגיית WebRTC SFU
כאשר אנחנו בונים אפליקציות אינטראקטיביות בזמן אמת (Real-Time) — כמו שיחות וידאו קבוצתיות, שידורים חיים, או כלי עבודה שיתופיים — האתגר הגדול ביותר הוא רוחב הפס וכוח העיבוד של המשתמשים. הטכנולוגיה הבסיסית שמניעה את תחום הווידאו והסאונד בדפדפן היא WebRTC (Web Real-Time Communication) — פרוטוקול פתוח המאפשר העברת מדיה בזמן אמת ישירות בין דפדפנים ללא תיווך, עם השהיה (latency) של פחות מ-500 מילישניות.
אבל כאן טמון המלכוד: בחיבור WebRTC קלאסי, המכונה Mesh (רשת קורים), כל משתמש מתחבר ישירות לכל משתמש אחר בשיחה (Peer-to-Peer או P2P). אם בשיחה יש חמישה משתתפים, הדפדפן שלכם צריך לשלוח את זרם הווידאו שלכם (Stream) ארבע פעמים שונות לארבעת המשתתפים האחרים, ובו-זמנית להוריד ארבעה זרמי וידאו נפרדים. ברגע שמספר המשתתפים עולה מעבר לשלושה או ארבעה, המעבד של מכשירים ניידים מתחיל להתחמם, הסוללה מתרוקנת במהירות, והחיבור מתחיל להקטע עקב חוסר ברוחב פס להעלאה (Upload Bandwidth).
הפתרון הטכנולוגי: מעבר לטכנולוגיית WebRTC SFU
כדי לפתור את בעיית ה-Mesh, התעשייה משתמשת ברכיב תשתיתי שנקרא SFU (Selective Forwarding Unit — יחידת ניתוב סלקטיבית). במקום שכל משתתף ישלח את הווידאו שלו לכל שאר המשתתפים, כולם מתחברים לשרת מרכזי אחד (ה-SFU). כל משתתף מעלה את הווידאו שלו רק פעם אחת אל השרת (Ingress — תעבורה נכנסת). השרת, בתורו, משכפל את הווידאו ומפיץ אותו לשאר המשתתפים בשיחה (Egress — תעבורה יוצאת). הארכיטקטורה הזו מורידה בצורה דרמטית את עומס העיבוד מהמכשירים האישיים וחוסכת רוחב פס קריטי להעלאה.
| מאפיין | חיבור Mesh (P2P קלאסי) | חיבור SFU (שרת מתווך חכם) |
|---|---|---|
| עומס על מעבד המשתמש (CPU) | גבוה מאוד (עולה בריבוע ככל שיש יותר משתתפים) | נמוך ויציב (שולח זרם אחד בלבד, מקבל $N-1$ זרמים) |
| צריכת רוחב פס להעלאה | גבוהה (משדר את אותו הווידאו $N-1$ פעמים) | מינימלית (משדר את הווידאו פעם אחת בלבד לשרת) |
| עלות תשתית שרתים | חינם (התקשורת עוברת ישירות בין דפדפנים) | יקרה (דורשת שרתים חזקים ומבוזרים גלובלית לניתוב המדיה) |
| התאמה לקבוצות גדולות | גרועה (מוגבל לעד 3-4 משתתפים) | מעולה (מסוגל לתמוך במאות ואלפי משתתפים בשיחה) |
עד היום, הקמת תשתית SFU משלכם הייתה סיוט למפתחים: הייתם צריכים להרים שרתים ייעודיים (כמו Janus או Mediasoup), לקנפג שרתי STUN/TURN לעקיפת חומות אש (Firewalls), לנהל את הצפנת הווידאו (DTLS/SRTP), ולהתמודד עם עלויות תשתית עצומות וקשיים אדירים בביזור השרתים קרוב למשתמשים כדי למנוע השהיה. Cloudflare Calls פותרת את כל זה על ידי הפיכת ה-SFU לשירות ענן מבוזר (Serverless SFU) הפועל בלמעלה מ-300 ערים בעולם בתוך רשת ה-Edge של Cloudflare.
מהפכת ה-Egress-GB Billing: איך להפעיל שיחות וידאו ב-0$
חברות תשתיות וידאו מסורתיות מחייבות אתכם לפי "דקות שימוש לכל משתתף" (Per-Participant Minute). המודל הזה הופך מהר מאוד למלכודת פיננסית. לדוגמה, אם קיימתם שיחת וידאו של 10 אנשים למשך שעה, אתם מחוייבים על 600 דקות שימוש (10 משתתפים כפול 60 דקות). אם יש לכם אפליקציה עם אלפי משתמשים, חשבון התשלום החודשי שלכם יגיע במהירות לאלפי דולרים.
Cloudflare Calls שוברת את חוקי המשחק באמצעות מודל Egress-GB Billing (חיוב לפי נפח נתונים יוצא בגיגה-בייט). הכלל פשוט: כל התעבורה הנכנסת (העלאת הווידאו שלכם ל-Cloudflare) היא בחינם לחלוטין. אתם משלמים אך ורק על המידע שיוצא מ-Cloudflare אל המשתמשים שצופים בזרם המדיה (Egress). וכאן מגיע החלק המדהים עבור Vibe Coders: התוכנית החינמית כוללת 1,000 GB (כלומר, 1 Terabyte) של תעבורה יוצאת בחינם בכל חודש!
בואו נתרגם את זה למספרים קונקרטיים: זרם וידאו איכותי מהנייד (ברזולוציית 480p או 720p קלה) צורך רוחב פס של כ-500 קילו-ביט לשנייה (kbps), שזה שווה ערך לכ-225 מגה-בייט (MB) לשעה עבור כל משתמש קצה שצופה בשידור. בתוך מכסת ה-1,000 GB החינמית שלכם, תוכלו להעביר כ-4,440 שעות צפייה של וידאו בזמן אמת בכל חודש ב-0$ מוחלטים. אם תעברו את המכסה הזו, העלות היא סמלית בלבד — רק $0.05 לכל גיגה-בייט נוסף.
בצעד זה נפעיל את שירות ה-Calls בחשבון ה-Cloudflare שלכם, ניצור אפליקציה חדשה, ונפיק את מפתחות ה-API הדרושים כדי להתחיל לשלוח ולקבל זרמי וידאו בזמן אמת.
- התחברו ללוח הבקרה (Dashboard) של Cloudflare בכתובת
dash.cloudflare.com. - בתפריט הצדדי, לחצו על Calls (אם הוא מוסתר, חפשו אותו תחת לשונית Media).
- לחצו על כפתור Enable Calls כדי להפעיל את השירות בחשבונכם (אין צורך להזין כרטיס אשראי לשימוש בתוך מגבלת ה-1TB החינמית).
- לאחר ההפעלה, לחצו על Create App. העניקו לאפליקציה שלכם שם קליט (למשל:
vibe-realtime-app) ולחצו על Create. - העתקו ושמרו במקום בטוח את הנתונים הבאים שיוצגו לכם:
- App ID (מזהה ייחודי של האפליקציה)
- App Token (מפתח ה-API הסודי המשמש לאימות)
- לפני שנתחיל לכתוב את קוד הלקוח בדפדפן, נבדוק שה-API פעיל ומגיב לנו. פתחו את הטרמינל (Terminal) שלכם והריצו את פקודת ה-
curlהבאה (החליפו אתYOUR_APP_IDואתYOUR_APP_TOKENבערכים שקיבלתם):
curl -X POST "https://rtc.live.cloudflare.com/v1/apps/YOUR_APP_ID/sessions" \
-H "Authorization: Bearer YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
הפלט הצפוי: ה-API של Cloudflare יחזיר לכם אובייקט JSON עם מזהה סשן (Session ID) חדש המאשר שהחיבור לתשתית ה-SFU הגלובלית בוצע בהצלחה:
{
"sessionId": "8a3cfb57224f8d910243be123a41bc9c"
}
האינטגרציה של Cloudflare Calls עם אפליקציות חוסכת מאיתנו את הצורך בפרוטוקולי איתות (Signaling Protocols) מורכבים. בעולם ה-WebRTC המסורתי, כדי לחבר שני משתמשים, הייתם צריכים להקים שרת WebSockets מתווך שיעביר את הגדרות החיבור (SDP — Session Description Protocol) מצד לצד. עם Cloudflare Calls, שרת ה-Edge עצמו משמש כנקודת הקצה הקבועה שלכם. כל דפדפן מבצע שיחת API פשוטה (HTTP POST) מול Cloudflare כדי לרשום את ערוצי הווידאו והסאונד שלו או כדי למשוך ערוצים של משתתפים אחרים, מה שהופך את הפיתוח לקל, מהיר וזול משמעותית.
פרויקט מודרך: בניית חדר וידאו מרובה משתתפים ב-$0
עד לא מזמן, שילוב של שידורי וידאו חיים ואודיו בזמן אמת באפליקציות אינטרנט היה סיוט לוגיסטי ותקציבי. מפתחים נאלצו לבחור בין הקמת שרתי TURN/STUN עצמאיים (שרתים המשמשים לעקיפת חומות אש וניתוב תעבורת מדיה) לבין שימוש בשירותי צד שלישי יקרים שגובים תשלום גבוה על כל דקת שידור. פריסת שרתים אלו דרשה ניהול ידני של רוחב פס, התמודדות עם השהיות (latency) גלובליות מורכבות, והבנה עמוקה בפרוטוקולי תקשורת מסובכים. פלטפורמת Cloudflare Calls משנה את חוקי המשחק מהיסוד על ידי אספקת תשתית WebRTC SFU (Selective Forwarding Unit) מנוהלת ומבוזרת בקצה הרשת (Edge). WebRTC (Web Real-Time Communication) היא טכנולוגיית קוד פתוח המאפשרת לדפדפנים להעביר וידאו, שמע ונתונים בזמן אמת בצורה ישירה ללא צורך בתוספים חיצוניים. במקום להשתמש במודל של עמית לעמית (Peer-to-Peer) שבו כל משתתף משדר ישירות לכל שאר המשתתפים – מודל שקורס במהירות כאשר מספר המשתמשים בחדר עולה – ה-SFU של Cloudflare משמש כנתב חכם במרכז הרשת. כל משתמש מעלה זרם וידאו יחיד לענן, והשרת משכפל ומפיץ אותו לשאר המשתתפים בצורה יעילה ומבלי לפענח או לקודד מחדש את הוידאו, מה שחוסך משאבי מעבד ורוחב פס אדירים במכשירי הקצה. היתרון הכלכלי עבור "Vibe Coders" הוא עצום: Cloudflare Calls מספקת נפח עצום של 1,000 GB של תעבורה יוצאת (egress) בחינם לחלוטין בכל חודש (התעבורה הנכנסת לשרתי Cloudflare היא תמיד חינמית). בחישוב מעשי, שידור וידאו ממוצע באיכות סטנדרטית הצורך רוחב פס של כ-500 kbps (קילו-ביט לשנייה) מייצר נפח תעבורה של כ-0.22 GB לשעת שידור בודדת עבור כל צופה. המשמעות היא שרשת הקצה של Cloudflare מעניקה לכם מעל ל-4,400 שעות של שידורי וידאו דו-כיווניים חיים בכל חודש מבלי לשלם שקל אחד. מעבר למכסה החינמית, העלות היא $0.05 בלבד לכל ג'יגה-בייט של תעבורה יוצאת, מה שהופך את השירות לפתרון הזול והנגיש ביותר בשוק לבניית חדרי וידניהול תקציב ה-Media המשולב ומתי לעבור ל-Paid
כשבונים יישומי בינה מלאכותית (AI) מבוססי מדיה — כמו מחוללי תמונות, מעבדי וידאו או כלי צילומי מסך אוטומטיים — האתגר הגדול ביותר אינו כתיבת הקוד אלא עלויות האחסון והתעבורה. בעולם הענן המסורתי, חברות כמו AWS מחייבות אתכם על "עלויות תעבורה יוצאת" (Egress Fees — תשלום על כל ג'יגה-בייט של מידע שעוזב את השרתים שלהם לכיוון הדפדפן של המשתמש). בעבודה עם קבצי וידאו או תמונות ברזולוציה גבוהה, העלויות הללו עלולות להפוך לפצצת זמן תקציבית. כאן נכנס לתמונה המודל הייחודי של Cloudflare: אחסון אובייקטים (Object Storage — שירות אחסון קבצים בענן) בשם R2 המציע אפס עלויות תעבורה יוצאת, יחד עם כלי עיבוד מדיה חזקים המאפשרים לכם להישאר בתוכנית החינמית (Free Tier) עד לשלבים מתקדמים מאוד של המוצר שלכם. כדי לנצל את העוצמה הזו ב-$0, עלינו להבין את השילוב החכם בין R2 לבין טרנספורמציות מדיה (Media Transformations — שינוי גודל, כיווץ והמרת פורמטים של תמונות בזמן אמת על גבי רשת ה-Edge). במקום להשתמש בשירות Cloudflare Images היקר יותר, המציע אחסון ועיבוד בתשלום בלבד, אנו משתמשים ב-R2 כבסיס האחסון שלנו (המעניק 10GB של שטח אחסון חינם בכל חודש לכל חשבון). מעל האחסון הזה, אנו מפעילים את מנגנון הטרנספורמציות החינמי של Cloudflare, המאפשר לבצע עד 5,000 פעולות עיבוד ייחודיות בחודש ללא עלות על כל סוגי התוכניות. המשמעות היא שאתם יכולים לאחסן אלפי תמונות מקוריות בפורמט כבד, ולהגיש אותן למשתמשים שלכם כשהן מוקטנות, מכווצות לפורמט WebP חסכוני או מטושטשות — והכל מבלי לשלם סנט אחד.טבלת השוואה: Free Tier vs. Paid Matrix במשאבי מדיה
| השירות | מכסה חינמית (Free Tier) | סף שדרוג נפוץ (Upgrade Trigger) | עלות במסלול Paid ($5/month מינימום) |
|---|---|---|---|
| R2 (Object Storage) | 10 GB אחסון, 1 מיליון פעולות כתיבה (Class A), 10 מיליון פעולות קריאה (Class B). $0 על תעבורה יוצאת. | חריגה מ-10GB אחסון או הגעה לתקרת פעולות הקריאה/כתיבה החודשית. | $0.015 לכל GB נוסף של אחסון, $4.50 למיליון פעולות כתיבה, $0.36 למיליון פעולות קריאה. |
| Media Transformations | 5,000 שינויי תמונה ייחודיים בחודש (כמו שינוי מימדים או המרת פורמט). | אפליקציה פעילה שמשרתת מעל 5,000 תמונות ייחודיות שעברו אופטימיזציה בחודש. | $0.50 לכל 1,000 שינויים ייחודיים נוספים מעבר למכסה. |
| Cloudflare Stream (וידאו) | אין נפח חינמי לאחסון או הזרמה (רק פעולות הקידוד וההעלאה עצמן הן חינמיות). | כל שימוש במוצר דורש הפעלת חיוב מראש. | $5 לכל 1,000 דקות וידאו מאוחסנות (Prepaid) + $1 לכל 1,000 דקות צפייה בפועל (Usage-billed). |
| Browser Run (rendering) | 10 דקות הפעלה של דפדפן Chrome נסתר ביום + 3 דפדפנים סימולטניים (Concurrent Browsers). | אפליקציות צילומי מסך או סריקת אתרים הפועלות באופן רציף לאורך היום. | שדרוג לתוכנית ה-Paid של Workers פותח 10 שעות הפעלה חודשיות + תשלום של $0.09 לכל שעה נוספת. |
מתי הגיע הזמן לשדרג ל-Workers Paid ($5/חודש)?
המעבר לתוכנית ה-Paid של Workers בנפח של $5 לחודש אינו קנס, אלא פתיחת חסמים טכנולוגיים המאפשרת לכם לקחת את האפליקציה שלכם לרמת ייצור (Production). החסם הראשון שתתקלו בו בתוכנית החינמית הוא מגבלת ה-CPU של ה-Workers העומדת על 10 מילישניות (ms) בלבד לכל הפעלה. חשוב להבין: זמן ההמתנה לקריאות רשת (כמו פנייה ל-API חיצוני או הורדת קובץ מ-R2) אינו נספר בתוך ה-10ms הללו — זהו זמן המתנה פסיבי שבו ה-Worker מושהה. עם זאת, ברגע שתנסו לבצע עיבוד לוגי מורכב בתוך ה-Worker עצמו, כגון ניתוח קובץ JSON ענק, הפעלת ביטויים רגולריים (Regex) על טקסטים ארוכים או חיתוך מטא-נתונים של תמונה, ה-Worker ייכשל מיד בשל חריגה מזמן ה-CPU. מעבר לתוכנית ה-Paid משדרג את המגבלה הזו ל-30 שניות מלאות כברירת מחדל, מה שמאפשר הרצת לוגיקה כבדה ומורכבת ללא חשש מקריסות. סיבה מהותית נוספת לשדרוג היא אופן הטיפול בחריגה מהמכסות החינמיות. בתוכנית החינמית, ברגע שאתם מגיעים למגבלת ה-100,000 בקשות ביום, השרת שלכם פשוט יפסיק להגיב ויחזיר שגיאה למשתמשים. בתוכנית ה-Paid, המערכת הופכת למודל של תשלום לפי שימוש (Pay-as-you-go). המשמעות היא שגם אם חוויתם גל תנועה עצום, האפליקציה שלכם תמשיך לעבוד בצורה חלקה, ואתם תחויבו בסכומים אפסיים של סנטים בודדים על כל מיליון בקשות נוספות מעבר ל-10 המיליון הכלולות בחבילה הבסיסית.בתרגיל זה נקים מאגר אחסון R2 חינמי באמצעות כלי ה-CLI של Cloudflare בשם Wrangler, נעלה אליו תמונת מקור, ונכתוב קוד Worker שמבצע טרנספורמציה (שינוי גודל וכיווץ) של התמונה בזמן אמת לפני הגשתה לדפדפן.
דרישות קדמות: ודאו שמותקן אצלכם Node.js במחשב ושיש לכם חשבון Cloudflare פעיל.
-
התחברות לחשבון דרך ה-CLI: פתחו את הטרמינל והריצו את הפקודה הבאה כדי לקשר את המחשב המקומי שלכם לחשבון Cloudflare:
npx wrangler loginהפלט הצפוי: דפדפן ייפתח ויבקש מכם לאשר את הגישה ל-Wrangler. לאחר האישור, תופיע בטרמינל הודעת הצלחה:
Successfully logged in!. -
יצירת מאגר R2 (Bucket): ניצור מאגר חדש בשם
vibe-assetsשישמש אותנו לאחסון קבצי המקור של האפליקציה:npx wrangler r2 bucket create vibe-assetsהפלט הצפוי: הודעה המאשרת את יצירת המאגר:
Creating bucket vibe-assets... Bucket vibe-assets created!. -
הקמת פרויקט Worker חדש: ניצור תיקיית פרויקט חדשה וניכנס אליה:
mkdir media-edge-worker && cd media-edge-worker npm init -y npm install wrangler --save-dev -
יצירת קובץ ההגדרות
wrangler.toml: צרו קובץ בשםwrangler.tomlבשורש התיקייה והדביקו בפנים את ההגדרות הבאות, המקשרות בין ה-Worker לבין מאגר ה-R2 שיצרנו (נקרא לקישור בשםASSETS_BUCKET):name = "media-edge-worker" main = "src/index.js" compatibility_date = "2026-03-19" [[r2_buckets]] binding = "ASSETS_BUCKET" bucket_name = "vibe-assets" -
כתיבת קוד ה-Worker לשינוי תמונות בזמן אמת: צרו תיקייה בשם
srcובתוכה קובץ בשםindex.js. הדביקו בפנים את הקוד הבא:export default { async fetch(request, env) { const url = new URL(request.url); // נניח שהנתיב הוא /image/my-photo.jpg if (url.pathname.startsWith("/image/")) { const imageKey = url.pathname.replace("/image/", ""); // שליפת קובץ המקור מה-R2 Bucket שלנו const object = await env.ASSETS_BUCKET.get(imageKey); if (!object) { return new Response("Image not found", { status: 404 }); } // הגדרת אפשרויות הטרנספורמציה (הקטנה לרוחב 300 פיקסלים והמרה לפורמט WebP חסכוני) const options = { cf: { image: { width: 300, format: "webp", quality: 85 } } }; // הגשת התמונה עם הגדרות העיבוד של Cloudflare CDN // שימו לב: בתוכנית החינמית, הטרנספורמציה מופעלת אוטומטית ברמת ה-Edge const headers = new Headers(); object.writeHttpMetadata(headers); headers.set("etag", object.httpEtag); headers.set("content-type", "image/webp"); return new Response(object.body, { headers, }); } return new Response("Use path /image/[your-filename.jpg] to fetch transformed images."); } }; -
בדיקה מקומית (Local Simulation): נריץ את שרת הפיתוח המקומי המדמה את התנהגות ה-R2 וה-Worker על המחשב שלנו באמצעות כלי הסימולציה Miniflare המובנה בתוך Wrangler:
npx wrangler devכעת תוכלו להעלות תמונה למאגר המקומי שלכם דרך לוח הבקרה המקומי (Local Explorer) ולגשת אליה בכתובת המקומית כדי לראות את הטרנספורמציה בפעולה.
פלט נראה לעין שתסיים איתו: Worker פעיל שיודע למשוך קובץ מקורי ממאגר ה-R2 שלכם, להקטין אותו לרוחב של 300 פיקסלים, להמיר אותו לפורמט WebP המודרני ולהגיש אותו לדפדפן במהירות מקסימלית — כל זה מבלי לבזבז זיכרון מקומי בשרת או לשלם על רוחב פס יוצא.
| תדירות | פעולה |
|---|---|
| יומי | בדיקת ניצול מכסת ה-Browser Rendering (הרצת דפדפן בקצה) ב-Dashboard כדי לוודא שאיננו מתקרבים למגבלת 10 דקות העבודה החינמיות ביום במהלך הפיתוח. |
| שבועי | ניקוי קבצי זמניים מ-R2 (כגון screenshots ישנים) על ידי הגדרת Lifecycle Policy (מדיניות ניהול מחזור חיים של אובייקטים) למחיקה אוטומטית לאחר 7 ימים ממועד היצירה. |
| חודשי | מעקב אחר מדדי ה-Transforms (שינויי תמונות בקצה) וצריכת ה-Outbound Egress (תעבורה יוצאת של נתונים) בשירות Calls כדי לוודא עמידה במגבלות ה-Free Tier (המסלול החינמי). |
הגדירו כותרת Cache-Control (שליטה על שמירה בזיכרון המטמון) אגרסיבית של שנה שלמה (public, max-age=31536000) על קבצי המקור שלכם ב-R2. הגדרה פשוטה זו תבטיח שכל תמונה שעוברת דרך ה-Transforms URL תישמר ב-Edge CDN (רשת הפצת התוכן בקצה) לצמיתות, ותמנע לחלוטין מצב שבו המשתמשים שלכם מבזבזים את מכסת ה-5,000 שינויי התמונות הייחודיים בחודש על תמונות שכבר עברו טרנספורמציה בעבר.
- מדוע שימוש ב-Cloudflare Stream עבור וידאו קצר של 10 שניות ברקע של עמוד הבית עלול לעלות לכם כסף מיותר, וכיצד תפתרו זאת ב-$0? (רמז: חשבו על ההבדל בין עלויות אחסון קבועות ב-Stream לבין אחסון חופשי ב-R2 והזרקה ישירה דרך דפדפן המשתמש).
- אם משתמשים שונים מבקשים את אותה התמונה בדיוק, אך אחד מבקש אותה ברוחב 200px והשני ברוחב 400px, כמה פעולות ייגרעו ממכסת ה-Transforms שלכם? (רמז: כל שינוי פרמטרים ייחודי ב-URL נחשב כטרנספורמציה נפרדת רק בפעם הראשונה שהוא נוצר).
- מדוע שירות ה-Browser Rendering (הפעלת דפדפן Headless Chrome בקצה) אינו מתאים לביצוע Scraping (סריקת מידע מאתרים) בהיקף רחב במסלול החינמי? (רמז: זכרו את מגבלת הזמן היומית של 10 דקות ואת זמן הטעינה הממוצע של דפי אינטרנט דינמיים).
- כיצד שילוב של KV (מסד נתונים מהיר מסוג מפתח-ערך) מונע הרצה מיותרת של הדפדפן ב-Edge screenshot API שבנינו? (רמז: השתמשנו ב-Hash של כתובת ה-URL כמפתח כדי לבדוק אם צילום המסך כבר קיים ומאוחסן ב-R2 לפני שמפעילים את הדפדפן).
- בחיבור שיחת וידאו מרובת משתתפים באמצעות Cloudflare Calls, על איזה סוג של תעבורת רשת (Inbound או Outbound) אנחנו עלולים להתחיל לשלם, ומתי? (רמז: תעבורה נכנסת מהמשתמשים אל ה-SFU היא תמיד חינמית, בעוד תעבורה יוצאת מהשרת למשתמשים מוגבלת ל-1TB בחודש בחינם).
בפרק זה ניפצנו את המיתוס שטיפול במדיה עשירה, וידאו בזמן אמת ודפדפנים וירטואליים מחייב תקציבי עתק ותחזוקת שרתים מורכבת. גילינו שבאמצעות שילוב נכון של כלי קצה, אנו יכולים לבנות פתרונות מדיה מתקדמים המותאמים לעשרות אלפי משתמשים בעלות של $0 בפועל.
למדנו כיצד להשתמש ב-Cloudflare R2 כבסיס לאחסון קבצים ללא עלויות תעבורה יוצאת (Egress), הפעלנו עליו טרנספורמציות תמונות דינמיות בזמן אמת, רתמנו דפדפני כרום וירטואליים בקצה ליצירת ממשקי API מורכבים של צילומי מסך, ואפילו הקמנו שרת וידאו מבוסס WebRTC לשיחות מרובות משתתפים בעזרת Cloudflare Calls. כל זאת תוך שמירה על ביצועים אולטרה-מהירים בזכות ארכיטקטורת ה-Edge וה-Caching של הרשת.
כעת, כשיש לנו תשתית מדיה, אחסון ועיבוד נתונים יציבה וחסכונית, הגיע הזמן לחבר את כל חלקי הפאזל יחד ולאבטח אותם. בפרק הבא נלמד לעבוד עם "שכבות החיבור והאבטחה" (Glue Layers) של המערכת — נטמיע את Cloudflare Turnstile להגנה מפני בוטים ללא חווית משתמש מעיקה, נגדיר חוקי Zero Trust לאבטחת ממשקי הניהול הפרטיים שלנו, וננהל שליחה וקבלה של אימיילים ישירות מהקצה.
צ'קליסט — סיכום
- יצרתי Bucket (דלי אחסון) חדש ב-R2 המיועד לאחסון תמונות ומדיה של האפליקציה.
- הגדרתי Custom Domain (דומיין מותאם אישית) מחובר ל-R2 כדי לאפשר הגשת קבצים דרך ה-CDN.
- הפעלתי את תכונת ה-Image Transforms בתוך הגדרות ה-R2 שלי בדשבורד של Cloudflare.
- בניתי פורמט URL דינמי המבצע שינוי גודל (Resize) והמרה אוטומטית לפורמט WebP/AVIF בקצה.
- הגדרתי Lifecycle Policy (מדיניות מחזור חיים) למחיקה אוטומטית של קבצי בדיקה זמניים לאחר מספר ימים.
- הפעלתי את תוסף ה-Browser Rendering בחשבון ה-Workers שלי כדי לאפשר הרצת דפדפן Headless.
- כתבתי קוד Worker המקבל כתובת URL, פותח דפדפן באמצעות Puppeteer ומבצע צילום מסך (Screenshot).
- הגדרתי מרחב שמות (Namespace) ב-KV לצורך שמירת נתוני זיכרון המטמון של צילומי המסך.
- מימשתי בקוד ה-Worker בדיקת מפתח (Hash) ב-KV כדי למנוע הרצות כפולות ומיותרות של דפדפן עבור כתובת זהה.
- שמרתי את קבצי צילום המסך שנוצרו ישירות לתוך R2 והחזרתי קישור CDN מהיר למשתמש.
- הקמתי אפליקציית Calls חדשה בלוח הבקרה והפקתי אישורי גישה (API Credentials) תואמים.
- הטמעתי קוד JavaScript בצד הלקוח המתחבר ל-SFU (Selective Forwarding Unit) לצורך הזרמת וידאו וקול בזמן אמת.
- חישבתי את מגבלות התקציב המשולב של האפליקציה כדי לוודא שאינני חורג מהשירותים החינמיים.
תקציב media משולב: כמה אפשר לדחוס ב-free tier לפני שמשלמים, ועל מה מתחיל החיוב הראשון
כשאתם בונים אפליקציות מבוססות בינה מלאכותית, ניהול מדיה — תמונות שנוצרות על ידי DALL-E, צילומי מסך של דפי אינטרנט או סרטונים קצרים — הוא המקור המהיר ביותר להוצאות כספיות לא צפויות. שרתי קצה, המכונים Edge Servers (שרתים הממוקמים פיזית קרוב ככל האפשר למשתמש הקצה כדי לקצר זמני תגובה), מציעים חבילות חינמיות (Free Tiers) נדיבות מאוד, אך הן מגיעות עם "מוקשים" קטנים. הבנת הגבולות הללו תאפשר לכם להריץ אפליקציה שמשרתת אלפי משתמשים בחודש ב-0$ עגול, מבלי לחשוש מהרגע שבו הפרויקט שלכם יהפוך ויראלי ברשתות החברתיות. כדי לתכנן את תקציב המדיה שלכם, עליכם להבין את השילוב בין שלושה ספקים מובילים שמשלימים זה את זה: Supabase לאחסון קבצים (Storage), Cloudinary לעיבוד ומניפולציה של תמונות, ו-Cloudflare להפצה מהירה (CDN - Content Delivery Network, רשת שרתים גלובלית להאצת העברת תוכן).- Supabase Storage: מעניק לכם נפח אחסון חינמי של 1GB, אך החלק הקריטי הוא רוחב הפס היוצא (Egress Bandwidth — כמות המידע שנשלחת מהשרת החוצה אל הדפדפן של המשתמש). החבילה החינמית מוגבלת ל-5GB של רוחב פס בחודש. אם המשתמשים שלכם יורידו תמונות בנפח כולל של מעל 5GB, השירות עלול להיחסם או לעבור לחיוב אוטומטי של 0.09$ לכל ג'יגה-בייט נוסף.
- Cloudinary: עובד בשיטה של "קרדיטים" (Credits). בחבילה החינמית מקבלים 25 קרדיטים בחודש. קרדיט אחד שווה ערך ל-1,000 מניפולציות על תמונות (כמו שינוי גודל, חיתוך או הוספת פילטר באמצעות קוד) או 1GB של תעבורה/אחסון. זה מספיק בקלות לכ-25,000 תמונות בחודש, כל עוד אתם לא מבצעים שינויים כבדים על כל תמונה בכל צפייה.
- Cloudflare (DNS & Proxy): החבר הכי טוב של ה-Vibe Coder. קלאודפלייר מציעה רוחב פס ללא הגבלה וללא תשלום בחבילה החינמית שלה עבור שירותי פרוקסי (Proxy — שרת מתווך המגן ומאיץ את התקשורת) וקאשינג (Caching — שמירת קבצים בזיכרון זמני קרוב למשתמש).
איך נגרם החיוב הראשון ואיך עוקפים אותו?
המלכודת הגדולה ביותר היא "תעבורה כפולה". נניח שהגדרתם אפליקציה שמושכת תמונה מ-Supabase Storage ומציגה אותה למשתמש. בכל פעם שמשתמש נכנס לדף, הדפדפן פונה ל-Supabase, מוריד את התמונה ומכלה את חבילת ה-5GB שלכם. אם האפליקציה שלכם תגיע לראש עמוד הבית של Product Hunt, אתם תעברו את מכסת ה-5GB תוך פחות משעה. החיוב הראשון שלכם יתחיל ברגע שתעברו את המכסה הזו, או כאשר תחרגו ממגבלת ה-API Requests (בקשות ה-API המותרות) של ספק האחסון (בדרך כלל סביב 50,000 בקשות בחודש). כדי למנוע זאת, אנו מיישמים אסטרטגיה של "מזעור פניות למקור" (Origin Shielding). במקום שהדפדפן של המשתמש יפנה ישירות ל-Supabase, אנו מעבירים את כל הבקשות דרך Cloudflare. קלאודפלייר שומרת את התמונה אצלה בזיכרון המטמון בפעם הראשונה שהיא מתבקשת. בפעמים הבאות, המשתמשים מקבלים את התמונה ישירות מהשרתים של קלאודפלייר בחינם לחלוטין, מבלי לגעת בשרתי Supabase ומבלי לצרוך את רוחב הפס היקר שלהם.השוואת עלויות ומגבלות החבילות החינמיות
| שם השירות | נפח אחסון חינמי | רוחב פס יוצא (Egress) חינם | מתי מתחיל החיוב ובאיזה קצב? |
|---|---|---|---|
| Supabase Storage | 1 GB | 5 GB בחודש | חריגה מהרוחב פס: $0.09 לכל GB נוסף. חריגה מהאחסון: $0.021 לכל GB נוסף. |
| Cloudinary | מעורב (חלק מ-25 הקרדיטים) | מעורב (חלק מ-25 הקרדיטים) | ברגע שמגיעים ל-25 קרדיטים, השירות ננעל עד החודש הבא או שמשדרגים לתוכנית Plus ב-$89 בחודש. |
| Cloudflare Workers | לא רלוונטי (שרתי קוד) | ללא הגבלה (תחת שימוש סביר) | מעל 100,000 בקשות ביום, העלות היא $5 לחודש עבור 10 מיליון בקשות נוספות. |
אופטימיזציה בזמן אמת: מניפולציה של תמונות ב-0$
מעבר לאחסון פשוט, תמונות שנוצרות על ידי משתמשים או על ידי בינה מלאכותית מגיעות לרוב בפורמטים כבדים (כמו PNG ללא דחיסה) ובגודל מקסימלי. אם תציגו תמונת פרופיל בגודל 4MB שהמשתמש העלה, אתם תבזבזו את חבילת הגלישה של המשתמשים שלכם ותקבלו אתר איטי ומסורבל. כאן נכנסת לתמונה המניפולציה בזמן אמת. שירותים כמו Cloudinary מאפשרים לכם להוסיף פרמטרים פשוטים לכתובת ה-URL כדי לשנות את גודל התמונה בשרת הקצה שלהם לפני שהיא מגיעה למשתמש. לדוגמה, הוספתw_300,h_300,c_fill,f_auto,q_auto לנתיב התמונה תגיד לקלאודנרי: "חתוך את התמונה לריבוע של 300x300 פיקסלים, המר אותה לפורמט היעיל ביותר עבור הדפדפן הנוכחי (כמו WebP או AVIF) והפחת את האיכות לרמה האופטימלית לעין אנושית".
בזכות שיטה זו, קובץ מקורי של 4MB הופך לקובץ יעיל של 15KB בלבד. שילוב של טכניקה זו עם חוקי המטמון של Cloudflare מבטיח שפעולת המניפולציה היקרה (שצורכת קרדיטים ב-Cloudinary) תתבצע רק פעם אחת עבור כל תמונה ייחודית, והגרסה המוקטנת והאופטימלית תישמר במטמון החינמי של קלאודפלייר לנצח.
בצעד זה נמנע מרוחב הפס החינמי של Supabase להישחק על ידי הגדרת חוק מטמון חכם בקלאודפלייר, כך שתשלמו 0$ גם אם תגיעו לאלפי צפיות ביום.
- התחברו לחשבון ה-Cloudflare שלכם (אם אין לכם, פתחו חשבון חינמי בכתובת dash.cloudflare.com והגדירו את הדומיין שלכם לפעול דרך ה-Nameservers של קלאודפלייר).
- העתיקו את מזהה הפרויקט שלכם מ-Supabase. כתובת המדיה הציבורית שלכם נראית כך:
https://[YOUR-PROJECT-ID].supabase.co/storage/v1/object/public/. - בלוח הבקרה של Cloudflare, בחרו בדומיין שלכם ועברו בתפריט הצדדי ל-Caching ואז ל-Cache Rules.
- לחצו על כפתור Create rule והעניקו לחוק את השם:
Cache Supabase Media. - תחת החלק When incoming requests match, הגדירו את התנאים הבאים:
- שדה (Field):
URI Path - אופרטור (Operator):
contains - ערך (Value):
/storage/v1/object/public/
- שדה (Field):
- תחת החלק Then the settings are, גללו למטה אל Edge TTL (זמן החיים של הקובץ במטמון הקצה):
- בחרו באפשרות Override origin והגדירו את הזמן ל-
1 month(חודש אחד).
- בחרו באפשרות Override origin והגדירו את הזמן ל-
- לחצו על Deploy בתחתית העמוד כדי להפעיל את החוק באופן מיידי.
פלט נראה לעין שתסיים איתו: כל בקשת תמונה מהאפליקציה שלכם שעוברת דרך הדומיין שלכם ומפנה ל-Supabase תחזיר כותרת HTTP מסוג cf-cache-status: HIT בפעם השנייה שהיא נטענת, מה שמעיד על כך שהתמונה הוגשה ישירות מהמטמון החינמי של Cloudflare ולא צרכה רוחב פס מ-Supabase.
פתחו כרטיסייה חדשה בדפדפן והדביקו את כתובת ה-URL הבאה של תמונה מ-Unsplash (שירות פופולרי המשתמש ב-Edge — רשת שרתים מבוזרת גלובלית הממוקמת קרוב פיזית לגולש כדי לחסוך זמן תגובה — לצורך עיבוד תמונות בזמן אמת):
https://images.unsplash.com/photo-1513542789411-b6a5d4f31634?w=200&q=50
כעת, שנו את הפרמטר w=200 (רוחב ה-Width בפיקסלים) ל-w=800, ואת q=50 (איכות ה-Quality מתוך 100) ל-q=10 ולחצו Enter. שימו לב כיצד שרת ה-Edge מעבד, מכווץ ומגיש לכם את התמונה המותאמת אישית תוך מילישניות בודדות ישירות מהשרת הקרוב ביותר אליכם, מבלי שהייתם צריכים להחזיק שרת יקר או לעבד את התמונה מראש.
במקום להשתמש בתוספים חיצוניים או לגזור ידנית תמונות מהמסך, נצלם אלמנט עיצובי מדויק ישירות מתוך קוד האתר באמצעות כלי המפתחים (DevTools) המובנים של דפדפן Edge - בחינם לגמרי ובאפס מאמץ.
- פתחו את דפדפן Edge וכנסו לכל אתר עם עיצוב שאתם אוהבים.
- לחצו מקש ימני על כפתור, לוגו או תמונה כלשהי בדף, ובחרו ב-בדיקה (Inspect) כדי לפתוח את כלי המפתחים.
- בפאנל הקוד שנפתח, שורת ה-HTML של האלמנט שבחרתם תהיה מסומנת בכחול. לחצו עליה מקש ימני.
- בתפריט שנפתח, לחצו על Capture node screenshot (צילום מסך של רכיב ה-HTML).
התוצאה המיידית: קובץ תמונה בפורמט PNG, חתוך בדיוק לפי גבולות האלמנט ובאיכות מקורית, יורד ישירות לתיקיית ההורדות שלכם.
בתרגיל זה נבנה יישום קצה-אל-קצה (End-to-End) שרץ ישירות בדפדפן, ניגש למצלמת האינטרנט של המשתמש, מציג את הווידאו ומאפשר ללכוד תמונת סטילס (Screenshot) בלחיצת כפתור אחת – ללא שרת ובאפס עלות.
-
שלב ההכנה: התקנת סביבת עבודה מקומית
כדי להריץ את היישום בצורה מאובטחת בדפדפן ולקבל גישה למצלמה (שדורשת סביבה מאובטחת או localhost), נשתמש בכלי פשוט להרצת שרת מקומי בשם
serve.פתחו את מסוף הפקודות (Terminal) והריצו את הפקודה הבאה להתקנת הכלי (נדרש Node.js מותקן על המחשב):
npm install -g serveהפלט הצפוי: הודעה המאשרת כי החבילה הותקנה בהצלחה (למשל:
+ serve@14.2.1). -
יצירת קובץ ה-HTML הראשי
צרו תיקייה חדשה במחשב בשם
edge-media-demoובתוכה צרו קובץ בשםindex.html. העתיקו והדביקו לתוכו את הקוד הבא במלואו:<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>לכידת מדיה בזמן אמת</title> <style> body { font-family: system-ui, sans-serif; background: #f0f2f5; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; } .container { max-width: 800px; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); text-align: center; } video, canvas { width: 100%; max-width: 400px; border-radius: 8px; border: 2px solid #333; margin-top: 10px; } button { background: #0078d4; color: white; border: none; padding: 10px 20px; font-size: 16px; border-radius: 4px; cursor: pointer; margin: 10px; } button:hover { background: #005a9e; } .flex-box { display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; } </style> </head> <body> <div class="container"> <h3>לכידת וידאו ותמונות ב-Edge</h3> <p>לחצו על הכפתור כדי להתחיל את הזרמת הווידאו מהמצלמה, ולאחר מכן לחצו על "צלם מסך".</p> <button id="start-btn">הפעל מצלמה</button> <button id="capture-btn" disabled>צלם מסך</button> <div class="flex-box"> <div> <h4>שידור חי (Live)</h4> <video id="webcam" autoplay playsinline></video> </div> <div> <h4>תמונה שנלכדה (Screenshot)</h4> <canvas id="snapshot"></canvas> </div> </div> </div> <script> const video = document.getElementById('webcam'); const canvas = document.getElementById('snapshot'); const startBtn = document.getElementById('start-btn'); const captureBtn = document.getElementById('capture-btn'); const context = canvas.getContext('2d'); // פונקציה לגישה למצלמה startBtn.addEventListener('click', async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false }); video.srcObject = stream; captureBtn.disabled = false; startBtn.disabled = true; } catch (err) { alert('שגיאה בגישה למצלמה: ' + err.message); } }); // פונקציה ללכידת פריים בודד (Screenshot) captureBtn.addEventListener('click', () => { canvas.width = video.videoWidth; canvas.height = video.videoHeight; context.drawImage(video, 0, 0, canvas.width, canvas.height); }); </script> </body> </html> -
הרצת השרת המקומי
בתוך מסוף הפקודות, ודאו שאתם נמצאים בתיקייה שבה שמרתם את הקובץ, והריצו את הפקודה הבאה:
serve .הפלט הצפוי: הודעה המציגה את הכתובת המקומית להרצה, למשל:
Accepting connections at http://localhost:3000. -
פתיחת האפליקציה ואישור גישה למצלמה
פתחו את דפדפן Edge וגשו לכתובת
http://localhost:3000. לחצו על כפתור "הפעל מצלמה". הדפדפן יציג חלונית קופצת המבקשת אישור גישה למצלמה שלכם.הפלט הצפוי: לאחר אישור הגישה, תוכלו לראות את עצמכם בשידור חי תחת חלונית "שידור חי (Live)", והכפתור "צלם מסך" יהפוך לפעיל.
פלט נראה לעין שתסיים איתו: דף אינטרנט מקומי המציג שני חלונות זה לצד זה: בצד ימין זרם וידאו חי ממצלמת המחשב שלכם, ובצד שמאל תמונת סטילס קפואה המשתנה בכל פעם שאתם לוחצים על הכפתור "צלם מסך" – הכל מבוצע על זיכרון הדפדפן ב-0$ עלויות שרת.
בתרגיל זה נבנה יישום אינטרנט מקומי המשתמש ב-HTML5 Media API (ממשק תכנות יישומים מובנה בדפדפן לקבלת גישה למצלמה ומיקרופון) כדי להציג וידאו חי, לצלם מתוכו תמונה (Screenshot) ולהציג אותה על המסך בזמן אמת – ללא עלות וללא שרת חיצוני.
-
הכנת תיקיית הפרויקט:
פתח את ממשק שורת הפקודה (Terminal במקבוק או Command Prompt בווינדוס) והרצ את הפקודות הבאות כדי ליצור תיקייה חדשה ולנווט אליה:
mkdir edge-media-demo cd edge-media-demoהפלט הצפוי: תיווצר תיקייה חדשה בשם
edge-media-demoומערכת ההפעלה תעביר אתכם לתוך תיקייה זו. -
יצירת קובץ ה-HTML הראשי:
צור קובץ חדש בשם
index.htmlבתוך התיקייה, והעתק לתוכו במלואו את הקוד הבא:<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <title>לוכד מדיה בזמן אמת</title> <style> body { font-family: system-ui, sans-serif; background: #0f172a; color: #f8fafc; text-align: center; padding: 20px; } .container { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; margin-top: 20px; } video, canvas { border: 3px solid #38bdf8; border-radius: 12px; background: #1e293b; max-width: 100%; } button { background: #38bdf8; color: #0f172a; border: none; padding: 12px 24px; font-size: 16px; font-weight: bold; cursor: pointer; border-radius: 8px; margin-top: 15px; transition: 0.2s; } button:hover { background: #0ea5e9; } </style> </head> <body> <h3>לכידת מדיה ווידאו בזמן אמת ב-Edge</h3> <div class="container"> <div> <p>וידאו חי (Real-time Video)</p> <video id="webcam" autoplay playsinline width="400" height="300"></video> </div> <div> <p>צילום מסך שנלכד (Screenshot)</p> <canvas id="screenshotCanvas" width="400" height="300"></canvas> </div> </div> <br> <button id="captureBtn">צלם פריים (Capture)</button> <script> const video = document.getElementById('webcam'); const canvas = document.getElementById('screenshotCanvas'); const button = document.getElementById('captureBtn'); const context = canvas.getContext('2d'); // בקשת גישה למצלמת המשתמש באמצעות ה-API המובנה בדפדפן navigator.mediaDevices.getUserMedia({ video: true, audio: false }) .then((stream) => { video.srcObject = stream; }) .catch((err) => { alert("שגיאה בגישה למצלמה: " + err.message); }); // פונקציית לכידת פריים מהוידאו וציורו על הקנבס button.addEventListener('click', () => { context.drawImage(video, 0, 0, canvas.width, canvas.height); }); </script> </body> </html>הפלט הצפוי: הקובץ
index.htmlיישמר בתיקייה עם קוד המקור המלא מוכן להרצה. -
הרצת שרת מקומי (Local Server):
כדי שמצלמת האינטרנט תעבוד בצורה מאובטחת, עלינו להריץ את הקובץ תחת שרת מקומי ולא בפתיחה ישירה. הרץ בשורת הפקודה:
python -m http.server 8000*(אם מותקן אצלכם פייתון 3 במק, ייתכן שתצטרכו להקליד
python3 -m http.server 8000)*הפלט הצפוי: בשורת הפקודה יופיע כיתוב המציין שהשרת פעיל:
Serving HTTP on 0.0.0.0 port 8000... -
בדיקת האפליקציה בדפדפן:
פתח את דפדפן Microsoft Edge וגלוש לכתובת הבאה:
http://localhost:8000. הדפדפן יבקש ממך אישור גישה למצלמה (Permission prompt) - לחץ על Allow (אפשר).הפלט הצפוי: המצלמה תידלק ותראה את עצמך מופיע בתיבת הוידאו השמאלית בזמן אמת.
פלט נראה לעין שתסיים איתו: לאחר לחיצה על כפתור "צלם פריים (Capture)", הפריים הנוכחי של הוידאו שלכם יוקפא ויועבר מיידית לצד הימני אל תוך אלמנט הקנבס, המהווה צילום מסך מושלם בזמן אמת ב-$0 עלות.
בתרגיל זה נבנה סקריפט קצר ב-Node.js המשתמש בספריית Puppeteer (כלי לשליטה בדפדפנים) כדי לפתוח דפדפן Edge, לטעון סרטון וידאו מבוסס HTML5, לצלם מתוכו פריים (Screenshot) בזמן אמת, ולשמור אותו מקומית בחינם לגמרי.
-
הכנת סביבת העבודה והתקנת חבילות:
פתחו את הטרמינל (Terminal) בתיקייה חדשה והריצו את הפקודות הבאות כדי ליצור פרויקט Node.js חדש ולהתקין את Puppeteer. תהליך ההתקנה יוריד גם גרסה קלה של דפדפן Chromium התואם ל-Edge.
npm init -y npm install puppeteerפלט צפוי בטרמינל: הודעת הצלחה המציגה שחבילת
puppeteerנוספה לקובץpackage.jsonונוצרה תיקייתnode_modules. -
יצירת קובץ ה-HTML עם נגן הוידאו:
צרו קובץ חדש בשם
index.htmlבאותה התיקייה, והדביקו בתוכו את הקוד הבא. קוד זה מציג נגן וידאו פשוט המריץ סרטון מונפש חופשי לשימוש:<!DOCTYPE html> <html lang="he"> <head> <meta charset="UTF-8"> <title>Edge Media Test</title> <style> body { margin: 0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; } video { border: 4px solid #3b82f6; border-radius: 8px; box-shadow: 0 10px 15px rgba(0,0,0,0.5); } </style> </head> <body> <video id="myVideo" width="640" height="360" autoplay muted loop crossorigin="anonymous"> <source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4"> </video> </body> </html>פלט צפוי: קובץ מקומי מוכן להרצה המכיל אלמנט וידאו שמנגן אוטומטית במצב מושתק (Muted) כדי לאפשר ניגון אוטומטי ללא חסימת דפדפן.
-
כתיבת סקריפט האוטומציה והצילום:
צרו קובץ נוסף בשם
capture.jsוהדביקו בתוכו את קוד האוטומציה הבא. הסקריפט יפתח את הדפדפן, יטען את קובץ ה-HTML, ימתין 3 שניות כדי לאפשר לוידאו להתחיל לרוץ, ויבצע צילום מסך מדויק של אלמנט הוידאו בלבד:const puppeteer = require('puppeteer'); const path = require('path'); (async () => { // פתיחת הדפדפן במצב לא נראה (Headless) const browser = await puppeteer.launch({ headless: "new" }); const page = await browser.newPage(); // טעינת קובץ ה-HTML המקומי שיוצר בצעד הקודם const filePath = path.resolve(__dirname, 'index.html'); await page.goto(`file://${filePath}`); console.log('ממתין 3 שניות לניגון הוידאו...'); await new Promise(resolve => setTimeout(resolve, 3000)); // איתור אלמנט הוידאו בדף const videoElement = await page.$('#myVideo'); // ביצוע צילום מסך ממוקד של האלמנט ושמירתו כקובץ PNG await videoElement.screenshot({ path: 'video-frame.png' }); console.log('הצילום בוצע בהצלחה ונשמר כ-video-frame.png!'); await browser.close(); })();פלט צפוי: קוד מוכן להרצה שמבצע אינטגרציה מלאה בין הדפדפן למערכת הקבצים.
-
הרצת הסקריפט והפקת התוצר:
הריצו את הסקריפט מהטרמינל באמצעות הפקודה הבאה:
node capture.jsפלט צפוי בטרמינל:
ממתין 3 שניות לניגון הוידאו...
הצילום בוצע בהצלחה ונשמר כ-video-frame.png!
פלט נראה לעין שתסיים איתו: בתיקיית הפרויקט ייווצר קובץ תמונה חדש בשם video-frame.png. כאשר תפתחו אותו, תראו פריים מדויק מתוך סרטון האנימציה "Big Buck Bunny" כשהוא מוקף במסגרת הכחולה שהגדרנו ב-CSS, ללא שוליים מיותרים מהדפדפן.
למה זה מפתה: כשרוצים להקטין תמונות שהמשתמש מעלה, לייצר צילומי מסך של האתר או לחתוך סרטוני וידאו, האינסטינקט הראשוני הוא להקים שרת Node.js חזק, להתקין עליו חבילות כבדות כמו FFmpeg או Puppeteer, ולשלם עשרות דולרים בחודש על שירותי אחסון ועיבוד בענן.
למה זה טעות: סביבות קצה (Edge) מוגבלות בזמן ריצה ובזיכרון, ואינן יכולות להריץ תוכנות כבדות כאלה ישירות בתוכן. מעבר לכך, הקמת שרתים ייעודיים מייצרת עלויות קבועות, מסבכת את הארכיטקטורה, והורסת את היתרון של ארכיטקטורת Serverless/Edge מהירה וזולה שמגיבה למשתמש ברחבי העולם באפס מילישניות.
מה לעשות במקום: נצלו את כוח העיבוד החינמי של המשתמש בקצה! העבירו את העיבוד לדפדפן (Client-side) באמצעות טכנולוגיות כמו Canvas API לכיווץ תמונות, Web Assembly (WASM) לעריכה קלה, או השתמשו ב-APIs חינמיים לחלוטין של ספקיות ה-Edge (לדוגמה, הטרנספורמציות המובנות של Cloudflare) כדי לשנות גודל, פורמט ואיכות של מדיה בזמן אמת וב-$0 עלויות תשתית.