- פתרון שגיאות מסוג 'תנועת HTTP בטקסט גלוי לא מורשית'
- פתרון השגיאות "SSLHandshakeException", "CertPathValidatorException" ו-"ERR_CERT_AUTHORITY_INVALID"
- למה אי אפשר להריץ קדימה או אחורה חלק מקובצי המדיה?
- למה המיקום לא מדויק בחלק מקובצי MP3?
- למה ההתקדמות בסרטון שלי איטית?
- למה חלק מקובצי MPEG-TS לא פועלים?
- למה לא נמצאות כתוביות בחלק מקובצי MPEG-TS?
- למה חלק מקובצי MP4/FMP4 מוצגים בצורה לא נכונה?
- למה חלק מהסטרימינג נכשל עם קוד תגובת HTTP 301 או 302?
- למה חלק מהסטרימים נכשלים עם UnrecognizedInputFormatException?
- למה הפונקציה setPlaybackParameters לא פועלת כמו שצריך בחלק מהמכשירים?
- מה המשמעות של השגיאות 'הגישה לנגן מתבצעת בשרשור הלא נכון'?
- איך אפשר לתקן את השגיאה 'שורת סטטוס לא צפויה: ICY 200 OK'?
- איך אפשר לברר אם הסטרימינג שמופעל הוא שידור חי?
- איך אפשר להמשיך להפעיל אודיו כשהאפליקציה פועלת ברקע?
- למה ExoPlayer תומך בתוכן שלי אבל ספריית ExoPlayer Cast לא?
- למה הפעלת התוכן נכשלת, אבל לא מוצגת שגיאה?
- איך אפשר לקבל ספריית פענוח כדי לטעון אותה ולהשתמש בה להפעלה?
- האם אפשר להפעיל סרטונים ב-YouTube ישירות באמצעות ExoPlayer?
- הפעלת הסרטון מגמגמת
- שגיאות לא יציבות ב-API lint
תיקון שגיאות מסוג 'תנועת 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 הקודם לבין מיקום החיפוש, ולמחוק אותם מיד (בלי להציג אותם במסך).
כדי לצמצם את ההשהיה שנוצרת בגלל (1), אפשר להגדיל את כמות הנתונים שמאוחסנים בזיכרון על ידי הנגן, או לטעון את הנתונים מראש מהמטמון בדיסק.
כדי לצמצם את זמן האחזור שנוצר בשלב (2), אפשר להקטין את רמת הדיוק של החיפוש באמצעות ExoPlayer.setSeekParameters, או לקודד מחדש את הסרטון כך שיהיו בו יותר פריימים מסוג I (מה שיגרום לקובץ פלט גדול יותר).
למה חלק מקובצי MPEG-TS לא פועלים?
חלק מקובצי MPEG-TS לא מכילים תווי הפרדה של יחידות גישה (AUD). כברירת מחדל, ExoPlayer מסתמך על יחידות AUD כדי לזהות גבולות של פריימים בעלות נמוכה. באופן דומה, חלק מקובצי MPEG-TS לא מכילים פריימים מרכזיים של IDR. כברירת מחדל, אלה הם סוגי פריימי המפתח היחידים ש-ExoPlayer מתייחס אליהם.
יכול להיות ש-ExoPlayer ייתקע במצב של אחסון בזיכרון הזמני (באפרינג) כשמבקשים ממנו להפעיל קובץ MPEG-TS שחסרים בו AUD או מסגרות מפתח של IDR. אם אתם צריכים להפעיל קבצים כאלה, אתם יכולים לעשות זאת באמצעות FLAG_DETECT_ACCESS_UNITS ו-FLAG_ALLOW_NON_IDR_KEYFRAMES בהתאמה. אפשר להגדיר את הדגלים האלה ב-DefaultExtractorsFactory באמצעות setTsExtractorFlags או ב-DefaultHlsExtractorFactory באמצעות הבונה.
לשימוש ב-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?
קודים 301 ו-302 של תגובת HTTP מציינים הפניה לכתובת אחרת. תיאורים קצרים זמינים בוויקיפדיה. כש-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 לא תומך בפורמט הקונטיינר של המדיה שאתם מנסים להפעיל. במקרה הזה, הכשל הוא כצפוי, אבל אפשר לשלוח הגשת בקשה להוספת תכונה לכלי למעקב אחרי בעיות, כולל פרטים על פורמט הקונטיינר וזרם בדיקה. לפני ששולחים הגשת בקשה להוספת תכונה חדשה, כדאי לחפש בקשות קיימות לתכונות.
למה הפונקציה setPlaybackParameters לא פועלת כמו שצריך בחלק מהמכשירים?
כשמריצים גרסת build לניפוי באגים של האפליקציה ב-Android M ובגרסאות קודמות, יכול להיות שתיתקלו בביצועים לא חלקים, בארטיפקטים שניתן לשמוע ובשימוש גבוה במעבד כשמשתמשים ב-API setPlaybackParameters. הסיבה לכך היא שאופטימיזציה שחשובה ל-API הזה מושבתת בגרסאות build לניפוי באגים שפועלות בגרסאות האלה של Android.
חשוב לציין שהבעיה הזו משפיעה רק על גרסאות ניפוי באגים. הוא לא משפיע על גרסאות ה-build להפצה, שבהן האופטימיזציה תמיד מופעלת. לכן, הבעיה הזו לא אמורה להשפיע על הגרסאות שאתם מספקים למשתמשי הקצה.
מה המשמעות של השגיאות 'הגישה לרכיב Player מתבצעת בשרשור הלא נכון'?
מידע נוסף זמין בקטע הערה בנושא שרשורים בדף תחילת העבודה.
איך אפשר לפתור את הבעיה 'שורת סטטוס לא צפויה: ICY 200 OK'?
הבעיה הזו יכולה להתרחש אם תגובת השרת כוללת שורת סטטוס ICY, ולא שורת סטטוס שתואמת ל-HTTP. השימוש בשורות הסטטוס של ICY הוצא משימוש, ולכן לא מומלץ להשתמש בהן. אם יש לכם שליטה בשרת, כדאי לעדכן אותו כך שיספק תגובה שתואמת ל-HTTP. אם לא הצלחתם לעשות את זה, שימוש בספריית ExoPlayer OkHttp יפתור את הבעיה, כי היא יודעת לטפל בשורות סטטוס של ICY בצורה נכונה.
איך אפשר לשאול אם השידור שמופעל הוא שידור חי?
אפשר לשלוח שאילתה לשיטה isCurrentWindowLive של הנגן. בנוסף, אפשר לסמן את התיבה isCurrentWindowDynamic כדי לבדוק אם חלון ההמרות הוא דינמי (כלומר, עדיין מתעדכן לאורך זמן).
איך אפשר להמשיך להפעיל אודיו כשהאפליקציה פועלת ברקע?
כדי לוודא שההפעלה של האודיו תימשך כשהאפליקציה פועלת ברקע:
- צריך להפעיל שירות שפועל בחזית. כך המערכת לא תפסיק את התהליך כדי לפנות משאבים.
- צריך להיות לכם
WifiLockוWakeLock. הם מבטיחים שמערכת תשאיר את רדיו ה-Wi-Fi ואת המעבד במצב פעיל. אם משתמשים ב-ExoPlayer, אפשר לעשות זאת בקלות על ידי קריאה ל-setWakeMode, שתשיג ותשחרר אוטומטית את הנעילות הנדרשות בזמנים הנכונים.
חשוב לבטל את הנעילה (אם לא משתמשים ב-setWakeMode) ולהפסיק את השירות ברגע שהשמע כבר לא מושמע.
למה ExoPlayer תומך בתוכן שלי אבל ספריית ExoPlayer Cast לא?
יכול להיות שהתוכן שאתם מנסים להפעיל לא תומך ב-CORS. כדי להפעיל תוכן באמצעות מסגרת Cast, צריך להפעיל את ה-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, אמור להופיע ב-Logcat קו יומן ברמת המידע, כמו 'Loaded FfmpegAudioRenderer', כשהמפענח נטען. אם הוא חסר, צריך לוודא שהאפליקציה תלויה בספריית הפענוח. - אם אתם רואים ב-Logcat יומנים ברמת אזהרה מ-
LibraryLoader, זה מצביע על כך שהטעינה של רכיב ה-native של הספרייה נכשלה. אם זה קורה, צריך לוודא שפעלתם לפי השלבים בקובץ ה-README של הספרייה בצורה נכונה, ושלא הוצגו שגיאות במהלך הפעולות.
אם אתם עדיין נתקלים בבעיות בשימוש בספריות פענוח, כדאי לבדוק בכלי למעקב אחרי בעיות של Media3 אם יש בעיות רלוונטיות מהזמן האחרון. אם אתם צריכים לדווח על בעיה חדשה שקשורה ליצירת החלק המקורי של הספרייה, עליכם לכלול את הפלט המלא של שורת הפקודה מהפעלת ההוראות בקובץ ה-README, כדי שנוכל לאבחן את הבעיה.
האם אפשר להפעיל סרטונים ב-YouTube ישירות באמצעות ExoPlayer?
לא, ל-ExoPlayer אין אפשרות להפעיל סרטונים מ-YouTube, כמו כתובות URL בפורמט
https://www.youtube.com/watch?v=.... במקום זאת, צריך להשתמש ב-YouTube
IFrame Player API, שהיא הדרך הרשמית להפעיל סרטונים ב-YouTube ב-Android.
הפעלת הסרטון מגמגמת
יכול להיות שהמכשיר לא יוכל לפענח את התוכן מספיק מהר אם, לדוגמה, קצב העברת הנתונים או הרזולוציה של התוכן חורגים מהיכולות של המכשיר. יכול להיות שתצטרכו להשתמש בתוכן באיכות נמוכה יותר כדי לקבל ביצועים טובים במכשירים כאלה.
אם אתם נתקלים בגימגום של סרטונים במכשיר עם Android מגרסה 6.0 (רמת API 23) עד גרסה 11 (רמת API 30) כולל, במיוחד כשמפעילים תוכן שמוגן על ידי DRM או תוכן עם קצב פריימים גבוה, אתם יכולים לנסות להפעיל תור מאגרים אסינכרוני.
שגיאות לא יציבות של API lint
Media3 מבטיח תאימות בינארית לחלק מממשק ה-API. החלקים שלא מבטיחים תאימות בינארית מסומנים ב-@UnstableApi. כדי להבהיר את ההבחנה הזו, שימוש בסמלי API לא יציבים יוצר שגיאת lint, אלא אם הם מסומנים ב-@OptIn.
ההערה @UnstableApi לא מרמזת על איכות או ביצועים של API, אלא רק על העובדה שהוא לא 'מוקפא'.
יש שתי אפשרויות לטיפול בשגיאות לא יציבות של 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.