Ang ExoPlayer ay isang open-source na media player library para sa Android, na binuo ng Google bilang alternatibo sa built-in na MediaPlayer. Ang ExoPlayer ay nagbibigay ng audio at video playback sa iba't ibang format, kabilang ang DASH, HLS, SmoothStreaming at ordinaryong media file, sa pamamagitan ng isang API na may suporta para sa adaptive streaming. Ayon sa Google I/O (2024), ang ExoPlayer ay ginagamit sa mahigit 60,000 Android app, kabilang ang YouTube, Google TV at Netflix.
Mga Pangunahing Punto
ExoPlayer ay isang library para sa multimedia playback sa Android na may open-source code (Apache 2.0), na ang unang bersyon ay inilabas ng Google noong 2014. Hindi tulad ng built-in na MediaPlayer, na isang manipis na layer sa ibabaw ng system media codec (MediaCodec), ang ExoPlayer ay ganap na naka-implement sa Java/Kotlin level, na nagbibigay sa mga developer ng buong kontrol sa bawat yugto ng playback.
Sa arkitektura, ang ExoPlayer ay binuo sa modular na prinsipyo: bawat aspeto ng playback ay naka-implement ng hiwalay na component. Ang pangunahing module (exoplayer-core) ay naglalaman ng player, renderer, track selector, at buffer management. Ang mga karagdagang module (exoplayer-dash, exoplayer-hls, exoplayer-rtsp, exoplayer-smoothstreaming) ay nagdadagdag ng suporta para sa kaukulang streaming protocols. Ang arkitekturang ito ay nagpapahintulot sa mga app na ikonekta lamang ang mga kinakailangang component, na nagpapaliit sa laki ng APK.
ExoPlayer 2 (kasalukuyang pangunahing bersyon) ay inilabas noong 2018 at nagdala ng malaking pagbabago sa API: pagpapakilala ng Player Interface, suporta para sa Compose sa pamamagitan ng AndroidX Media3, pinahusay na pag-handle ng error, at adaptive track selection algorithms. Mula sa bersyon 2.19 (2024), ang ExoPlayer ay naging bahagi ng AndroidX Media library, na nagpasimple ng integration at update sa pamamagitan ng standard Android dependency manager.
Sa puso ng ExoPlayer ay ang component na ExoPlayerImpl, na namamahala sa lifecycle ng playback. Ito ay naglalaman ng MediaSource (media source), TrackSelector (track selection), LoadControl (buffer management), at listahan ng Renderer (renderer para sa video, audio, subtitle at metadata). Bawat component ay maaaring palitan ng sariling implementasyon sa pamamagitan ng Builder o factory methods.
Para sa video rendering, ang ExoPlayer ay gumagamit ng SurfaceView, TextureView o SphericalSurfaceView (para sa 360-degree na video). Ang inirerekomendang opsyon ay SurfaceView dahil nagbibigay ito ng hardware acceleration at minimal na konsumo ng kuryente. Para sa Jetpack Compose, ang AndroidX Media3 library ay nagbibigay ng `AndroidView` component na bumabalot sa SurfaceView, at experimental na `Media3Compose` na may native Compose integration.
ExoPlayer ay nagbibigay ng malawak na hanay ng mga function na lampas sa ordinaryong media player. Ang mga pangunahing feature ay kinabibilangan ng suporta para sa lahat ng sikat na streaming protocols, flexible DRM system, adaptive bitrate switching (ABR), at playback analytics tools.
| Function | Paglalarawan | Module |
|---|---|---|
| DASH | Adaptive streaming ayon sa MPEG standard | exoplayer-dash |
| HLS | HTTP Live Streaming mula sa Apple | exoplayer-hls |
| SmoothStreaming | Adaptive streaming mula sa Microsoft | exoplayer-smoothstreaming |
| RTSP | Real-Time Streaming Protocol para sa live | exoplayer-rtsp |
| Widevine | DRM proteksyon ng content | exoplayer-drm |
| Concatenation | Pagsasama ng maraming media file | exoplayer-core |
| Ads | IMA SDK integration para sa mga ad | exoplayer-ima |
ABR (Adaptive Bitrate) sa ExoPlayer ay naka-implement sa pamamagitan ng AdaptiveTrackSelection interface. Bilang default, ginagamit ang AdaptiveTrackSelectionFactory na lumilikha ng DefaultAdaptiveTrackSelection — isang balanseng algorithm na isinasaalang-alang ang network bandwidth at buffer size. Para sa mga partikular na scenario, maaaring ikonekta ang mga alternatibong implementasyon: BOLA (pag-minimize ng switching), RandomAdaptiveTrackSelection (pagsubok), o sariling implementasyon sa pamamagitan ng TrackSelection interface.
BandwidthMeter ay isa pang mahalagang component na responsable sa pagsukat ng network bandwidth. Bilang default, ginagamit ang DefaultBandwidthMeter na nangongolekta ng statistics mula sa lahat ng HTTP requests ng player. Maaaring palawakin ito ng developer upang isaalang-alang ang mga karagdagang factor: uri ng network (Wi-Fi, 4G, 5G), signal ng cell tower, o halaga ng traffic para sa user.
ExoPlayer ay sumusuporta sa Widevine (L1, L3), PlayReady at ClearKey DRM. Ang pagkuha ng lisensya ay naka-configure sa pamamagitan ng DrmSessionManager na nakikipag-ugnayan sa license server. Para sa premium na video (4K HDR), kinakailangan ang hardware support ng Widevine L1 na nagbibigay ng proteksyon sa chip level at pumipigil sa screen capture. Ang pagpili ng DRM system ay depende sa target platform: Widevine ay ginagamit sa Android at Chromecast, PlayReady sa Xbox at Windows, FairPlay sa iOS at Apple TV. Awtomatikong tinutukoy ng ExoPlayer ang available na DRM system batay sa MPD file at hindi nangangailangan ng manual configuration para sa mga basic scenario.
Ang pagkonekta ng ExoPlayer sa Android project ay ginagawa sa pamamagitan ng Gradle dependencies. Mula sa bersyon 2.19, ang ExoPlayer ay bahagi ng AndroidX Media (androidx.media3) na tinitiyak ang compatibility sa Jetpack Compose at iba pang AndroidX component. Tingnan natin ang step-by-step na integration sa Kotlin.
Idagdag ang ExoPlayer modules sa build.gradle file (Module). Ang minimum na set ay kinabibilangan ng core, ui at module para sa kinakailangang streaming protocol. Para sa pag-play ng DASH content, kinakailangan ang exoplayer-dash, para sa HLS — exoplayer-hls.
dependencies {
implementation "androidx.media3:media3-exoplayer:1.5.0"
implementation "androidx.media3:media3-ui:1.5.0"
implementation "androidx.media3:media3-exoplayer-dash:1.5.0"
implementation "androidx.media3:media3-exoplayer-hls:1.5.0"
}
Paglikha at pag-configure ng player sa Activity o Fragment. Ang ExoPlayer ay gumagamit ng PlayerView (o StyledPlayerView para sa customization) para magpakita ng video at built-in na controls. Ang minimum na configuration ay kinabibilangan ng paglikha ng player sa pamamagitan ng ExoPlayer.Builder at pagpapasa ng MediaItem na may source URI.
class PlayerActivity : AppCompatActivity() {
private var player: ExoPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_player)
player = ExoPlayer.Builder(this).build()
val playerView = findViewById<StyledPlayerView>(R.id.playerView)
playerView.player = player
val mediaItem = MediaItem
.Builder()
.setUri("https://example.com/video.mp4")
.build()
player?.setMediaItem(mediaItem)
player?.prepare()
}
override fun onDestroy() {
player?.release()
super.onDestroy()
}
}
Para sa production apps, kinakailangan ang pag-handle ng mga posibleng playback error: network failures, hindi suportadong format, DRM licensing errors. Ang ExoPlayer ay nagbibigay ng Player.Listener interface na may mga method na onPlayerError, onPlaybackStateChanged at onPlayWhenReadyChanged. Inirerekomenda na magpakita ng mga informative error message sa user na may posibilidad ng pag-ulit.
Ang pagpili sa pagitan ng ExoPlayer at built-in na MediaPlayer ay karaniwang tanong sa pag-develop ng Android apps. Ang MediaPlayer ay bahagi ng Android SDK mula bersyon 1.0, habang ang ExoPlayer ay isang library na nangangailangan ng koneksyon sa pamamagitan ng Gradle. Tingnan natin ang kanilang mga pagkakaiba batay sa mga pangunahing criterion.
| Criterion | ExoPlayer | MediaPlayer |
|---|---|---|
| Arkitektura | Modular, ganap sa Java/Kotlin | Layer sa ibabaw ng system C++ components |
| Streaming | DASH, HLS, SmoothStreaming, RTSP | Local files lang at HLS (Android 9+) |
| Customization | Buong (bawat component mapapalitan) | Minimal (parameters lang) |
| Updates | Sa pamamagitan ng Google Play o APK (independyente sa OS) | Sa pamamagitan lang ng Android update (OTA) |
| Laki ng APK | +1-3 MB (depende sa modules) | 0 (bahagi ng system) |
| Min SDK | API 16+ (Android 4.1) | API 1+ |
| DRM | Widevine, PlayReady, ClearKey | Widevine (limitado) |
Mananalo ang ExoPlayer sa mga scenario na nangangailangan ng streaming (DASH, HLS), UI customization, DRM support at independence sa Android version. Ang MediaPlayer ay angkop para sa mga simpleng app na nagpe-play ng local media file, kung saan kritikal ang laki ng APK at walang requirements para sa adaptive streaming. Para sa mga modernong app na may content mula sa network, ang ExoPlayer ay malinaw na pagpipilian.
Exception — mga app na may minimum SDK na mas mababa sa API 16 (Android 4.1), na halos wala na sa merkado. Para sa lahat ng app na may targetSdk 33+ at minimum SDK 21+, ang ExoPlayer ay hindi lamang mas gusto, kundi kinakailangan para sa suporta ng mga modernong format tulad ng AV1 at Dolby Vision sa pamamagitan ng mga kaukulang extension.
Para sa production apps, ang basic integration ng ExoPlayer ay madalas nangangailangan ng karagdagang configuration: cache management, optimization ng buffering para sa mobile networks, integration sa analytics, at customization ng audio track selection. Tingnan natin ang mga advanced na use scenario.
CacheDataSourceFactory ay nagpapahintulot ng pag-cache ng mga na-download na segment sa local storage, na nakakatipid ng traffic sa paulit-ulit na panonood at nagbibigay ng offline playback. Gumagamit ang ExoPlayer ng SimpleCache mula sa exoplayer-cas library — file caching na may suporta para sa LRU evacuation at size limits.
val cache = SimpleCache(
cacheDir,
LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024),
AppDatabaseProvider(this)
)
val cacheDataSourceFactory = CacheDataSource
.Factory()
.setCache(cache)
val player = ExoPlayer.Builder(this)
.setMediaSourceFactory(
DefaultMediaSourceFactory(cacheDataSourceFactory)
)
.build()
Sa mobile apps, ang pag-handle ng switching sa pagitan ng Wi-Fi at cellular network ay mahalaga. Ang ExoPlayer ay nagbibigay ng ConnectivityManager para sa pagsubaybay ng network status. Sa pagkawala ng koneksyon, inirerekomenda na huwag itigil ang player, kundi ilipat ito sa PAUSED state na may pagpapanatili ng posisyon. Pagkatapos ng pagbawi ng koneksyon, ipagpatuloy ang playback na may reload ng mga segment.
Sa paglabas ng AndroidX Media3, ang library ay nakatanggap ng experimental na suporta para sa Jetpack Compose. Ang `AndroidView` component ay bumabalot ng SurfaceView o PlayerView, na tinitiyak ang compatibility sa Compose hierarchy. Para sa mas malalim na integration, ginagamit ang `androidx.media3:media3-ui-compose` library na nagbibigay ng Compose-compatible na player controls.
@Composable
fun VideoPlayer(uri: String) {
val context = LocalContext.current
val player = remember {
ExoPlayer.Builder(context).build()
.also { it.setMediaItem(MediaItem.fromUri(uri)) }
}
DisposableEffect(key = null) {
player.prepare()
onDispose { player.release() }
}
AndroidView(
factory = { StyledPlayerView(context).also { it.player = player } }
)
}
Mga Madalas Itanong
ExoPlayer ay sumusuporta sa Android API 16+ (Android 4.1 Jelly Bean). Gayunpaman, para sa DASH at HLS na may fMP4 segments, inirerekomenda ang API 21+ (Android 5.0 Lollipop). Ang DRM modules (Widevine) ay nangangailangan ng API 19+, at ang hardware decoding ng HEVC ay available mula API 21.
Oo, ang ExoPlayer ay mahusay para sa audio. Para sa pag-play ng tunog lamang, hindi kinakailangan ang SurfaceView o PlayerView. Awtomatikong pipili ang ExoPlayer ng audio renderer at gagana sa background. Para sa background playback, inirerekomenda ang paggamit ng MediaSessionService para sa integration sa system controls.
TrackSelector sa ExoPlayer ay namamahala sa pagpili ng audio tracks. Para lumipat, gamitin ang player.getCurrentTracks().groups at player.setTrackSelectionParameters() na may pagtukoy ng gustong audio language. Para sa DASH at HLS streams na may maraming audio tracks, ang paglipat ay nangyayari nang hindi naaabala ang playback.
Oo, sinusuportahan ng ExoPlayer ang built-in (sa MP4, WebM container) at external na subtitle sa mga format na TTML, SRT, VTT at CEA-608. Para sa external na subtitle, ginagamit ang SingleSampleMediaSource o MergingMediaSource para pagsamahin sa video stream. Ang pagpapakita ng naka-style na subtitle ay naka-configure sa pamamagitan ng CaptionStyleCompat.
Para sa Low-Latency streaming, i-configure ang LoadControl na may mas maliit na target buffer values: gamitin ang DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000) para sa HLS LL at DASH LL. Gayundin, itakda ang minPlaybackSpeed = 1.02 para sa accelerated buffer filling kapag nahuhuli sa live broadcast.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din