video: support direct playback
parent
79aecab377
commit
e5745d0c05
|
@ -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,14 +236,44 @@ import gallery.memories.databinding.ActivityMainBinding
|
|||
binding.videoView.setShowNextButton(false)
|
||||
binding.videoView.setShowPreviousButton(false)
|
||||
|
||||
// Check if HLS source from URI (contains .m3u8 anywhere)
|
||||
if (uri.toString().contains(".m3u8")) {
|
||||
exoPlayer.addMediaSource(HlsMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(mediaItem))
|
||||
} else {
|
||||
exoPlayer.setMediaItems(listOf(mediaItem), mediaItemIndex, playbackPosition)
|
||||
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")) {
|
||||
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
|
||||
exoPlayer.prepare()
|
||||
|
@ -266,7 +288,7 @@ import gallery.memories.databinding.ActivityMainBinding
|
|||
playWhenReady = true
|
||||
mediaItemIndex = 0
|
||||
playbackPosition = 0L
|
||||
playerUri = null
|
||||
playerUris = null
|
||||
playerUid = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue