|
@@ -16,7 +16,15 @@ class MoviePlayerV2 {
|
|
|
fun onMoviePlayComplete()
|
|
|
}
|
|
|
|
|
|
+ interface OnGifPlayListener {
|
|
|
+ fun onGifStart()
|
|
|
+ fun onGifSeek(time: Int)
|
|
|
+ fun onGifPause()
|
|
|
+ fun onGifUpdate(time: Int)
|
|
|
+ }
|
|
|
+
|
|
|
var moviePlayListener: OnMoviePlayListener? = null
|
|
|
+ var gifPlayListener: OnGifPlayListener? = null
|
|
|
|
|
|
var story: Story? = null
|
|
|
|
|
@@ -44,7 +52,7 @@ class MoviePlayerV2 {
|
|
|
|
|
|
currentTime = 0
|
|
|
|
|
|
- updateMovie()
|
|
|
+ updateMovie(true)
|
|
|
|
|
|
tryStopRecord()
|
|
|
|
|
@@ -54,16 +62,19 @@ class MoviePlayerV2 {
|
|
|
|
|
|
initMediaPlayer()
|
|
|
|
|
|
+ gifPlayListener?.onGifPause()
|
|
|
}
|
|
|
|
|
|
fun start() {
|
|
|
if (timer == null) {
|
|
|
+ var time = System.nanoTime()
|
|
|
timer = Timer()
|
|
|
timer?.scheduleAtFixedRate(object : TimerTask() {
|
|
|
override fun run() {
|
|
|
+ var now = System.nanoTime()
|
|
|
if (!isPause) {
|
|
|
|
|
|
- currentTime++
|
|
|
+ currentTime = Math.min(period, currentTime + (now - time) / 1000000)
|
|
|
|
|
|
updateMovie()
|
|
|
|
|
@@ -76,11 +87,14 @@ class MoviePlayerV2 {
|
|
|
init()
|
|
|
}
|
|
|
}
|
|
|
+ time = now
|
|
|
}
|
|
|
- }, 0, 1)
|
|
|
+ }, 0, 20)
|
|
|
} else {
|
|
|
isPause = false
|
|
|
+ updateMovie(true)
|
|
|
}
|
|
|
+ gifPlayListener?.onGifStart()
|
|
|
}
|
|
|
|
|
|
fun pause() {
|
|
@@ -89,31 +103,109 @@ class MoviePlayerV2 {
|
|
|
tryPauseRecord()
|
|
|
|
|
|
tryPauseMusic()
|
|
|
+
|
|
|
+ gifPlayListener?.onGifPause()
|
|
|
}
|
|
|
|
|
|
fun seekTo(currentTime: Long) {
|
|
|
this.currentTime = currentTime
|
|
|
|
|
|
- updateMovie()
|
|
|
+ updateMovie(true)
|
|
|
|
|
|
trySeekRecord()
|
|
|
|
|
|
trySeekMusic()
|
|
|
}
|
|
|
|
|
|
- private fun updateMovie() {
|
|
|
- val scene = getScene(currentTime)
|
|
|
- scene?.apply {
|
|
|
+ private var startPeriodCache = 0L
|
|
|
+ private var endPeriodCache = 0L
|
|
|
+ private var targetScene: Scene? = null
|
|
|
+ private var previousTrackIndex = -1
|
|
|
+ private var currentTrackIndex = -1
|
|
|
+
|
|
|
+ private fun updateMovie(seek: Boolean = false) {
|
|
|
+ if (currentTime < startPeriodCache || currentTime >= endPeriodCache) {
|
|
|
+ targetScene = null
|
|
|
+ var startPeriod = 0L
|
|
|
+ var endPeriod = 0L
|
|
|
+ story?.apply {
|
|
|
+ for (scene in scenes) {
|
|
|
+ scene.record?.apply {
|
|
|
+ endPeriod += period
|
|
|
+ if (currentTime in (endPeriod - period)..endPeriod) {
|
|
|
+ targetScene = scene
|
|
|
+ startPeriod = endPeriod - period
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (targetScene != null)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ startPeriodCache = startPeriod
|
|
|
+ endPeriodCache = endPeriod
|
|
|
+ previousTrackIndex = -1
|
|
|
+ currentTrackIndex = -1
|
|
|
+ }
|
|
|
+
|
|
|
+ val currentTimeInScene = currentTime - startPeriodCache
|
|
|
+ targetScene?.apply {
|
|
|
moviePlayListener?.onMovieSceneUpdate(this)
|
|
|
record?.let {
|
|
|
- for (track in it.tracks) {
|
|
|
- if (track.time == currentTime) {
|
|
|
- moviePlayListener?.onMoviePlayViewUpdate(track.positionX)
|
|
|
+ if (it.tracks == null || it.tracks.size == 0) {
|
|
|
+ moviePlayListener?.onMoviePlayViewUpdate(0)
|
|
|
+ return@let
|
|
|
+ }
|
|
|
+ if (currentTimeInScene < it.tracks[0].time) {
|
|
|
+ moviePlayListener?.onMoviePlayViewUpdate(0)
|
|
|
+ return@let
|
|
|
+ }
|
|
|
+ if (currentTimeInScene >= it.tracks[it.tracks.size - 1].time) {
|
|
|
+ moviePlayListener?.onMoviePlayViewUpdate(it.tracks[it.tracks.size - 1].positionX)
|
|
|
+ return@let
|
|
|
+ }
|
|
|
+
|
|
|
+ var startIndex = 1
|
|
|
+ var endIndex = it.tracks.size
|
|
|
+ var hitCache = true
|
|
|
+ if (currentTrackIndex > 0) {
|
|
|
+ if (currentTimeInScene < it.tracks[previousTrackIndex].time) {
|
|
|
+ endIndex = previousTrackIndex
|
|
|
+ hitCache = false
|
|
|
+ } else if (currentTimeInScene > it.tracks[currentTrackIndex].time) {
|
|
|
+ startIndex = Math.max(1, currentTrackIndex - 1)
|
|
|
+ hitCache = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ hitCache = false
|
|
|
+ }
|
|
|
+ if (!hitCache) {
|
|
|
+ previousTrackIndex = Math.max(0, startIndex)
|
|
|
+ currentTrackIndex = Math.min(it.tracks.size - 1, endIndex)
|
|
|
+ for (i in startIndex until endIndex) {
|
|
|
+ if (currentTimeInScene in (it.tracks[i - 1].time .. it.tracks[i].time)) {
|
|
|
+ previousTrackIndex = i - 1
|
|
|
+ currentTrackIndex = i
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ val previousTrack = it.tracks[previousTrackIndex]
|
|
|
+ val track = it.tracks[currentTrackIndex]
|
|
|
+ val positionX = previousTrack.positionX + (track.positionX - previousTrack.positionX) * (currentTimeInScene - previousTrack.time) / Math.max(1, track.time - previousTrack.time)
|
|
|
+ moviePlayListener?.onMoviePlayViewUpdate(positionX.toInt())
|
|
|
}
|
|
|
}
|
|
|
moviePlayListener?.onMoviePlayTimeUpdate(currentTime)
|
|
|
+ if (seek) {
|
|
|
+ if (timer == null || isPause) {
|
|
|
+ gifPlayListener?.onGifUpdate(currentTimeInScene.toInt())
|
|
|
+ gifPlayListener?.onGifPause()
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ gifPlayListener?.onGifSeek(currentTimeInScene.toInt())
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private fun getScene(t: Long): Scene? {
|