Skip to content

Instantly share code, notes, and snippets.

@ithustle
Last active October 24, 2022 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ithustle/dd979f1bd253aebb6f77b59124ae0d6f to your computer and use it in GitHub Desktop.
Save ithustle/dd979f1bd253aebb6f77b59124ae0d6f to your computer and use it in GitHub Desktop.
Play with ExoPlayer / Caching / HLS
package com.toquemedialabs.crossaudio
import android.annotation.SuppressLint
import android.net.Uri
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.google.android.exoplayer2.upstream.cache.*
import okhttp3.OkHttpClient
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
class MainActivity : AppCompatActivity() {
private lateinit var simpleCache: SimpleCache
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val playButton = findViewById<Button>(R.id.button)
val clear = findViewById<Button>(R.id.button2)
val evictor = LeastRecentlyUsedCacheEvictor((50 * 1024 * 1024).toLong())
val databaseProvider = StandaloneDatabaseProvider(this)
simpleCache = SimpleCache(File(cacheDir, "media"), evictor, databaseProvider)
clear.setOnClickListener {
simpleCache.release()
Toast.makeText(this, "Cache limpo", Toast.LENGTH_LONG).show()
}
playButton.setOnClickListener {
Toast.makeText(this, "Playing", Toast.LENGTH_LONG).show()
val hlsUri1 = Uri.parse("https://....m3u8")
val hlsUri2 = Uri.parse("https://...m3u8")
val hlsUri3 = Uri.parse("https://....m3u8")
val audios = ArrayList<Uri>()
val queue = LinkedList<MediaSource>()
audios.add(hlsUri1)
audios.add(hlsUri2)
audios.add(hlsUri3)
val ms = audios.map { getMediaSourceFromAudioItem(it) }
queue.addAll(ms)
val player = ExoPlayer.Builder(this).build()
player.addMediaSources(queue)
player.playWhenReady = true
player.prepare()
}
}
private fun getMediaSourceFromAudioItem(audioItem: Uri): HlsMediaSource {
//val defaultBandwidthMeter = DefaultBandwidthMeter.Builder(this)
val userAgent = System.getProperty("http.agent")
val builder = OkHttpClient.Builder()
val client = builder.build()
val okHttpDataSourceFactory = OkHttpDataSource.Factory(client)
.setUserAgent(userAgent)
val cache = CacheDataSource.Factory()
.setCache(simpleCache)
.setUpstreamDataSourceFactory(okHttpDataSourceFactory)
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE or CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
val mediaItem = getMediaItemFromAudioItem(audioItem)
return HlsMediaSource.Factory(cache)
.setStreamKeys(cacheStreamKeys)
.setAllowChunklessPreparation(true)
.createMediaSource(mediaItem)
}
private fun getMediaItemFromAudioItem(audioItem: Uri): MediaItem {
return MediaItem.Builder().setUri(audioItem).build()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment