ExoPlayer: چیست، قابلیت‌ها و تنظیمات

نویسنده: IT Sectr منتشر شده: 2026-05-23 زمان مطالعه: 8 دقیقه

ExoPlayer یک کتابخانه پخش‌کننده رسانه متن‌باز برای اندروید است که توسط گوگل به عنوان جایگزینی برای MediaPlayer داخلی توسعه یافته است. ExoPlayer پخش صوتی و تصویری را در فرمت‌های مختلف از جمله DASH، HLS، SmoothStreaming و فایل‌های رسانه معمولی از طریق یک API واحد با پشتیبانی از پخش تطبیقی فراهم می‌کند. به گفته Google I/O (2024)، ExoPlayer در بیش از 60٬000 اپلیکیشن اندروید از جمله YouTube، Google TV و Netflix استفاده می‌شود.

نکات کلیدی

  • ExoPlayer یک کتابخانه پخش‌کننده رسانه متن‌باز برای اندروید از گوگل است.
  • فرمت‌های چندسکویی — ExoPlayer از DASH، HLS، SmoothStreaming و RTSP از طریق سیستم افزونه‌های ماژولار پشتیبانی می‌کند.
  • شخصی‌سازی — هر مؤلفه پخش‌کننده (رندرکننده، منبع داده، DRM) می‌تواند با پیاده‌سازی شخصی جایگزین شود.
  • Canvas و Compose — ExoPlayer هم با رویکرد سنتی View (SurfaceView) و هم با Jetpack Compose ادغام می‌شود.
  • DRM — پشتیبانی از Widevine، PlayReady و ClearKey از طریق سیستم DRM ماژولار.

ExoPlayer چیست؟

ExoPlayer یک کتابخانه پخش چندرسانه‌ای برای اندروید با کد متن‌باز (Apache 2.0) است که اولین نسخه آن توسط گوگل در سال 2014 منتشر شد. برخلاف MediaPlayer داخلی که یک لایه نازک بر روی کدک رسانه سیستمی (MediaCodec) است، ExoPlayer کاملاً در سطح Java/Kotlin پیاده‌سازی شده است که به توسعه‌دهندگان کنترل کامل بر هر مرحله از پخش می‌دهد.

از نظر معماری، ExoPlayer بر اصل ماژولار ساخته شده است: هر جنبه از پخش توسط یک مؤلفه جداگانه پیاده‌سازی می‌شود. ماژول اصلی (exoplayer-core) شامل پخش‌کننده، رندرکننده‌ها، انتخاب‌گرهای مسیر و مدیریت بافر است. ماژول‌های اضافی (exoplayer-dash، exoplayer-hls، exoplayer-rtsp، exoplayer-smoothstreaming) پشتیبانی از پروتکل‌های پخش مربوطه را اضافه می‌کنند. این معماری به اپلیکیشن‌ها اجازه می‌دهد فقط مؤلفه‌های لازم را متصل کرده و اندازه APK را به حداقل برسانند.

ExoPlayer 2 (نسخه اصلی فعلی) در سال 2018 منتشر شد و بازنگری اساسی API را به ارمغان آورد: معرفی Player Interface، پشتیبانی از Compose از طریق AndroidX Media3، مدیریت خطای بهبود یافته و الگوریتم‌های تطبیقی انتخاب مسیر. از نسخه 2.19 (2024)، ExoPlayer بخشی از کتابخانه AndroidX Media شده است که ادغام و به‌روزرسانی را از طریق مدیر وابستگی استاندارد اندروید ساده‌تر کرده است.

معماری ExoPlayer

در هسته ExoPlayer مؤلفه ExoPlayerImpl قرار دارد که چرخه حیات پخش را مدیریت می‌کند. این مؤلفه شامل MediaSource (منبع رسانه)، TrackSelector (انتخاب مسیر)، LoadControl (مدیریت بافر) و فهرستی از Renderer (رندرکننده‌های ویدئو، صدا، زیرنویس و فراداده) است. هر مؤلفه می‌تواند از طریق Builder یا روش‌های کارخانه‌ای با پیاده‌سازی شخصی جایگزین شود.

برای رندر ویدئو، ExoPlayer از SurfaceView، TextureView یا SphericalSurfaceView (برای ویدئوی 360 درجه) استفاده می‌کند. گزینه توصیه‌شده SurfaceView است زیرا شتاب سخت‌افزاری و حداقل مصرف انرژی را فراهم می‌کند. برای Jetpack Compose، کتابخانه AndroidX Media3 مؤلفه `AndroidView` را ارائه می‌دهد که SurfaceView را می‌پیچد و همچنین `Media3Compose` آزمایشی با ادغام بومی Compose.

قابلیت‌های ExoPlayer

ExoPlayer مجموعه گسترده‌ای از قابلیت‌های فراتر از یک پخش‌کننده رسانه معمولی را فراهم می‌کند. قابلیت‌های اصلی شامل پشتیبانی از تمام پروتکل‌های محبوب پخش، سیستم DRM انعطاف‌پذیر، تغییر نرخ بیت تطبیقی (ABR) و ابزارهای تحلیل پخش است.

قابلیتتوضیحاتماژول
DASHپخش تطبیقی بر اساس استاندارد MPEGexoplayer-dash
HLSHTTP Live Streaming از اپلexoplayer-hls
SmoothStreamingپخش تطبیقی از مایکروسافتexoplayer-smoothstreaming
RTSPپروتکل پخش بلادرنگ برای پخش زندهexoplayer-rtsp
Widevineحفاظت از محتوای DRMexoplayer-drm
Concatenationالحاق چند فایل رسانهexoplayer-core
Adsادغام IMA SDK برای تبلیغاتexoplayer-ima

تغییر نرخ بیت تطبیقی

ABR (Adaptive Bitrate) در ExoPlayer از طریق رابط AdaptiveTrackSelection پیاده‌سازی شده است. به طور پیش‌فرض از AdaptiveTrackSelectionFactory استفاده می‌شود که DefaultAdaptiveTrackSelection را ایجاد می‌کند — یک الگوریتم متعادل که پهنای باند شبکه و اندازه بافر را در نظر می‌گیرد. برای سناریوهای خاص، می‌توان پیاده‌سازی‌های جایگزین را متصل کرد: BOLA (به حداقل رساندن تغییرات)، RandomAdaptiveTrackSelection (تست) یا پیاده‌سازی شخصی از طریق رابط TrackSelection.

BandwidthMeter یکی دیگر از مؤلفه‌های کلیدی است که مسئول اندازه‌گیری پهنای باند شبکه است. به طور پیش‌فرض از DefaultBandwidthMeter استفاده می‌شود که آمار تمام درخواست‌های HTTP پخش‌کننده را جمع‌آوری می‌کند. توسعه‌دهنده می‌تواند آن را برای در نظر گرفتن عوامل اضافی گسترش دهد: نوع شبکه (Wi-Fi، 4G، 5G)، سیگنال دکل مخابراتی یا هزینه ترافیک برای کاربر.

DRM و حفاظت از محتوا

ExoPlayer از Widevine (L1، L3)، PlayReady و ClearKey DRM پشتیبانی می‌کند. دریافت مجوز از طریق DrmSessionManager که با سرور مجوز تعامل دارد، پیکربندی می‌شود. برای ویدئوی پریمیوم (4K HDR) پشتیبانی سخت‌افزاری Widevine L1 مورد نیاز است که حفاظت در سطح تراشه را فراهم کرده و از ضبط صفحه جلوگیری می‌کند. انتخاب سیستم DRM به پلتفرم هدف بستگی دارد: Widevine در اندروید و Chromecast، PlayReady در Xbox و Windows، FairPlay در iOS و Apple TV استفاده می‌شود. ExoPlayer به طور خودکار سیستم DRM موجود را بر اساس فایل MPD تعیین می‌کند و برای سناریوهای پایه به پیکربندی دستی نیاز ندارد.

چگونه ExoPlayer را در پروژه اندروید ادغام کنیم

اتصال ExoPlayer به پروژه اندروید از طریق وابستگی‌های Gradle انجام می‌شود. از نسخه 2.19، ExoPlayer بخشی از AndroidX Media (androidx.media3) است که سازگاری با Jetpack Compose و سایر مؤلفه‌های AndroidX را تضمین می‌کند. بیایید ادغام گام‌به‌گام در Kotlin را بررسی کنیم.

اتصال وابستگی‌ها

ماژول‌های ExoPlayer را به فایل build.gradle (Module) اضافه کنید. مجموعه حداقلی شامل core، ui و ماژول برای پروتکل پخش مورد نیاز است. برای پخش محتوای DASH به exoplayer-dash و برای 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"
}

ادغام پایه در Activity

ایجاد و پیکربندی پخش‌کننده در Activity یا Fragment. ExoPlayer از PlayerView (یا StyledPlayerView برای شخصی‌سازی) برای نمایش ویدئو و کنترل‌های داخلی استفاده می‌کند. حداقل پیکربندی شامل ایجاد پخش‌کننده از طریق ExoPlayer.Builder و ارسال MediaItem با URI منبع است.

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

مدیریت خطاها و وضعیت‌ها

برای اپلیکیشن‌های تولیدی، مدیریت خطاهای احتمالی پخش ضروری است: خرابی شبکه، فرمت‌های پشتیبانی‌نشده، خطاهای مجوز DRM. ExoPlayer رابط Player.Listener را با متدهای onPlayerError، onPlaybackStateChanged و onPlayWhenReadyChanged ارائه می‌دهد. توصیه می‌شود پیام‌های خطای آموزنده با امکان تکرار به کاربر نشان داده شود.

ExoPlayer در مقابل MediaPlayer: مقایسه

انتخاب بین ExoPlayer و MediaPlayer داخلی یک سوال رایج در توسعه اپلیکیشن‌های اندروید است. MediaPlayer از نسخه 1.0 بخشی از Android SDK است، در حالی که ExoPlayer کتابخانه‌ای است که نیاز به اتصال از طریق Gradle دارد. تفاوت‌های آنها را بر اساس معیارهای کلیدی بررسی کنیم.

معیارExoPlayerMediaPlayer
معماریماژولار، کاملاً در Java/Kotlinلایه‌ای بر مؤلفه‌های C++ سیستمی
پخشDASH، HLS، SmoothStreaming، RTSPفقط فایل‌های محلی و HLS (اندروید 9+)
شخصی‌سازیکامل (هر مؤلفه قابل جایگزینی)حداقل (فقط پارامترها)
به‌روزرسانی‌هااز طریق Google Play یا APK (مستقل از OS)فقط از طریق به‌روزرسانی اندروید (OTA)
اندازه APK+1-3 مگابایت (بسته به ماژول‌ها)0 (بخشی از سیستم)
حداقل SDKAPI 16+ (اندروید 4.1)API 1+
DRMWidevine، PlayReady، ClearKeyWidevine (محدود)

ExoPlayer برتر است در سناریوهایی که نیاز به پخش (DASH، HLS)، شخصی‌سازی UI، پشتیبانی DRM و استقلال از نسخه اندروید دارند. MediaPlayer برای اپلیکیشن‌های ساده‌ای که فایل‌های رسانه محلی را پخش می‌کنند، مناسب است جایی که اندازه APK حیاتی است و الزامی برای پخش تطبیقی وجود ندارد. برای اپلیکیشن‌های مدرن با محتوای شبکه، ExoPlayer انتخاب قطعی است.

استثنا — اپلیکیشن‌هایی با حداقل SDK کمتر از API 16 (اندروید 4.1) که عملاً در بازار باقی نمانده‌اند. برای تمام اپلیکیشن‌های با targetSdk 33+ و حداقل SDK 21+، ExoPlayer نه تنها ترجیح داده می‌شود، بلکه برای پشتیبانی از فرمت‌های مدرن مانند AV1 و Dolby Vision از طریق افزونه‌های مربوطه ضروری است.

تنظیمات پیشرفته ExoPlayer

برای اپلیکیشن‌های تولیدی، ادغام پایه ExoPlayer اغلب به تنظیمات اضافی نیاز دارد: مدیریت حافظه نهان، بهینه‌سازی بافر برای شبکه‌های موبایل، ادغام با تحلیل و شخصی‌سازی انتخاب مسیرهای صوتی. بیایید سناریوهای استفاده پیشرفته را بررسی کنیم.

ذخیره‌سازی محتوا در حافظه نهان

CacheDataSourceFactory امکان ذخیره‌سازی بخش‌های بارگیری‌شده در حافظه محلی را فراهم می‌کند که باعث صرفه‌جویی در ترافیک در هنگام تماشای مجدد و پخش آفلاین می‌شود. ExoPlayer از SimpleCache از کتابخانه exoplayer-cas استفاده می‌کند — ذخیره‌سازی فایلی با پشتیبانی از تخلیه LRU و محدودیت اندازه.

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

مدیریت تغییر شبکه

در اپلیکیشن‌های موبایل، مدیریت تغییر بین Wi-Fi و شبکه سلولی حیاتی است. ExoPlayer ConnectivityManager را برای ردیابی وضعیت شبکه فراهم می‌کند. هنگام قطع اتصال، توصیه می‌شود پخش‌کننده را متوقف نکنید، بلکه با حفظ موقعیت به حالت PAUSED منتقل کنید. پس از بازیابی اتصال، پخش را با بارگیری مجدد بخش‌ها از سر بگیرید.

ادغام با Jetpack Compose

با انتشار AndroidX Media3، کتابخانه پشتیبانی آزمایشی از Jetpack Compose دریافت کرد. مؤلفه `AndroidView` SurfaceView یا PlayerView را می‌پیچد و سازگاری با سلسله‌مراتب Compose را تضمین می‌کند. برای ادغام عمیق‌تر، از کتابخانه `androidx.media3:media3-ui-compose` استفاده می‌شود که کنترل‌های سازگار با 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 } }
    )
}

سوالات متداول

حداقل نسخه اندروید برای ExoPlayer چقدر است؟

ExoPlayer از Android API 16+ (اندروید 4.1 Jelly Bean) پشتیبانی می‌کند. با این حال، برای DASH و HLS با بخش‌های fMP4، API 21+ (اندروید 5.0 Lollipop) توصیه می‌شود. ماژول‌های DRM (Widevine) به API 19+ نیاز دارند و رمزگشایی سخت‌افزاری HEVC از API 21 در دسترس است.

آیا می‌توان از ExoPlayer برای صدا بدون ویدئو استفاده کرد؟

بله، ExoPlayer برای صدا عالی است. برای پخش فقط صدا به SurfaceView یا PlayerView نیازی نیست. ExoPlayer به طور خودکار رندرکننده صدا را انتخاب کرده و در پس‌زمینه کار می‌کند. برای پخش پس‌زمینه، توصیه می‌شود از MediaSessionService برای ادغام با کنترل‌های سیستمی استفاده کنید.

چگونه بین مسیرهای صوتی در ExoPlayer جابجا شویم؟

TrackSelector در ExoPlayer انتخاب مسیرهای صوتی را مدیریت می‌کند. برای جابجایی از player.getCurrentTracks().groups و player.setTrackSelectionParameters() با指定 زبان صوتی ترجیحی استفاده کنید. برای جریان‌های DASH و HLS با چندین مسیر صوتی، جابجایی بدون قطع پخش انجام می‌شود.

آیا ExoPlayer از زیرنویس پشتیبانی می‌کند؟

بله، ExoPlayer از زیرنویس‌های داخلی (در کانتینر MP4، WebM) و خارجی در فرمت‌های TTML، SRT، VTT و CEA-608 پشتیبانی می‌کند. برای زیرنویس‌های خارجی از SingleSampleMediaSource یا MergingMediaSource برای ترکیب با جریان ویدئو استفاده می‌شود. نمایش زیرنویس‌های سبک‌دار از طریق CaptionStyleCompat پیکربندی می‌شود.

چگونه تأخیر در پخش زنده در ExoPlayer را کاهش دهیم؟

برای پخش کم‌تأخیر، LoadControl را با مقادیر هدف بافر کوچک‌تر پیکربندی کنید: برای HLS LL و DASH LL از DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000) استفاده کنید. همچنین minPlaybackSpeed = 1.02 را برای پر کردن سریع‌تر بافر هنگام عقب‌ماندن از پخش زنده تنظیم کنید.

خلاصه

  • ExoPlayer — کتابخانه پخش‌کننده رسانه متن‌باز از گوگل با معماری ماژولار و شخصی‌سازی کامل.
  • پخش تطبیقی — پشتیبانی از DASH، HLS، SmoothStreaming و RTSP از طریق سیستم افزونه‌های ماژولار.
  • DRM — Widevine، PlayReady و ClearKey از طریق ماژول exoplayer-drm با API واحد ادغام می‌شوند.
  • ذخیره‌سازی نهان — SimpleCache پخش آفلاین و صرفه‌جویی در ترافیک در تماشای مجدد را فراهم می‌کند.
  • Compose — از AndroidX Media3، ExoPlayer از طریق AndroidView با Jetpack Compose ادغام می‌شود.
  • شخصی‌سازی — هر مؤلفه (MediaSource، TrackSelector، LoadControl، Renderer) قابل جایگزینی است.
  • توصیه می‌شود — برای تمام پروژه‌هایی که نیاز به پخش، DRM یا شخصی‌سازی پخش دارند از ExoPlayer استفاده کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید