- תיקון שגיאות מסוג "אסור להשתמש בתנועת HTTP לא מוצפנת"
- תיקון השגיאות "SSLHandshakeException", "CertPathValidatorException" ו-"ERR_CERT_AUTHORITY_INVALID"
- למה אי אפשר לחפש בחלק מקובצי המדיה?
- למה החיפוש לא מדויק בחלק מקובצי ה-MP3?
- למה הדילוג בסרטון שלי איטי?
- למה חלק מקובצי MPEG-TS לא פועלים?
- למה לא נמצאו כתוביות בחלק מקובצי MPEG-TS?
- למה קובצי MP4/FMP4 מסוימים לא פועלים כמו שצריך?
- למה חלק מהשידורים נכשלים עם קוד תגובת HTTP 301 או 302?
- למה חלק מהסטרימינג נכשל עם UnrecognizedInputFormatException?
- למה setPlaybackParameters לא פועל כמו שצריך במכשירים מסוימים?
- מה המשמעות של השגיאות "הגישה לנגן מתבצעת בשרשור הלא נכון"?
- איך אפשר לתקן את השגיאה "Unexpected status line: ICY 200 OK"?
- איך אפשר לבדוק אם השידור שמופעל הוא שידור חי?
- איך אפשר להמשיך להפעיל אודיו כשהאפליקציה פועלת ברקע?
- למה ExoPlayer תומך בתוכן שלי אבל ספריית ExoPlayer Cast לא?
- למה התוכן לא מופעל, אבל לא מוצגת שגיאה?
- איך אפשר לטעון ספריית פענוח ולהשתמש בה להפעלה?
- אפשר להפעיל סרטונים ב-YouTube ישירות באמצעות ExoPlayer?
- הפעלת הסרטון מקוטעת
- שגיאות lint ב-API לא יציב
- איך אפשר לבדוק או לבודד בעיות שנגרמו כתוצאה מתכונות או מאופטימיזציות חדשות?
תיקון שגיאות מסוג "אסור להשתמש בתנועת HTTP לא מוצפנת"
השגיאה הזו תופיע אם האפליקציה תבקש תנועת HTTP לא מוצפנת (כלומר, http:// במקום https://) כשהתצורה של אבטחת הרשת לא מאפשרת זאת. אם האפליקציה מטרגטת ל-Android 9 (רמת API 28) ומעלה, תנועת HTTP בטקסט לא מוצפן מושבתת בהגדרת ברירת המחדל.
אם האפליקציה צריכה לעבוד עם תנועת HTTP בטקסט לא מוצפן, צריך להשתמש בתצורה של אבטחת רשת שמאפשרת את זה. פרטים נוספים זמינים במסמכי התיעוד בנושא אבטחת רשת של Android. כדי לאפשר את כל תעבורת ה-HTTP בטקסט לא מוצפן, אפשר פשוט להוסיף את android:usesCleartextTraffic="true" לרכיב application בקובץ AndroidManifest.xml של האפליקציה.
אפליקציית ההדגמה של ExoPlayer משתמשת בתצורה של אבטחת רשת שמוגדרת כברירת מחדל, ולכן היא לא מאפשרת תנועת HTTP לא מוצפנת. אפשר להפעיל אותו לפי ההוראות שלמעלה.
תיקון השגיאות SSLHandshakeException, CertPathValidatorException ו-ERR_CERT_AUTHORITY_INVALID
השגיאות SSLHandshakeException, CertPathValidatorException ו-ERR_CERT_AUTHORITY_INVALID מצביעות על בעיה באישור ה-SSL של השרת. השגיאות האלה לא ספציפיות ל-ExoPlayer. פרטים נוספים זמינים במסמכי התיעוד של Android בנושא SSL.
למה אי אפשר לדלג על חלק מקובצי המדיה?
כברירת מחדל, ExoPlayer לא תומך בדילוג במדיה שבה השיטה היחידה לביצוע פעולות דילוג מדויקות היא שהנגן יסרוק את כל הקובץ ויוסיף אותו לאינדקס. ExoPlayer מתייחס לקבצים כאלה כקבצים שלא ניתן לדלג בהם. רוב הפורמטים המודרניים של מאגרי מדיה כוללים מטא-נתונים לחיפוש (כמו אינדקס דגימה), יש להם אלגוריתם חיפוש מוגדר היטב (לדוגמה, חיפוש חצייה עם אינטרפולציה ל-Ogg), או שהם מציינים שהתוכן שלהם הוא קצב העברת נתונים קבוע. במקרים כאלה, אפשר לבצע פעולות חיפוש יעילות שנתמכות על ידי ExoPlayer.
אם אתם צריכים להריץ קדימה או אחורה אבל המדיה לא מאפשרת את זה, מומלץ להמיר את התוכן לפורמט קובץ מתאים יותר. בקובצי MP3, ADTS ו-AMR, אפשר גם להפעיל חיפוש בהנחה שלקבצים יש קצב העברת נתונים קבוע, כמו שמתואר כאן.
למה החיפוש לא מדויק בחלק מקובצי ה-MP3?
קובצי MP3 עם קצב העברת נתונים משתנה (VBR) לא מתאימים לתרחישי שימוש שדורשים חיפוש מדויק. יש לכך שתי סיבות:
- כדי לדלג לנקודה מדויקת, פורמט של מאגר צריך לספק מיפוי מדויק של זמן-לבייט בכותרת. המיפוי הזה מאפשר לנגן למפות את זמן החיפוש המבוקש להיסט הבייטים המתאים, ולהתחיל לבקש, לנתח ולהפעיל מדיה מההיסט הזה. לצערנו, הכותרות שזמינות לציון המיפוי הזה ב-MP3 (כמו כותרות XING) הן בדרך כלל לא מדויקות.
- בפורמטים של קונטיינרים שלא מספקים מיפוי מדויק של זמן לבייטים (או מיפוי כלשהו של זמן לבייטים), עדיין אפשר לבצע חיפוש מדויק אם הקונטיינר כולל חותמות זמן מוחלטות של דגימות בסטרימינג. במקרה כזה, הנגן יכול למפות את זמן החיפוש לניחוש הכי טוב של היסט הבייטים התואם, להתחיל לבקש מדיה מההיסט הזה, לנתח את חותמת הזמן המוחלטת הראשונה של הדגימה, ולבצע חיפוש בינארי מונחה במדיה עד שהוא מוצא את הדגימה הנכונה. לצערנו, קובצי MP3 לא כוללים חותמות זמן מוחלטות של דגימות בסטרימינג, ולכן הגישה הזו לא אפשרית.
לכן, הדרך היחידה לבצע חיפוש מדויק בקובץ MP3 עם VBR היא לסרוק את כל הקובץ וליצור באופן ידני מיפוי של זמן לבייטים בנגן. כדי להפעיל את האסטרטגיה הזו, משתמשים ב-FLAG_ENABLE_INDEX_SEEKING, שאפשר להגדיר ב-DefaultExtractorsFactory באמצעות setMp3ExtractorFlags. חשוב לדעת שהשיטה הזו לא מתאימה לקובצי MP3 גדולים, במיוחד אם המשתמש מנסה לדלג קדימה קרוב לסוף הסטרימינג זמן קצר אחרי תחילת ההפעלה. במקרה כזה, הנגן צריך להמתין עד להורדה וליצירת אינדקס של כל הסטרימינג לפני ביצוע הדילוג. ב-ExoPlayer, החלטנו לבצע אופטימיזציה למהירות על פני דיוק במקרה הזה, ולכן FLAG_ENABLE_INDEX_SEEKING מושבת כברירת מחדל.
אם אתם שולטים במדיה שאתם מפעילים, מומלץ מאוד להשתמש בפורמט קונטיינר מתאים יותר, כמו MP4. אנחנו לא מכירים תרחישים שבהם MP3 הוא הפורמט הכי טוב.
למה הדילוג בסרטון שלי איטי?
כשהנגן מחפש מיקום חדש להפעלה בסרטון, הוא צריך לבצע שתי פעולות:
- טוענים למאגר הנתונים הזמני את הנתונים שמתאימים למיקום החדש של ההפעלה (יכול להיות שזה לא יהיה נחוץ אם הנתונים האלה כבר נשמרו במאגר הנתונים הזמני).
- מנקים את מפענח הווידאו ומתחילים לפענח מה-I-frame (פריים מפתח) לפני מיקום ההפעלה החדש, בגלל הקידוד בתוך הפריים שמשמש את רוב הפורמטים של דחיסת וידאו. כדי לוודא שהחיפוש מדויק (כלומר, ההפעלה מתחילה בדיוק במיקום החיפוש), צריך לפענח את כל הפריימים בין ה-I-frame הקודם לבין מיקום החיפוש, ולהשליך אותם מיד (בלי להציג אותם במסך).
כדי לצמצם את זמן האחזור שנוצר בגלל (1), אפשר להגדיל את כמות הנתונים שמאוחסנים במאגר הנתונים הזמני בזיכרון של הנגן, או לשמור מראש את הנתונים במטמון בדיסק.
כדי לצמצם את זמן האחזור שנוצר בגלל (2), אפשר להפחית את הדיוק של החיפוש באמצעות ExoPlayer.setSeekParameters, או לקודד מחדש את הסרטון כך שיהיו בו יותר פריימים מסוג I (מה שיגרום לקובץ פלט גדול יותר).
למה קובצי MPEG-TS מסוימים לא פועלים?
חלק מקובצי MPEG-TS לא מכילים תוחמי יחידות גישה (AUD). כברירת מחדל, ExoPlayer מסתמך על AUD כדי לזהות גבולות של פריימים בצורה זולה. באופן דומה, קובצי MPEG-TS מסוימים לא מכילים פריימים מרכזיים של IDR. כברירת מחדל, אלה הסוגים היחידים של פריימים מרכזיים ש-ExoPlayer מתייחס אליהם.
נראה ש-ExoPlayer תקוע במצב אגירה כשמבקשים ממנו להפעיל קובץ MPEG-TS שחסרים בו AUDs או פריימים מרכזיים של IDR. אם אתם צריכים להפעיל קבצים כאלה, אתם יכולים לעשות את זה באמצעות FLAG_DETECT_ACCESS_UNITS ו-FLAG_ALLOW_NON_IDR_KEYFRAMES בהתאמה. אפשר להגדיר את הדגלים האלה ב-
DefaultExtractorsFactory באמצעות setTsExtractorFlags או ב-
DefaultHlsExtractorFactory באמצעות ה-
constructor.
לשימוש ב-FLAG_DETECT_ACCESS_UNITS אין תופעות לוואי, מלבד העובדה שהוא דורש משאבי מחשוב רבים יותר בהשוואה לזיהוי גבולות של פריימים שמבוסס על AUD. השימוש ב-FLAG_ALLOW_NON_IDR_KEYFRAMES עלול לגרום לפגיעה זמנית באיכות התצוגה בתחילת ההפעלה ומיד אחרי חיפושים במהלך הפעלה של קובצי MPEG-TS מסוימים.
למה לא נמצאו כתוביות בחלק מקובצי MPEG-TS?
חלק מקובצי MPEG-TS כוללים טראקים של CEA-608 אבל לא מצהירים עליהם במטא-נתונים של מאגר התגים, ולכן ExoPlayer לא יכול לזהות אותם. אפשר לציין באופן ידני טראקים של כתוביות על ידי הוספת רשימה של פורמטים צפויים של כתוביות ל-DefaultExtractorsFactory, כולל ערוצי הנגישות שבהם אפשר להשתמש כדי לזהות אותם בסטרימינג של MPEG-TS:
Kotlin
val extractorsFactory = DefaultExtractorsFactory() .setTsSubtitleFormats( listOf( Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build() ) ) val player: Player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()
Java
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setTsSubtitleFormats( ImmutableList.of( new Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build())); Player player = new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
למה קובצי MP4 או FMP4 מסוימים לא מופעלים כמו שצריך?
חלק מקובצי MP4/FMP4 מכילים רשימות עריכה שמשכתבות את ציר הזמן של המדיה על ידי דילוג על רשימות של דגימות, העברה שלהן או חזרה עליהן. ל-ExoPlayer יש תמיכה חלקית בהחלת רשימות עריכה. לדוגמה, הוא יכול לעכב או לחזור על קבוצות של דגימות שמתחילות בדגימת סנכרון, אבל הוא לא חותך דגימות אודיו או מדיה של טרום-סרטון בעריכות שלא מתחילות בדגימת סנכרון.
אם אתם רואים שחלק מהמדיה חסר או חוזר על עצמו באופן בלתי צפוי, נסו להגדיר את Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS או את FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, כדי שהמחלץ יתעלם לחלוטין מרשימות העריכה. אפשר להגדיר אותם ב-DefaultExtractorsFactory באמצעות setMp4ExtractorFlags או setFragmentedMp4ExtractorFlags.
למה חלק מהשידורים נכשלים עם קוד תגובת HTTP 301 או 302?
קודי תגובת HTTP 301 ו-302 מציינים הפניה לכתובת URL אחרת. אפשר למצוא תיאורים קצרים בויקיפדיה. כש-ExoPlayer שולח בקשה ומקבל תגובה עם קוד סטטוס 301 או 302, בדרך כלל הוא יפעל לפי ההפניה האוטומטית ויתחיל את ההפעלה כרגיל. המקרה היחיד שבו זה לא קורה כברירת מחדל הוא בהפניות אוטומטיות בין פרוטוקולים. הפניה אוטומטית בין פרוטוקולים היא הפניה אוטומטית מ-HTTPS ל-HTTP או להיפך (או, במקרים פחות נפוצים, בין זוג אחר של פרוטוקולים). כדי לבדוק אם כתובת URL גורמת להפניה אוטומטית בין פרוטוקולים, אפשר להשתמש בכלי שורת הפקודה wget באופן הבא:
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
הפלט אמור להיראות בערך כך:
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
בדוגמה הזו יש שתי הפניות אוטומטיות. ההפניה האוטומטית הראשונה היא מ-https://yourserver.example.com/test.mp3 אל https://secondserver.example.net/test.mp3. שניהם מסוג HTTPS, ולכן זו לא הפניה אוטומטית בין פרוטוקולים. ההפניה האוטומטית השנייה היא מ-https://secondserver.example.net/test.mp3 אל http://thirdserver.example.org/test.mp3. ההפניה הזו היא מ-HTTPS ל-HTTP, ולכן היא הפניה אוטומטית בין פרוטוקולים. ExoPlayer לא יבצע את ההפניה האוטומטית הזו בהגדרת ברירת המחדל שלו, כלומר ההפעלה תיכשל.
אם צריך, אפשר להגדיר את ExoPlayer כך שיעקוב אחרי הפניות אוטומטיות בין פרוטוקולים כשיוצרים מופעים של DefaultHttpDataSource.Factory שמשמשים באפליקציה. מידע ולמידה על בחירה והגדרה של מקבץ הרשת כאן.
למה חלק מהשידורים נכשלים עם השגיאה UnrecognizedInputFormatException?
השאלה הזו מתייחסת לכשלים בהפעלה מהסוג הבא:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
יש שתי סיבות אפשריות לכשל הזה. הסיבה הנפוצה ביותר היא שאתם מנסים להפעיל תוכן מסוג DASH (mpd), HLS (m3u8) או SmoothStreaming (ism, isml), אבל הנגן מנסה להפעיל אותו כסטרימינג פרוגרסיבי. כדי להפעיל סטרימינג כזה, צריך להסתמך על המודול המתאים של ExoPlayer. במקרים שבהם ה-URI של הסטרימינג לא מסתיים בסיומת הקובץ הרגילה, אפשר גם להעביר את MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 או MimeTypes.APPLICATION_SS אל setMimeType של MediaItem.Builder כדי לציין במפורש את סוג הסטרימינג.
הסיבה השנייה, הפחות נפוצה, היא ש-ExoPlayer לא תומך בפורמט הקונטיינר של המדיה שאתם מנסים להפעיל. במקרה כזה, הכשל הוא מכוון, אבל אתם יכולים לשלוח הגשת בקשה להוספת תכונה בIssue Tracker, כולל פרטים על פורמט מאגר הנתונים וסטרימינג לבדיקה. לפני שאתם שולחים הגשת בקשה להוספת תכונה חדשה, חפשו אם כבר קיימת בקשה כזו.
למה setPlaybackParameters לא פועל כמו שצריך במכשירים מסוימים?
כשמפעילים גרסת build לניפוי באגים של האפליקציה ב-Android M ובגרסאות קודמות, יכול להיות שתבחינו בביצועים מקוטעים, בעיוותים בצליל ובניצול גבוה של המעבד (CPU) בזמן השימוש ב-API של setPlaybackParameters. הסיבה לכך היא שאופטימיזציה שחשובה ל-API הזה מושבתת בגרסאות build לניפוי באגים שפועלות בגרסאות האלה של Android.
חשוב לציין שהבעיה הזו משפיעה רק על גרסאות build לניפוי באגים. היא לא משפיעה על גרסאות build להפצה, שבהן האופטימיזציה תמיד מופעלת. לכן, הבעיה הזו לא אמורה להשפיע על הגרסאות שאתם מספקים למשתמשי הקצה.
מה המשמעות של השגיאות "הגישה לנגן מתבצעת בשרשור הלא נכון"?
במאמר תחילת השימוש ב-Service Management API מופיע מידע נוסף על שרשורים.
איך אפשר לתקן את השגיאה "Unexpected status line: ICY 200 OK"?
הבעיה הזו יכולה לקרות אם תגובת השרת כוללת שורת סטטוס ICY, במקום שורה שתואמת ל-HTTP. שורות הסטטוס של ICY הוצאו משימוש ואין להשתמש בהן. אם השרת בשליטתכם, אתם צריכים לעדכן אותו כדי שיספק תגובה שתואמת ל-HTTP. אם אתם לא יכולים לעשות זאת, תוכלו להשתמש בספריית ExoPlayer OkHttp כדי לפתור את הבעיה, כי היא יכולה לטפל בשורות סטטוס ICY בצורה נכונה.
איך אפשר לבדוק אם השידור שמופעל הוא שידור חי?
אפשר לשלוח שאילתה ל-method isCurrentWindowLive של הנגן. בנוסף, אפשר לבדוק את isCurrentWindowDynamic כדי לראות אם החלון דינמי (כלומר, עדיין מתעדכן לאורך זמן).
איך אפשר להמשיך להפעיל אודיו כשהאפליקציה פועלת ברקע?
כדי שהאודיו ימשיך לפעול כשהאפליקציה ברקע, צריך לפעול לפי השלבים הבאים:
- צריך להיות לכם שירות שפועל בחזית. כך המערכת לא תפסיק את התהליך כדי לפנות משאבים.
- אתם צריכים להחזיק ב
WifiLockובWakeLock. כך המערכת שומרת על מצב פעיל של ה-Wi-Fi והמעבד. אפשר לעשות את זה בקלות אם משתמשים ב-ExoPlayerבאמצעות קריאה ל-setWakeMode, שתקבל ותשחרר באופן אוטומטי את הנעילות הנדרשות בזמנים הנכונים.
חשוב לבטל את החסימות (אם לא משתמשים ב-setWakeMode) ולהפסיק את השירות ברגע שהאודיו מפסיק לפעול.
למה ExoPlayer תומך בתוכן שלי אבל ספריית ExoPlayer Cast לא?
יכול להיות שהתוכן שאתם מנסים להפעיל לא תומך ב-CORS. כדי להפעיל תוכן ב-Cast framework, צריך להפעיל CORS בתוכן.
למה התוכן לא מופעל, אבל לא מוצגת שגיאה?
יכול להיות שהמכשיר שבו אתם מפעילים את התוכן לא תומך בפורמט ספציפי של דגימת מדיה. כדי לוודא זאת, אפשר להוסיף EventLogger כמאזין לנגן, ולחפש שורה דומה לזו ב-Logcat:
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
הערך NO_UNSUPPORTED_TYPE מציין שהמכשיר לא יכול לפענח את פורמט דגימת המדיה שצוין על ידי mimeType. במסמכי התיעוד של פורמטים של מדיה ב-Android מפורט מידע על פורמטים נתמכים של דגימות. איך אפשר לטעון ספריית פענוח ולהשתמש בה להפעלה?
איך אפשר לטעון ספריית פענוח ולהשתמש בה להפעלה?
- ברוב ספריות המפענחים יש שלבים ידניים לבדיקה ולבנייה של יחסי התלות, אז חשוב לוודא שפעלתם לפי השלבים בקובץ README של הספרייה הרלוונטית. לדוגמה, בספריית ExoPlayer FFmpeg צריך לפעול לפי ההוראות בקובץ libraries/decoder_ffmpeg/README.md, כולל העברת דגלי הגדרה כדי להפעיל מפענחים לכל הפורמטים שרוצים להפעיל.
- בספריות שיש בהן קוד Native, חשוב לוודא שאתם משתמשים בגרסה הנכונה של Android NDK, כמו שמצוין בקובץ README, ולשים לב לשגיאות שמופיעות במהלך ההגדרה והפיתוח. אחרי שתבצעו את השלבים בקובץ README, אמורים להופיע קובצי
.soבספריית המשנהlibsשל נתיב הספרייה לכל ארכיטקטורה נתמכת. - כדי לנסות את ההפעלה באמצעות הספרייה באפליקציית ההדגמה, עיינו במאמר הפעלת מפענחים בחבילה. הוראות לשימוש בספרייה מהאפליקציה שלכם מופיעות בקובץ README של הספרייה.
- אם אתם משתמשים ב-
DefaultRenderersFactory, אמורה להופיע שורת יומן ברמת המידע כמו "Loaded FfmpegAudioRenderer" ב-Logcat כשהמפענח נטען. אם היא חסרה, צריך לוודא שהאפליקציה תלויה בספריית הפענוח. - אם מופיעים ב-Logcat יומנים ברמת אזהרה מ-
LibraryLoader, סימן שהטעינה של הרכיב המקורי של הספרייה נכשלה. במקרה כזה, צריך לוודא שפעלתם לפי השלבים בקובץ README של הספרייה, ושלא הופיעו שגיאות בזמן שפעלתם לפי ההוראות.
אם אתם עדיין נתקלים בבעיות בשימוש בספריות פענוח, כדאי לבדוק אם יש בעיות רלוונטיות מהזמן האחרון בIssue Tracker של Media3. אם אתם צריכים לדווח על בעיה חדשה שקשורה ליצירת החלק המקורי של הספרייה, צרפו את הפלט המלא של שורת הפקודה מהפעלת ההוראות בקובץ README, כדי לעזור לנו לאבחן את הבעיה.
אפשר להפעיל סרטונים ב-YouTube ישירות באמצעות ExoPlayer?
לא, ExoPlayer לא יכול להפעיל סרטונים מ-YouTube, כמו כתובות URL בפורמט https://www.youtube.com/watch?v=.... במקום זאת, צריך להשתמש ב-YouTube IFrame Player API, שהוא הדרך הרשמית להפעיל סרטוני YouTube ב-Android.
הפעלת הסרטון מקוטעת
יכול להיות שהמכשיר לא יצליח לפענח את התוכן מספיק מהר אם, לדוגמה, קצב העברת הנתונים או הרזולוציה של התוכן חורגים מהיכולות של המכשיר. יכול להיות שתצטרכו להשתמש בתוכן באיכות נמוכה יותר כדי לקבל ביצועים טובים במכשירים כאלה.
אם הסרטון נתקע במכשיר עם גרסת Android מ-Android 6.0 (רמת API 23) ועד Android 11 (רמת API 30) כולל, במיוחד כשמפעילים תוכן שמוגן באמצעות DRM או תוכן עם קצב פריימים גבוה, אתם יכולים לנסות להפעיל תור אסינכרוני במאגר נתונים זמני (buffer queue).
שגיאות lint ב-API לא יציב
Media3 מבטיח תאימות בינארית לקבוצת משנה של ממשק ה-API. החלקים שלא מבטיחים תאימות בינארית מסומנים ב-@UnstableApi. כדי להבהיר את ההבדל הזה, שימוש בסמלי API לא יציבים יוצר שגיאת lint, אלא אם הם מסומנים ב-@OptIn.
ההערה @UnstableApi לא מעידה על האיכות או הביצועים של ה-API, אלא רק על העובדה שהוא לא "API-frozen".
יש שתי אפשרויות לטיפול בשגיאות לא יציבות של API lint:
- עוברים לשימוש ב-API יציב שמשיג את אותה תוצאה.
- להמשיך להשתמש ב-API הלא יציב ולהוסיף הערה לשימוש באמצעות
@OptIn, כפי שמוצג בהמשך.
מוסיפים את ההערה @OptIn
Android Studio יכול לעזור לכם להוסיף את ההערה:
אתם יכולים גם להוסיף הערות באופן ידני לאתרים ספציפיים:
Kotlin
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Java
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
כדי להביע הסכמה לכל החבילות, אפשר להוסיף קובץ package-info:
Kotlin
// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
Java
// In your package-info.java
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
אפשר להצטרף לפרויקטים שלמים על ידי ביטול שגיאת ה-lint הספציפית בקובץ lint.xml שלהם:
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="UnsafeOptInUsageError">
<option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
</issue>
</lint>
יש גם הערה מסוג kotlin.OptIn שאסור להשתמש בה. חשוב להשתמש בהערה androidx.annotation.OptIn.
איך אפשר לבדוק או לבודד בעיות שנגרמו כתוצאה מאופטימיזציות או מתכונות חדשות?
Media3 כולל תשתית של feature flags שבה תכונות ואופטימיזציות חדשות מופעלות כברירת מחדל במצב Canary.
אם אתם חושדים שבעיה או רגרסיה באפליקציה קשורה לתכונה או לאופטימיזציה חדשה, אתם יכולים להשבית זמנית את מצב Canary:
Flags.setCanaryModeEnabled(false);
או להשבית feature flags ספציפיים בנפרד באמצעות Flags.disableFlag(flagId). למידע נוסף על הגדרת מצב Canary, שינוי דגלים והגדרת מתגי השבתה מרחוק, עיינו במדריך בנושא דגלי תכונות ומצב Canary.