ExoPlayer: nó là gì, tính năng và thiết lập

Tác giả: IT Sectr Đã đăng: 2026-05-23 Thời gian đọc: 8 phút

ExoPlayer là một thư viện trình phát đa phương tiện mã nguồn mở dành cho Android do Google phát triển như một sự thay thế cho MediaPlayer tích hợp sẵn. ExoPlayer cung cấp khả năng phát âm thanh và video ở nhiều định dạng khác nhau, bao gồm DASH, HLS, SmoothStreaming và các tệp đa phương tiện thông thường, thông qua một API duy nhất có hỗ trợ phát trực tuyến thích ứng. Theo Google I/O (2024), ExoPlayer được sử dụng trong hơn 60.000 ứng dụng Android, bao gồm YouTube, Google TV và Netflix.

Điểm chính

  • ExoPlayer — thư viện trình phát đa phương tiện mã nguồn mở dành cho Android từ Google.
  • Định dạng đa nền tảng — ExoPlayer hỗ trợ DASH, HLS, SmoothStreaming và RTSP thông qua hệ thống mở rộng mô-đun.
  • Tùy chỉnh — mọi thành phần của trình phát (bộ kết xuất, nguồn dữ liệu, DRM) có thể được thay thế bằng triển khai tùy chỉnh.
  • Canvas và Compose — ExoPlayer tích hợp cả với cách tiếp cận View truyền thống (SurfaceView) và Jetpack Compose.
  • DRM — hỗ trợ Widevine, PlayReady và ClearKey thông qua hệ thống DRM mô-đun.

ExoPlayer là gì?

ExoPlayer là một thư viện phát đa phương tiện mã nguồn mở (Apache 2.0) dành cho Android, có phiên bản đầu tiên được Google phát hành vào năm 2014. Không giống như MediaPlayer tích hợp sẵn, vốn là một lớp bọc mỏng trên bộ giải mã đa phương tiện hệ thống (MediaCodec), ExoPlayer được triển khai hoàn toàn ở cấp độ Java/Kotlin, mang lại cho nhà phát triển quyền kiểm soát hoàn toàn đối với mọi giai đoạn phát lại.

Về mặt kiến trúc, ExoPlayer được xây dựng dựa trên nguyên tắc mô-đun: mỗi khía cạnh của việc phát lại được triển khai bởi một thành phần riêng biệt. Mô-đun lõi (exoplayer-core) chứa trình phát, bộ kết xuất, bộ chọn rành và quản lý bộ đệm. Các mô-đun bổ sung (exoplayer-dash, exoplayer-hls, exoplayer-rtsp, exoplayer-smoothstreaming) thêm hỗ trợ cho các giao thức phát trực tuyến tương ứng. Kiến trúc này cho phép các ứng dụng chỉ bao gồm các thành phần cần thiết, giảm thiểu kích thước APK.

ExoPlayer 2 (phiên bản chính hiện tại) được phát hành vào năm 2018 và mang lại sự đại tu lớn về API: giới thiệu Player Interface, hỗ trợ Compose thông qua AndroidX Media3, cải thiện xử lý lỗi và các thuật toán chọn rành thích ứng. Từ phiên bản 2.19 (2024), ExoPlayer trở thành một phần của thư viện AndroidX Media, đơn giản hóa việc tích hợp và cập nhật thông qua trình quản lý phụ thuộc tiêu chuẩn của Android.

Kiến trúc ExoPlayer

Ở trung tâm của ExoPlayer là thành phần ExoPlayerImpl, quản lý vòng đời phát lại. Nó chứa MediaSource (nguồn đa phương tiện), TrackSelector (chọn rành), LoadControl (quản lý bộ đệm) và danh sách Renderer (bộ kết xuất cho video, âm thanh, phụ đề và siêu dữ liệu). Mỗi thành phần có thể được thay thế bằng triển khai tùy chỉnh thông qua Builder hoặc phương thức nhà máy.

Để kết xuất video, ExoPlayer sử dụng SurfaceView, TextureView hoặc SphericalSurfaceView (cho video 360 độ). Lựa chọn được khuyến nghị là SurfaceView, vì nó cung cấp khả năng tăng tốc phần cứng và tiêu thụ điện tối thiểu. Đối với Jetpack Compose, thư viện AndroidX Media3 cung cấp thành phần `AndroidView`, bao bọc SurfaceView và `Media3Compose` thử nghiệm với tích hợp Compose gốc.

