ExoPlayer و آموزش پخش ویدیو در اندروید

ExoPlayer و آموزش پخش ویدیو در اندروید
در این پست می‌خوانید:

به جرات میشه گفت ExoPlayer بهترین ویدیو پلیر اندروید هستش که دستتون واقعا همه جوره باز هست.

با این پلیر هر نوع فرمت ویدیو ای که مد نظرت باشه رو میتونی پخش کنی.

خیلی راحت میتونی ویدیوهای آنلاین و آفلاین رو پخش کنی.

به بهترین شکل ممکن عملیات مربوط به بافرینگ پخش ویدیو رو انجام میده و واقعا میشه گفت همه چیز تموم هست.

توی این مقاله میخوام آموزش اگزوپلیر رو بدم و بگم که چطور میتونی خیلی راحت از این پلیر قدرتمند اندروید استفاده کنی.

اضافه کردن کتابخونه ExoPlayer به پروژه اندروید

برای اینکه بتونی از این کتابخونه قدرتمند استفاده کنی باید dependency زیر رو به فایل build.gradle پروژه خودت اضافه کنی

implementation 'com.google.android.exoplayer:exoplayer:2.18.0'

بعد از اضافه کردن این کتابخونه، پروژه رو باید sync کنی.

حالا که سینک کردن پروژه با موفقیت به پایان رسید، نوبت این رسیده که ازش استفاده کنیم.

آموزش استفاده کردن از اگزوپلیر

برای استفاده کردن از این کتابخونه اول از همه باید ویو مربوط به اون رو به XML صفحه ای که میخوای ویدیو رو نشون بدی اضافه کنی.

بعد از اون باید کدهای کاتلین یا جاوا رو بهش اضافه کنی و ازش استفاده کنی.

استفاده کردن از این کتابخونه به صورت پیشفرض کار خیلی سختی نیستش.

ولی توی این مقاله آموزشی میخوام یکسری نکات خیلی مهم و کمیابی هم آموزش بدم.

مثل کَش کردن ویدیو ها، تغییر ظاهری نمایش ویدیو و …

اضافه کردن View به فایل XML

اول از همه باید View مربوط به این پلیر رو به فایل XML خودمون اضافه کنیم.

من قصد دارم از این پلیر در یک اکتیویتی با نام PlayerActivity استفاده کنم.

برای همین کد زیر رو به activity_player.xml اضافه میکنم:

<com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/myPlayer"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
نکته
این نکته رو هم حواست باشه که این ساده ترین حالت ممکن برای نمایش ویدیو هستش.
جلوتر یاد میدم که بتونی شخصی سازیش کنی و بهترش کنی.

حالا که این ویو رو به XML اضافه کردی دیگه میتونی با کدهای کاتلین یا جاوا تنظیمات دیگه‌ش رو انجام بدی و ویدیو رو پخش کنی.

اضافه کردن کدهای کاتلین

توی این آموزش قراره که با زبان کاتلین پیش بریم، پس تمامی کدهایی که قرار میدم با زبان کاتلین هستش.

اول از همه نیاز داریم یک متغیری از جنس ExoPlayer تعریف کنیم و به پلیر اصلی خودمون دسترسی داشته باشیم.

برای این منظور من این متغیر رو به صورت جهانی یا Global تعریف کردم که توی fun های دیگه هم بتونم بهش دسترسی داشته باشم.

private var exoPlayer: ExoPlayer? = null
نکته
حتما null رو برای متغیر درنظر بگیر، چون قراره که جلوتر این متغیر رو مقداردهی کنیم.

بعد از تعریف کردن متغیر، باید مقدار دهی بشه.

برای مقداردهی کردن متغیری که بالاتر تعریف کردیم میتونی از کد زیر استفاده کنی.

exoPlayer = ExoPlayer.Builder(this).build()

از کدش هم کاملا مشخصه، از متد Builder استفاده میکنیم و در ورودی هم context رو براش ارسال میکنیم تا متغیرمون رو مقدار دهی کنیم.

الان باید view ای که توی xml تعریف کردیم رو به متغیر خودمون متصل کنیم.

توی XML یک view از نوع PlayerView ساختیم و آیدی اون رو هم myPlayer قرار دادیم.

باید این پلیر رو به کمک exoplayer مقدار دهی کنیم و برای اینکار من از کد زیر استفاده کردم.

binding.myPlayer.player = exoPlayer

متغیری که بالاتر تعریف کردیم و به کمک متد player به ویو خودمون یعنی myPlayer میدیم.

به این صورت ویو ما هم مقداردهی میشه و میتونیم ازش استفاده کنیم.

نمایش ویدیو به کمک ExoPlayer

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

برای پخش کردن ویدیو شما نیاز به لینک ویدیو داری، حالا این لینک میتونه از سمت سرور دریافت بشه یا خودت دستی قرار بدی و پخشش کنی.

مهم اینه که لینک ویدیو رو داشته باشی.

من لینک یک ویدیوای رو داخل پروژه خودم قرار دادم و از اون استفاده کردم.

شماهم برای تست میتونی از این لینک استفاده کنی.

val url = "https://download.samplelib.com/mp4/sample-20s.mp4"

توی این مرحله نیازه که تنظیمات اصلی رو اعمال کنیم تا بتونیم ویدیو رو پخش کنیم.

برای اینکار میتونی از کد زیر استفاده کنی:

val mediaItem: MediaItem = MediaItem.fromUri(url)
        exoPlayer?.let { player ->
            player.setMediaSource(mediaSource)
            player.prepare()
            player.play()
        }

توسط کد بالا اول از همه به کمک MediaItem آدرس فایل ویدیوای که داخل پروژه قرار دادیم رو برای پخش آماده میکنیم.

سپس تنظیمات پخش ویدیو رو روی متغیر exoPlayer اعمال میکنیم و در مرحله بعد توسط prepare فایل ویدیوای رو آماده پخش میکنیم و درنهایت به کمک play ویدیو مورد نظر رو پخشش میکنیم.

اگر برنامه رو اجرا کنی و دسترسی به اینترنت رو در manifest پروژه دادی باشه، بعد از اجرا شدن برنامه ویدیو به صورت خودکار پخش خواهد شد.

تغییرات ظاهری در ExoPlayer

توسط کدهای بالا ما به ساده ترین شکل تونستیم ویدیو موردنظرمون رو پخش کنیم.

ولی خب ظاهر پلیر آنچنان که باید جذاب نیستش، میخوام بهتون یاد بدم که چطور میتونید ظاهرش رو جذابتر بکنید.

بجای کد بالا که توی XML اضافه کردی، میتونی از کد زیر استفاده کنی.

<com.google.android.exoplayer2.ui.StyledPlayerView
    android:id="@+id/player"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:animation_enabled="true"
    app:resize_mode="fit"
    app:use_controller="true" />

این کد هم مثل حالت قبل هستش، ولی ظاهر حرفه ای تره داره.

توضیحات نام خصوصیت
فعال کردن انیمیشن های مربوط به پلیر app:animation_enabled
مقیاس بندی اندازه ویدیو app:resize_mode
نمایش کنترلرها روی پلیر app:use_controller

بعد از انجام دادن مراحل بالا، خروجی کار تقریبا مشابه حالت زیر میشه:

exoplayer_android_play_video_nouri_academy

البته من از یک ویدیو دیگه ای برای نمایش استفاده کردم.

اگر تنظیمات خاصی روی نمایش ویدیو نمیخوای اعمال کنی، تقریبا کار تمومه و دیگه نمیخواد بقیه مقاله رو پیش ببری.

ولی اگر میخوای سیستم Cache (کَش) رو هم انجام بدی حتما با ادامه مقاله با هم همراه باش.

فعال سازی Cache (کَش) کردن ویدیو در ExoPlayer

کَش کردن ویدیو واقعا جز یکی از اصلی ترین بخش هایی هستش که هنگام پخش ویدیو بهش نیاز داری.

اصلا کَش کردن در ویدیو یعنی چی؟

زمانی که سیستم کَش کردن رو فعال میکنی، تا جایی که اینترنت کاربر ویدیو رو دانلود کرده اون رو توی حافظه خودش نگه میده.

اگر مجددا کاربر وارد اون ویدیو بشه، یا حتی اینترنتش رو هم قطع کنه خیلی راحت میتونه ویدیو موردنظر شما رو ببینه.

چون ویدیو در کَش دستگاه ذخیره شده.

برای اینکار باید تنظیمات کَش رو در کلاس Application انجام بدیم.

ساختن کلاس Application برای فعال سازی کَش

اول از همه باید یک کلاس از نوع application درست کنیم و تنظیمات زیر رو داخل قرار بدیم.

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()

        leastRecentlyUsedCacheEvictor = LeastRecentlyUsedCacheEvictor(exoCacheSize)
        standaloneDatabaseProvider = StandaloneDatabaseProvider(this)
        simpleCache = SimpleCache(
            File(this.cacheDir, "media"),
            leastRecentlyUsedCacheEvictor,
            standaloneDatabaseProvider
        )
    }

    companion object {
        lateinit var simpleCache: SimpleCache
        lateinit var leastRecentlyUsedCacheEvictor: LeastRecentlyUsedCacheEvictor
        lateinit var standaloneDatabaseProvider: StandaloneDatabaseProvider
        private const val exoCacheSize: Long = 100 * 1024 * 1024
    }
}

بعد از اینکه این کلاس رو تعریف کردی، باید داخل manifest به عنوان name بهش دسترسی بدی.

