video: support direct playback

pull/653/merge
Varun Patil 2023-05-23 19:57:01 -07:00
parent 79aecab377
commit e5745d0c05
2 changed files with 55 additions and 27 deletions

View File

@ -14,12 +14,15 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.common.util.Util
import androidx.media3.datasource.DefaultDataSource
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.hls.HlsMediaSource
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import gallery.memories.databinding.ActivityMainBinding
@UnstableApi class MainActivity : AppCompatActivity() {
@ -30,7 +33,7 @@ import gallery.memories.databinding.ActivityMainBinding
private lateinit var nativex: NativeX
private var player: ExoPlayer? = null
private var playerUri: Uri? = null
private var playerUris: Array<Uri>? = null
private var playerUid: String? = null
private var playWhenReady = true
private var mediaItemIndex = 0
@ -72,8 +75,8 @@ import gallery.memories.databinding.ActivityMainBinding
public override fun onResume() {
super.onResume()
if (playerUri != null && (Util.SDK_INT <= 23 || player == null)) {
initializePlayer(playerUri!!, playerUid!!)
if (playerUris != null && (Util.SDK_INT <= 23 || player == null)) {
initializePlayer(playerUris!!, playerUid!!)
}
if (mNeedRefresh) {
refreshTimeline(true)
@ -212,7 +215,7 @@ import gallery.memories.databinding.ActivityMainBinding
requestPermissionLauncher.launch(android.Manifest.permission.READ_EXTERNAL_STORAGE)
}
fun initializePlayer(uri: Uri, uid: String) {
fun initializePlayer(uris: Array<Uri>, uid: String) {
if (player != null) {
if (playerUid.equals(uid)) return
player?.release()
@ -220,20 +223,9 @@ import gallery.memories.databinding.ActivityMainBinding
}
// Prevent re-creating
playerUri = uri
playerUris = uris
playerUid = uid
// Add cookies from webview to data source
val cookies = CookieManager.getInstance().getCookie(uri.toString())
val httpDataSourceFactory =
DefaultHttpDataSource.Factory()
.setDefaultRequestProperties(mapOf("cookie" to cookies))
.setAllowCrossProtocolRedirects(true)
val dataSourceFactory = DefaultDataSource.Factory(this, httpDataSourceFactory)
// Create media item from local or remote uri
val mediaItem = MediaItem.fromUri(uri)
// Build exoplayer
player = ExoPlayer.Builder(this)
.build()
@ -244,13 +236,43 @@ import gallery.memories.databinding.ActivityMainBinding
binding.videoView.setShowNextButton(false)
binding.videoView.setShowPreviousButton(false)
for (uri in uris) {
// Create media item from URI
val mediaItem = MediaItem.fromUri(uri)
// Check if remote or local URI
if (uri.toString().contains("http")) {
// Add cookies from webview to data source
val cookies = CookieManager.getInstance().getCookie(uri.toString())
val httpDataSourceFactory =
DefaultHttpDataSource.Factory()
.setDefaultRequestProperties(mapOf("cookie" to cookies))
.setAllowCrossProtocolRedirects(true)
val dataSourceFactory = DefaultDataSource.Factory(this, httpDataSourceFactory)
// Check if HLS source from URI (contains .m3u8 anywhere)
exoPlayer.addMediaSource(
if (uri.toString().contains(".m3u8")) {
exoPlayer.addMediaSource(HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem))
HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem)
} else {
ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem)
}
)
} else {
exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition)
}
}
// Catch errors and fall back to other sources
exoPlayer.addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
exoPlayer.seekToNext()
exoPlayer.playWhenReady = true
exoPlayer.play()
}
})
// Start the player
exoPlayer.playWhenReady = playWhenReady
@ -266,7 +288,7 @@ import gallery.memories.databinding.ActivityMainBinding
playWhenReady = true
mediaItemIndex = 0
playbackPosition = 0L
playerUri = null
playerUris = null
playerUid = null
}
}

View File

@ -13,6 +13,7 @@ import gallery.memories.service.AccountService
import gallery.memories.service.DownloadService
import gallery.memories.service.ImageService
import gallery.memories.service.TimelineQuery
import org.json.JSONArray
import java.io.ByteArrayInputStream
import java.net.URLDecoder
@ -155,16 +156,21 @@ import java.net.URLDecoder
// Play with exoplayer
mCtx.runOnUiThread {
mCtx.initializePlayer(video.uri, fileId)
mCtx.initializePlayer(arrayOf(video.uri), fileId)
}
}.start()
}
@JavascriptInterface
fun playVideoHls(fileId: String?, url: String?) {
if (fileId == null || url == null) return
fun playVideoRemote(fileId: String?, urlsArray: String?) {
if (fileId == null || urlsArray == null) return
val urls = JSONArray(urlsArray)
val list = Array(urls.length()) {
Uri.parse(urls.getString(it))
}
mCtx.runOnUiThread {
mCtx.initializePlayer(Uri.parse(url), fileId)
mCtx.initializePlayer(list, fileId)
}
}