אינטרנט ישראל
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
ראשי » מדריכים » HTML 5 » שימוש ב-getUserMedia לקבל וידאו ואודיו מהמשתמשים

שימוש ב-getUserMedia לקבל וידאו ואודיו מהמשתמשים

רן בר-זיק אפריל 16, 2017 7:07 am 5 תגובות

הסבר מקיף על ה-API שמאפשר לנו להתחבר לקבל אודיו ו-וידאו מהמשתמש בצד לקוח עם ג'אווהסקריפט

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.

אחד מה-API המעניינים יותר בשנים האחרונות בתקן HTML 5 הוא getUserMedia שמאפשר לנו גישה נוחה וקלה באמצעות ג'אווהסקריפט למצלמת הוידאו של המשתמש ולמיקרופון שלו. היום כמעט לכל מחשב יש מצלמת וידאו (כל לפטופ, טלפון או טאבלט) ולאף יותר יש מיקרופון. באמצעות WebRTC API אנחנו יכולים לצלם או להקליט את המשתמש לצרכים שונים. למשל לשיחות וידאו/קול, לקחת צילום של תמונת פרופיל או סרטונים וכל שימוש שהוא. לא צריך נייטיב (נייטיב זה בעצם תוכנה שיושבת על מערכת ההפעלה ללא תיווך דפדפן). במאמר הזה אני אסביר על getUserMedia ואיך משתמשים בו ללכידת אודיו ו-וידאו. נכון להיום,getUserMedia נתמך בפיירפוקס, כרום ואדג'. כרום לא מאפשר שימוש ב-getUserMedia באתרים שאינם https או localhost.

הדוגמאות נכתבו בתקן ES6 ונדרשת הבנה ב-promises, פונקציות חץ וקלאסים.

אז בואו ונתחיל דווקא בדוגמה חיה. הכנסו אל הדף הזה עם דפדפן כרום או פיירפוקס (במובייל או בדסקטופ אבל כדאי עם מכשיר שיש בו מצלמה), אל תשכחו לאשר את הרשאות האודיו והוידאו שמאפשרות את זה. אם אתם גולשים בדסקטופ בלי מובייל, השתמשו ב-QR code הזה על מנת לגשת לדף.

https://internet-israel.com/internet_files/webrtc/another_example/

הכפתור הזה מבקש הרשאות להתקן הוידאו והאודיו שלכם. במידה וההרשאות לא יתקבלו, ההתקן לא יוכל לעבוד. אם הכל עובד כמו שצריך, אתם תוכלו לראות את עצמכם במצלמה. להקליט, לעצור את ההקלטה. לנגן אותה שוב ואף להוריד את ההקלטה.

See the Pen WebRTC sample by Ran Bar-Zik (@barzik) on CodePen.

איך זה עובד? הקוד שמאפשר לנו לעשות את זה הוא קצת יותר ממאה שורות בג'אווהסקריפט שרובו הוא ניהול הכפתורים. בגדול, הקסם מתחיל מפה:


    const constraints = {
      audio: true,
      video: true
    };

    // Get user permission,
    navigator.mediaDevices.getUserMedia(constraints).
      then((stream) => {
        this.handleSuccess(stream);
      }).
      catch((error) => {
        this.handleError(error);
      });

ראשית אני מגדיר אובייקט שבו יש את ההרשאות שאני מבקש. את האובייקט הזה אני מעביר דרך האובייקט הגלובלי navigator. באובייקט זה, שכאמור הוא זמין בכל דפדפן, יש את mediaDevices ולו יש את תכונת getUserMedia שאליה אני מעביר את ההרשאות. התכונה הזו מחזירה promise שהוא בעצם מתקיים אך ורק אם המשתמש אישר את הבקשה ורק אם יש ציוד קצה שמתאים. הבקשה מתמלאת ומעבירה לי את ה-stream. משתנה ג'אווהסקריפטי שמייצג את זרם הנתונים מהמצלמה. מה אני יכול לעשות עם זה? בת'כלס כל מה שמתחשק לי. אבל השימוש הראשוני הוא להכניס אותו ישירות לתוך אלמנט וידאו כדי שהמשתמש יוכל לראות את עצמו. איך אני עושה את זה? בפונקציה הראשונה, שמתממשת אם המשתמש אישר את ההרשאות והכל תקין, אני לוקח את ה-stream ומעביר אותו איך שהוא לאלמנט וידאו כ-src. ממש ככה:


  handleSuccess(stream) {
    this.video.srcObject = stream;
  }

this.video הוא אלמנט פשוט שאפשר להשיג אותו עם סלקטור פשוט כמו getElementById או כל אחד אחר. srcObject זהה למדי ל-src. זה הכל. בשניה שעשיתי את זה המשתמש יכול לראות את עצמו באלמנט הוידאו.

דוגמה עם חצים הממחישים ויזואלית את מה שאני כותב. ברגע שהמשתמש מאשר את הבקשה יש לי גישה ל-stream של התקן המדיה ואני יכול לעשות איתו מה שאני רוצה.
דוגמה עם חצים הממחישים ויזואלית את מה שאני כותב. ברגע שהמשתמש מאשר את הבקשה יש לי גישה ל-stream של התקן המדיה ואני יכול לעשות איתו מה שאני רוצה.

אם אתם רוצים לראות, אז הנה הקישור לדוגמה הפשוטה.

https://internet-israel.com/internet_files/webrtc/simple_example/
https://internet-israel.com/internet_files/webrtc/simple_example/

הנה הקוד המלא:


'use strict';
class Recorder {
  constructor() {
    // Defining all globals.
    this.video = document.querySelector('video');
    // Get user permission,
    const constraints = {
      audio: false,
      video: true
    };
    navigator.mediaDevices.getUserMedia(constraints).
      then((stream) => {
        this.handleSuccess(stream);
      }).
      catch((error) => {
        this.handleError(error);
      });
  }


  /**
   * When user granting success, this function is firing. 
   * @param {*} stream of video
   */
  handleSuccess(stream) {
    this.video.srcObject = stream;
  }
  /**
   * If user is not granting success, this function is firing.
   * @param {*} error 
   */
  handleError(error) {
    console.log('navigator.getUserMedia error: ', error);
  }

}


new Recorder(); // Init class constructor.

תראו כמה זה קל! כל מה שצריך זה לקרוא ל-navigator.mediaDevices.getUserMedia ולהבין מספיק ב-promises כדי לדעת מה עושים עם הפלט. הפלט הןא stream ואפשר לעשות איתו מה שרוצים. במקרה הזה זה פשוט, אבל אני יכול לקחת את ה-stream הזה ולאגור אותו. איך אני עושה את זה? באמצעות שימוש באובייקט mediaRecorder שמאפשר לי להקליט stream. ראשית אני צריך לאתחל אותו. איך? ככה:


let options = { mimeType: 'video/webm;codecs=vp9' };
mediaRecorder = new MediaRecorder(window.stream, options);

אני מעביר לו את ה-stream עצמו. שניתן להציב אותו בפונקציה handleSuccess ב-window.stream על מנת שיהיה גלובלי. אני גם מעביר לו את הקידוד שאני רוצה לשמור בו את המדיה. עכשיו אני יוצר event listener שירוץ בכל פעם שהמאגר של ה-MediaRecorder יתמלא. אני מתחיל את ההקלטה באמצעות mediaRecorder.start(10) כאשר הארגומנט (שבמקרה הזה הוא 10) הוא מספר המילישניות שיש במאגר. על מנת להפסיק להקליט אני צריך ללחוץ על this.mediaRecorder.stop();


mediaRecorder.ondataavailable = this.handleDataAvailable;
    mediaRecorder.start(10); // collect 10ms of data

השלב האחרון הוא הקולבק של ondataavailable. כלומר הפונקציה handleDataAvailable שמופעלת בכל פעם שאני מקבל מידע.


handleDataAvailable(event) {
    if (event.data && event.data.size > 0) {
      this.recordedBlobs.push(event.data);
    }
  }

הפונקציה הזו פשוט שומרת את המידע במערך גלובלי של recordedBlobs. זה הכל. ומכאן? מכאן אני יכול לעשות מה שאני רוצה עם recordedBlobs. אני יכול לשלוח אותו לשרת ואני יכול לשים אותו באלמנט וידאו אחר. כמו בדוגמה הראשונה. הקוד בדוגמה הראשונה זמין גם ב-codepen וגם באתר ואתם יותר ממוזמנים לבחון אותו. כתבתי הערות היכן שצריך. על מנת להמחיש את התהליך, הנה דוגמה:
הסבר באמצעות דיאגרמת זרימה על התהליך שהסברתי בטקסט

ברגע שמבינים ש-stream הוא בעצם נתון כמו כל נתון ושאפשר להשתמש בו או כמקור מידע לאלמנט HTML של וידאו או כמקור מידע ל-MediaRecorder שיכול להקליט את המידע ולשדר אותו לכל מקום אחר (או אלמנט וידאו אחר או לשרת שיכול להעביר אותו לכל מקום אחר). אז זה פשוט.

כיוון שהקלטה של משתמשים היא בעייתית מאוד מבחינה חוקית, הדפדפנים מבצעים כמה פעילויות על מנת להגן על המשתמשים שלהם. הפעילות הראשונה היא לבקש, בפעם הראשונה שהדף עולה, הרשאה ספציפית מהמשתמש לשימוש בהתקני המדיה שלו: מיקרופון ו/או מצלמה (תלוי מה ביקשתם). הבקשה הזו היא חד פעמית. נגעתם? נסעתם. לא צריך לבקש שוב. שכבת ההגנה השניה היא אינדקיציה גרפית על הלשונית. הנה האינדקיציה ששלושת הדפדפנים המרכזיים נותנים בדסקטופ:

התרעה על שימוש בהקלטה (וידאו או אודיו) בדפדפנים שונים

ההגנה האחרונה היא של מערכת ההפעלה שמדליקה נורית קטנה ליד המצלמה במידה והיא מופעלת. אני מאמין שכל המתכנתים שמבקרים באתר הזה ולומדים ממנו ישתמשו בידע הזה באופן אתי ולא ינסו לצלם אותי רוקד בתחתונים ליד המחשב 🙂

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.
»Web Sockets
»אלמנט meter שמציג מדדים עם HTML 5
HTML 5 וידאו באתר אינטרנט

5 תגובות

  1. אבי הגב אפריל 16, 2017 בשעה 11:32 am

    תודה רבה!
    כיף שאתה משקיע וכותב בעברית!
    חג שמח!

  2. משתמש אנונימי (לא מזוהה) הגב אפריל 16, 2017 בשעה 2:42 pm

    לא עובד בכרום IOS

  3. משתמש אנונימי (לא מזוהה) הגב אפריל 22, 2017 בשעה 12:04 am

    מושקע,כל הכבוד.

  4. ישראל הגב אפריל 23, 2017 בשעה 4:17 pm

    האם ניתן להשתמש בזה לוידאו צט?

    • רן בר-זיק הגב מאי 3, 2017 בשעה 6:29 am

      זו המטרה המוצהרת שלו וגוגל עושים את זה עם google hangouts.

השארת תגובה

ביטול

ללמוד ג'אווהסקריפט בעברית

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-2000 תומכים - בואו ללמוד עכשיו איך לתכנת.

רשימת הנושאים
  • מדריכים
    • ריאקט
    • טייפסקריפט
    • ECMAScript 6
    • ES20XX
    • Node.js
    • Express
    • רספברי פיי
    • Babel
    • docker
    • MongoDB
    • Git
    • לימוד MySQL
    • SASS
    • jQuery
    • CSS3
    • HTML 5
    • SVN
    • LESS
  • פיתוח אינטרנט
    • פתרונות ומאמרים על פיתוח אינטרנט
    • jQuery Scripts
    • jQuery למתקדמים
    • יסודות בתכנות
    • נגישות אינטרנט
  • חדשות אינטרנט
  • מידע כללי על אינטרנט
    • רשת האינטרנט
    • בניית אתרי אינטרנט
  • rss logo

    לכל המאמרים

    לכל המאמרים שפורסמו באינטרנט ישראל משנת 2008 ועד עכשיו.
  • rss logo

    RSS Feed

    משתמשים בקורא RSS? אם כן, עקבו אחרי אינטרנט ישראל באמצעות פיד ה-RSS!
    מה זה RSS?
  • Twitter logo

    עקבו אחרי בטוויטר

    בחשבון הטוויטר שלי אני מפרסם עדכונים מהירים על חדשות בתחום התכנות והיזמות, התרעות על מצבי חירום ורכילות בוערת על תחום הווב.
    מה זה טוויטר?
  • facebook like image

    ערוץ הטלגרם של אינטרנט ישראל

    בערוץ הטלגרם של אינטרנט ישראל אני מפרסם את הפוסטים של באתר וכן עדכונים טכנולוגיים נוספים.
    מה זה טלגרם?
  • github logo

    הפרויקטים שלי בגיטהאב

    הפרויקטים שאני כותב ושוחררו לציבור ברישיון קוד פתוח נמצאים ברובם בגיטהאב.
חיפוש

כל הזכויות שמורות לרן בר-זיק ולאינטרנט ישראל | מדיניות הפרטיות של אתר אינטרנט ישראל | אתר אינטרנט ישראל נגיש לפי תקן WCAG 2.0 AA | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

גלילה לראש העמוד