مثل کد زیر:

<application
    android:name=".utils.MyApp"

توی کد بالا من 100مگابایت رو برای کَش کردن ویدیو درنظر گرفتم که خیلی راحت میتونی این عدد رو با توجه به نیازت تغییر بدی.

ولی سعی کن دیگه عدد خیلی بزرگی رو ندی.

برای اینکار میتونی مقدار 100 رو در متغیر exoCacheSize تغییر بدی.

بعد از انجام دادن این کارها نیازه که کَش رو به ExoPlayer معرفی کنیم.

برای اینکار وارد کدهای اکتیویتی که بالاتر ازش استفاده کرده بودیم میشیم و به شکل زیر تغییرش میدیم.

//Cache
val mediaSource = ProgressiveMediaSource.Factory(
    CacheDataSource.Factory()
        .setCache(MyApp.simpleCache)
        .setUpstreamDataSourceFactory(
            DefaultHttpDataSource.Factory()
                .setUserAgent("ExoPlayer")
        )
        .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
).createMediaSource(MediaItem.fromUri(url))

//Play
val mediaItem: MediaItem = MediaItem.fromUri(url)
exoPlayer?.let { player ->
    player.setMediaSource(mediaSource)
    player.prepare()
    player.play()
}

اینسری دیگه بجای setMediaItem از setMediaSource استفاده میکنیم.

زمانی که کَش رو فعال میکنی بهتره که این 2 خط رو هم به XML مربوط به اگزوپلیر اضافه کنی.

app:show_buffering="when_playing"
app:surface_type="texture_view"

برای نمایش loading روی ویدیو هستش که کاربر متوجه درحال بارگذاری شدن ویدیو باشه.

اگر کدهای بالا رو به درستی انجام داده باشی ویدیو بدون هیچ مشکلی مثل حالت زیر اجرا میشه.

exoplayer_android_video_speed_nouri_academy

اگر توجه کنی پایین ویدیو یک نوار خاکستری رنگ وجود داره که مقدار کَش شده رو نشون میده.

توی اگزوپلیر کاربر خیلی راحت میتونه سرعت پخش ویدیو رو هم دستی کنترل کنه، فقط کافیه از دکمه تنظیمات روی ویدیو گزینه Speed رو انتخاب کنه.

بستن ExoPlayer

زمانی که میخوای از صفحه خارج بشی حتما حتما باید اگزوپلیر رو از رَم خارج کنی.

اگر اینکار رو نکنی، حتی زمانی که کاربر از صفحه مربوط به پلیر هم خارج بشه ویدیو اون پشت پخش میشه.

هم باعث اذیت شدن کاربر میشه و هم اینکه باعث میشه اپلیکیشنت حافظه کم بیاره و بسته بشه.

برای اینکار هم میتونی از کد زیر استفاده کنی:

override fun onDestroy() {
    super.onDestroy()
    if (exoPlayer != null)
        exoPlayer!!.release()
}

کد کامل صفحه PlayerActivity

کد کامل صفحه رو هم قرار میدم که راحتتر بتونی کدهای خودت رو با چیزی که بالاتر توضیح دادم و خودم زدم مقایسه کنی.

class PlayerActivity : BaseActivity() {
    //Binding
    private var _binding: ActivityPlayerBinding? = null
    private val binding get() = _binding!!

    //Other
    val url = "https://download.samplelib.com/mp4/sample-20s.mp4"
    private var exoPlayer: ExoPlayer? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        _binding = ActivityPlayerBinding.inflate(layoutInflater)
        //Full screen
        @Suppress("DEPRECATION")
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
        setContentView(binding.root)
        //Play video
    playVideo(videoId)
    }

    private fun playVideo() {
        exoPlayer = ExoPlayer.Builder(this).build()
        binding.player.player = exoPlayer
        //Cache
        // Creating the media source for streaming through HTTP
        val mediaSource = ProgressiveMediaSource.Factory(
            CacheDataSource.Factory()
                .setCache(MyApp.simpleCache)
                .setUpstreamDataSourceFactory(
                    DefaultHttpDataSource.Factory()
                        .setUserAgent("ExoPlayer")
                )
                .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
        ).createMediaSource(MediaItem.fromUri(url))
        //Play
        val mediaItem: MediaItem = MediaItem.fromUri(url)
        exoPlayer?.let { player ->
            //player.setMediaItem(mediaItem)
            player.setMediaSource(mediaSource)
            player.prepare()
            player.play()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (exoPlayer != null)
            exoPlayer!!.release()
    }
}

امیدوارم که این آموزش هم برای مفید باشه و تونسته باشی که با ExoPlayer کار کنی.

اگر آموزش خاصی مدنظرت هست توی کامنت ها بنویس که قرار بدم.

دیدگاه‌ها ۰
ارسال دیدگاه جدید