פתרון בעיות הקשורות לשגיאות ב-Meet Media API ותיקון שלהן

במדריך הזה מוסבר איך לפתור שגיאות נפוצות ב-Google Meet Media API.

פתרון בעיות בקודי שגיאה

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

קודי שגיאה
NO_ACTIVE_CONFERENCE מוודאים שלקוח Meet Media API מנסה להתחבר רק אחרי שהמשתמש המאומת כבר נמצא בשיחה במרחב המשותף.
INVALID_OFFER כדאי לקרוא את הדרישות להצגת מבצעים כדי לבדוק אם חסר פרט כלשהו, כמו ערוצי הנתונים הנדרשים לפתיחת המבצע. אפשר גם להשוות בין מחרוזת המבצע של האפליקציה למבצע לדוגמה ולבדוק אם יש הבדלים.
INCOMPATIBLE_DEVICE מכשיר אחד או יותר בפגישה לא תואם ללקוחות של Meet Media API. האפליקציה לא תוכל להצטרף, לכן כדאי להודיע על כך למשתמשי הקצה.
CONNECTIONS_EXHAUSTED רק לקוח אחד של Meet Media API יכול להתחבר לשיחת ועידה בכל פעם. אם האפליקציה קורסת, יכול להיות שתופיע השגיאה הזו אם היא תנסה להתחבר מחדש. במקרה כזה, צריך לחכות כ-30 שניות עד שפג התוקף של החיבור הקודם ב-Meet. לאחר מכן מנסים שוב.

תוכנית מאוחדת

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

שגיאה בסדר התיאור של המדיה

כשיוצרים חיבור peer-to-peer עם הצעה של Session Description Protocol (‏SDP), עשויה להופיע השגיאה הבאה:

Failed to execute 'setRemoteDescription' on 'RTCPeerConnection':
Failed to set remote answer sdp:
The order of m-lines in answer doesn't match order in offer. Rejecting answer.

כלומר, שורות תיאור המדיה בתשובה ל-SDP לא תואמות לתיאור המדיה בהצעת ה-SDP:

הצעת SDP תשובה ל-SDP
m=audio 9 UDP/TLS/RTP/SAVPF 111 m=audio 9 UDP/TLS/RTP/SAVPF 111
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 m=audio 9 UDP/TLS/RTP/SAVPF 111
m=audio 9 UDP/TLS/RTP/SAVPF 111 m=audio 9 UDP/TLS/RTP/SAVPF 111
m=audio 9 UDP/TLS/RTP/SAVPF 111 m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99

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

דוגמת הקוד הבאה מראה איך להתאים בצורה נכונה את תיאורי המדיה:

C++‎

rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection;

// Signal the entire video at once.
for (uint32_t i = 0; i < configurations.receiving_video_stream_count; ++i) {
    webrtc::RtpTransceiverInit video_init;
    video_init.direction = webrtc::RtpTransceiverDirection::kRecvOnly;
    video_init.stream_ids = {absl::StrCat("video_stream_", i)};

    webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
        video_result = peer_connection->AddTransceiver(
            cricket::MediaType::MEDIA_TYPE_VIDEO, video_init);
  // . . .
}

JavaScript

pc = new RTCPeerConnection();

// Signal the entire video at once.
pc.addTransceiver(video, {'direction':'recvonly'});
pc.addTransceiver(video, {'direction':'recvonly'});
pc.addTransceiver(video, {'direction':'recvonly'});

שגיאה במאפיין התפקיד של DTLS

כשמגדירים את מאפיין התפקיד של DTLS, עשויה להופיע השגיאה הבאה:

All DTLS roles must be one of [ACTIVE, ACTPASS].

השגיאה הזו מתרחשת כשהמאפיין a=setup:< > לא מוגדר כראוי לכל תיאורי המדיה בהצעת ה-SDP.

כדי לתקן את השגיאה, צריך לוודא שלכל תיאור מדיה בהצעת ה-SDP יש אחד מהמאפיינים הנדרשים הבאים:

  • a=setup:actpass
  • a=setup:active
v=0
o=- 4743178474630771513 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101
. . .
a=setup:actpass
. . .
m=audio 39807 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=setup:actpass
. . .

פתרון בעיות שמע

בקטעים הבאים מוסבר איך לפתור בעיות אודיו באפליקציה.

בדיקת היומנים

אם אתם משתמשים בלקוח האינטרנט בדפדפן Chrome:

  1. פותחים כרטיסייה חדשה ומזינים בסרגל הכתובות: chrome://webrtc-internals.
  2. עוברים לקטע Stats graph for inbound-rtp.
  3. בודקים כל תרשים אודיו כדי לראות אם חבילות מתקבלות.

אם אתם משתמשים בלקוח העזרה של C++‎, בודקים אם OnAudioFrame נקרא אי פעם.

אימות היקפי ההרשאות של OAuth

האודיו מועבר רק אם היקף הרשאה מתאים מסופק בבקשת החיבור הראשונית. כדי לפתור את השגיאה, צריך לספק את ההיקפים הנכונים של OAuth 2.0. מידע נוסף זמין במאמר היקפי הרשאה של Meet Media API.

מוודאים שהועידה מוגדרת בצורה נכונה

  • כשהלקוח מתחבר לשרתי Google Meet, הוא לא מקבל אישור אוטומטי להצטרף לכנס. מוודאים שקיבלתם עדכון של משאב לבקרת סשן דרך ערוץ הנתונים לבקרת הסשן עם המצב STATE_JOINED.

    {"sessionStatus":{"connectionState":"STATE_JOINED"}}
    
  • מוודאים שמשתתפים אחרים בשיחת הצ'אט לא מושתקים.

אימות האות של האודיו

ב-Meet יתבצע שידור אודיו רק אם תציינו זאת בהצעה ל-SDP. המבצע צריך לכלול שלושה תיאורים של מדיה אודיו לקבלה בלבד.

m=audio 39807 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:0
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:1
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:2
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .

אם השרתים של Meet מקבלים הצעה תקפה, הם משיבים בתשובה SDP עם שלושה תיאורי מדיה של אודיו לצורך שליחה בלבד.

m=audio 19306 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:0
. . .
a=sendonly
a=msid:virtual-6666 virtual-6666
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:1
. . .
a=sendonly
a=msid:virtual-6667 virtual-6667
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:2
. . .
a=sendonly
a=msid:virtual-6668 virtual-6668
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .

בדיקת ההטמעה של משתמשי הצפייה

אם מעבירים את עיבוד הנתונים לשרשור אחר, חשוב ליצור עותקים של נתוני האודיו. למעשה, AudioFrame.pcm16 הוא הפניה לנתונים הבסיסיים, ולכן ניסיון לגשת אליו אחרי OnAudioFrame גורם להתנהגות לא מוגדרת, כמו שגיאת חלוקה.

פתרון בעיות בסרטונים

בקטעים הבאים מוסבר איך לפתור בעיות שקשורות לסרטונים באפליקציה.

בדיקת היומנים

אם אתם משתמשים בלקוח האינטרנט בדפדפן Chrome:

  1. פותחים כרטיסייה חדשה ומזינים בסרגל הכתובות: chrome://webrtc-internals.
  2. עוברים לקטע Stats graph for inbound-rtp.
  3. בודקים כל תרשים של סרטון כדי לראות אם חבילות מתקבלות.

אם אתם משתמשים בלקוח העזרה של C++‎, בודקים אם OnVideoFrame נקרא אי פעם.

אימות היקפי ההרשאות של OAuth

הסרטון מועבר רק אם היקף הבקשה הראשונית להתחברות הוא היקף מתאים. כדי לפתור את השגיאה, צריך לספק את ההיקפים הנכונים של OAuth 2.0. מידע נוסף זמין במאמר היקפי הרשאה של Meet Media API.

מוודאים שהועידה מוגדרת בצורה נכונה

  • כשהלקוח מתחבר לשרתים של Meet, הוא לא מקבל אישור אוטומטי להצטרף לכנס. מוודאים שקיבלתם עדכון של משאב לבקרת סשן דרך ערוץ הנתונים לבקרת הסשן, עם המצב STATE_JOINED.

    {"sessionStatus":{"connectionState":"STATE_JOINED"}}
    
  • מוודאים שמשתתפים אחרים בפגישה לא מושתקים.

אימות האות של שיחת הווידאו

ב-Meet, הווידאו מוצג רק אם הוא מצוין בהצעה של SDP. בהצעה צריכים להיות עד שלושה תיאורים של מדיה מסוג וידאו לקבלה בלבד.

v=0
o=- 4743178474630771513 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 35 36 37 38 102 103 104 105 106 107 108 109 127 125 39 40 41 42 43 44 45 46 47 48 112 113 114 115 116 117 118 49
. . .
a=setup:actpass
a=mid:1
. . .
a=recvonly
. . .
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
. . .

אם ב-Meet מתקבלת הצעה תקפה, הוא משיב בתשובה SDP עם n תיאורי מדיה של וידאו לשלוח בלבד, כאשר n הוא מספר תיאורי המדיה של וידאו בהצעת ה-SDP.

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS virtual-video-7777/7777
a=ice-lite
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99
. . .
a=setup:passive
a=mid:1
. . .
a=msid:virtual-video-7777/7777 virtual-video-7777/7777
a=rtcp-mux
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
. . .

פתרון בעיות שקשורות לכך שאין וידאו

  • בודקים אם הערך m=video … קיים בהצעת ה-SDP שנשלחת לשרתים של Meet.
  • בודקים ש-a=recvonly הוא מאפיין בכל שורה של m=video.
  • בודקים שיש מספר שווה של שורות m=video בתשובה ל-SDP.
  • בודקים ש-a=sendonly או a=sendrecv הם מאפיינים שמופיעים מתחת לכל שורה של m=video בתשובה ל-SDP.
  • בודקים ש-VideoAssignmentRequest נשלחה בהצלחה לשרתים של Meet ונקלטה בהם. צריך להודיע ללקוח על הצלחה או כישלון דרך אותו ערוץ נתונים.

פתרון בעיות שקשורות למספר נמוך מהצפוי של סטרימינג של וידאו

  • בודקים שהצעת ה-SDP מכילה את המספר הנכון של שורות m=video ….
  • חשוב לוודא שכל התיאורים של m=video בתשובה ל-SDP מכילים מאפיין a=sendonly או a=sendrecv. כל שורה שמסומנת ב-a=recvonly בתשובה מפחיתה באותה כמות את מספר הסטרימינג שנשלחים ללקוח.

בדיקת ההטמעה של משתמשי הצפייה

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