Tính năng của ExoPlayer

ExoPlayer cung cấp nhiều tính năng vượt xa một trình phát đa phương tiện thông thường. Các khả năng chính bao gồm hỗ trợ tất cả các giao thức phát trực tuyến phổ biến, hệ thống DRM linh hoạt, chuyển đổi tốc độ bit thích ứng (ABR) và công cụ phân tích phát lại.

Tính năngMô tảMô-đun
DASHPhát trực tuyến thích ứng theo chuẩn MPEGexoplayer-dash
HLSHTTP Live Streaming từ Appleexoplayer-hls
SmoothStreamingPhát trực tuyến thích ứng từ Microsoftexoplayer-smoothstreaming
RTSPGiao thức phát trực tuyến thời gian thực cho liveexoplayer-rtsp
WidevineBảo vệ nội dung DRMexoplayer-drm
ConcatenationGhép nhiều tệp đa phương tiệnexoplayer-core
AdsTích hợp IMA SDK cho quảng cáoexoplayer-ima

Chuyển đổi tốc độ bit thích ứng

ABR (Adaptive Bitrate) trong ExoPlayer được triển khai thông qua giao diện AdaptiveTrackSelection. Theo mặc định, AdaptiveTrackSelectionFactory được sử dụng, tạo ra DefaultAdaptiveTrackSelection — một thuật toán cân bằng xem xét băng thông mạng và kích thước bộ đệm. Đối với các trường hợp cụ thể, có thể kết nối các triển khai thay thế: BOLA (giảm thiểu chuyển đổi), RandomAdaptiveTrackSelection (thử nghiệm) hoặc triển khai tùy chỉnh thông qua giao diện TrackSelection.

BandwidthMeter — một thành phần quan trọng khác chịu trách nhiệm đo băng thông mạng. Theo mặc định, DefaultBandwidthMeter được sử dụng, thu thập thống kê về tất cả các yêu cầu HTTP của trình phát. Nhà phát triển có thể mở rộng nó để tính đến các yếu tố bổ sung: loại mạng (Wi-Fi, 4G, 5G), tín hiệu tháp di động hoặc chi phí dữ liệu cho người dùng.

DRM và bảo vệ nội dung

ExoPlayer hỗ trợ Widevine (L1, L3), PlayReady và ClearKey DRM. Việc lấy giấy phép được cấu hình thông qua DrmSessionManager, tương tác với máy chủ cấp phép. Đối với video cao cấp (4K HDR), cần hỗ trợ phần cứng Widevine L1, cung cấp bảo vệ ở cấp độ chip và ngăn chặn chụp màn hình. Việc lựa chọn hệ thống DRM phụ thuộc vào nền tảng mục tiêu: Widevine được sử dụng trên Android và Chromecast, PlayReady trên Xbox và Windows, FairPlay trên iOS và Apple TV. ExoPlayer tự động xác định hệ thống DRM khả dụng dựa trên tệp MPD và không yêu cầu cấu hình thủ công cho các trường hợp cơ bản.

Cách tích hợp ExoPlayer vào dự án Android

Việc kết nối ExoPlayer với một dự án Android được thực hiện thông qua các phụ thuộc Gradle. Từ phiên bản 2.19, ExoPlayer là một phần của AndroidX Media (androidx.media3), đảm bảo tương thích với Jetpack Compose và các thành phần AndroidX khác. Hãy xem tích hợp từng bước trong Kotlin.

Thêm phụ thuộc

Thêm các mô-đun ExoPlayer vào tệp build.gradle (Module). Bộ tối thiểu bao gồm core, ui và mô-đun cho giao thức phát trực tuyến cần thiết. Để phát nội dung DASH, cần exoplayer-dash, cho HLS — exoplayer-hls.

groovy
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"
}

Tích hợp cơ bản trong Activity

Tạo và cấu hình trình phát trong Activity hoặc Fragment. ExoPlayer sử dụng PlayerView (hoặc StyledPlayerView để tùy chỉnh) để hiển thị video và các điều khiển tích hợp sẵn. Cấu hình tối thiểu bao gồm tạo trình phát qua ExoPlayer.Builder và chuyển MediaItem với URI nguồn.

kotlin
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()
    }
}

Xử lý lỗi và trạng thái

Đối với ứng dụng sản xuất, cần xử lý các lỗi phát lại có thể xảy ra: lỗi mạng, định dạng không được hỗ trợ, lỗi cấp phép DRM. ExoPlayer cung cấp giao diện Player.Listener với các phương thức onPlayerError, onPlaybackStateChanged và onPlayWhenReadyChanged. Nên hiển thị cho người dùng thông báo lỗi có thông tin kèm tùy chọn thử lại.

ExoPlayer so với MediaPlayer: so sánh

Lựa chọn giữa ExoPlayer và MediaPlayer tích hợp sẵn là một câu hỏi phổ biến khi phát triển ứng dụng Android. MediaPlayer là một phần của Android SDK từ phiên bản 1.0, trong khi ExoPlayer là một thư viện yêu cầu phụ thuộc Gradle. Hãy xem sự khác biệt của chúng theo các tiêu chí chính.

Tiêu chíExoPlayerMediaPlayer
Kiến trúcMô-đun, hoàn toàn bằng Java/KotlinLớp bọc trên thành phần C++ hệ thống
Phát trực tuyếnDASH, HLS, SmoothStreaming, RTSPChỉ tệp cục bộ và HLS (Android 9+)
Tùy chỉnhHoàn toàn (mọi thành phần đều thay thế được)Tối thiểu (chỉ tham số)
Cập nhậtQua Google Play hoặc APK (không phụ thuộc HĐH)Chỉ qua cập nhật Android (OTA)
Kích thước APK+1–3 MB (tùy mô-đun)0 (một phần của HĐH)
SDK tối thiểuAPI 16+ (Android 4.1)API 1+
DRMWidevine, PlayReady, ClearKeyWidevine (hạn chế)

ExoPlayer vượt trội trong các kịch bản yêu cầu phát trực tuyến (DASH, HLS), tùy chỉnh giao diện người dùng, hỗ trợ DRM và độc lập với phiên bản Android. MediaPlayer phù hợp cho các ứng dụng đơn giản phát tệp đa phương tiện cục bộ, nơi kích thước APK là quan trọng và không có yêu cầu về phát trực tuyến thích ứng. Đối với các ứng dụng hiện đại có nội dung từ mạng, ExoPlayer là lựa chọn rõ ràng.

Ngoại lệ — các ứng dụng có SDK tối thiểu dưới API 16 (Android 4.1), hầu như không còn trên thị trường. Đối với tất cả các ứng dụng có targetSdk 33+ và SDK tối thiểu 21+, ExoPlayer không chỉ được ưa tiên mà còn cần thiết để hỗ trợ các định dạng hiện đại như AV1 và Dolby Vision thông qua các phần mở rộng thích hợp.

Cấu hình nâng cao ExoPlayer

Đối với các ứng dụng sản xuất, việc tích hợp cơ bản ExoPlayer thường yêu cầu cấu hình bổ sung: quản lý bộ nhớ đệm, tối ưu hóa bộ đệm cho mạng di động, tích hợp phân tích và tùy chỉnh lựa chọn rành âm thanh. Hãy xem các kịch bản sử dụng nâng cao.

Lưu vùng đệm nội dung

CacheDataSourceFactory cho phép lưu vùng đệm các phân đoạn đã tải xuống vào bộ nhớ cục bộ, tiết kiệm lưu lượng khi xem lại và cho phép phát ngoại tuyến. ExoPlayer sử dụng SimpleCache từ thư viện exoplayer-cas — bộ nhớ đệm dựa trên tệp có hỗ trợ loại bỏ LRU và giới hạn kích thước.

kotlin
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()

Xử lý chuyển đổi mạng

Trong các ứng dụng di động, việc xử lý chuyển đổi giữa Wi-Fi và mạng di động là rất quan trọng. ExoPlayer cung cấp ConnectivityManager để theo dõi trạng thái mạng. Khi mất kết nối, nên không dừng trình phát mà chuyển nó sang trạng thái PAUSED trong khi giữ nguyên vị trí. Sau khi khôi phục kết nối, hãy tiếp tục phát lại bằng cách tải lại các phân đoạn.

Tích hợp với Jetpack Compose

Với sự ra mắt của AndroidX Media3, thư viện đã có hỗ trợ thử nghiệm cho Jetpack Compose. Thành phần `AndroidView` bao bọc SurfaceView hoặc PlayerView, đảm bảo tương thích với phân cấp Compose. Để tích hợp sâu hơn, thư viện `androidx.media3:media3-ui-compose` được sử dụng, cung cấp các điều khiển trình phát tương thích Compose.

kotlin
@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 } }
    )
}

Câu hỏi thường gặp

Phiên bản Android tối thiểu cho ExoPlayer là gì?

ExoPlayer hỗ trợ Android API 16+ (Android 4.1 Jelly Bean). Tuy nhiên, đối với DASH và HLS với các phân đoạn fMP4, nên sử dụng API 21+ (Android 5.0 Lollipop). Các mô-đun DRM (Widevine) yêu cầu API 19+ và giải mã HEVC phần cứng khả dụng từ API 21.

Có thể sử dụng ExoPlayer chỉ cho âm thanh mà không có video không?

Có, ExoPlayer rất phù hợp cho âm thanh. Đối với phát chỉ âm thanh, không cần SurfaceView hoặc PlayerView. ExoPlayer sẽ tự động chọn bộ kết xuất âm thanh và hoạt động trong nền. Để phát nền, nên sử dụng MediaSessionService để tích hợp với các điều khiển hệ thống.

Làm thế nào để chuyển đổi giữa các rành âm thanh trong ExoPlayer?

TrackSelector trong ExoPlayer quản lý việc chọn rành âm thanh. Để chuyển đổi, hãy sử dụng player.getCurrentTracks().groups và player.setTrackSelectionParameters() chỉ định ngôn ngữ âm thanh ưa thích. Đối với các luồng DASH và HLS có nhiều rành âm thanh, việc chuyển đổi diễn ra mà không làm gián đoạn phát lại.

ExoPlayer có hỗ trợ phụ đề không?

Có, ExoPlayer hỗ trợ phụ đề nhúng (trong vùng chứa MP4, WebM) và bên ngoài ở các định dạng TTML, SRT, VTT và CEA-608. Đối với phụ đề bên ngoài, SingleSampleMediaSource hoặc MergingMediaSource được sử dụng để hợp nhất với luồng video. Hiển thị phụ đề có kiểu cách được cấu hình thông qua CaptionStyleCompat.

Làm thế nào để giảm độ trễ trong phát trực tiếp với ExoPlayer?

Đối với phát trực tuyến độ trễ thấp, hãy cấu hình LoadControl với các giá trị bộ đệm mục tiêu nhỏ hơn: sử dụng DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000) cho HLS LL và DASH LL. Đồng thời đặt minPlaybackSpeed = 1.02 để đổ đầy bộ đệm tăng tốc khi bị tụt lại so với phát trực tiếp.

Tóm tắt

  • ExoPlayer — thư viện trình phát đa phương tiện mã nguồn mở từ Google với kiến trúc mô-đun và tùy chỉnh hoàn toàn.
  • Phát trực tuyến thích ứng — hỗ trợ DASH, HLS, SmoothStreaming và RTSP thông qua hệ thống mở rộng mô-đun.
  • DRM — Widevine, PlayReady và ClearKey tích hợp qua mô-đun exoplayer-drm với API thống nhất.
  • Bộ nhớ đệm — SimpleCache cho phép phát ngoại tuyến và tiết kiệm lưu lượng khi xem lại.
  • Compose — từ AndroidX Media3, ExoPlayer tích hợp với Jetpack Compose thông qua AndroidView.
  • Tùy chỉnh — mọi thành phần (MediaSource, TrackSelector, LoadControl, Renderer) đều có thể thay thế.
  • Khuyến nghị sử dụng ExoPlayer cho tất cả các dự án cần phát trực tuyến, DRM hoặc tùy chỉnh phát lại.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm