Browse Source

Implement new seek API

pipelines/135724
Nicolas Pomepuy 5 years ago
parent
commit
3b739ff90b
  1. 6
      application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt
  2. 8
      application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt
  3. 29
      application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
  4. 24
      application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
  5. 2
      application/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.kt
  6. 2
      application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt
  7. 2
      application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt
  8. 16
      application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
  9. 2
      application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerOverlayDelegate.kt
  10. 6
      application/vlc-android/src/org/videolan/vlc/gui/video/VideoTouchDelegate.kt
  11. 8
      application/vlc-android/src/org/videolan/vlc/media/PlayerController.kt
  12. 2
      application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt
  13. 2
      application/vlc-android/src/org/videolan/vlc/viewmodels/BookmarkModel.kt
  14. 12
      application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt

6
application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt

@ -135,7 +135,7 @@ class AudioPlayerActivity : BaseTvActivity() {
override fun onProgressChanged(sb: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
model.time = progress.toLong()
model.setTime(progress.toLong())
}
}
}
@ -273,9 +273,9 @@ class AudioPlayerActivity : BaseTvActivity() {
}
private fun seek(delta: Int) {
val time = model.time.toInt() + delta
val time = model.getTime().toInt() + delta
if (time < 0 || time > model.length) return
model.time = time.toLong()
model.setTime(time.toLong())
}
fun onClick(v: View) {

8
application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt

@ -229,7 +229,7 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
override fun onPlayFromUri(uri: Uri?, extras: Bundle?) = playbackService.loadUri(uri)
override fun onPlayFromSearch(query: String?, extras: Bundle?) {
playbackService.mediaSession.setPlaybackState(PlaybackStateCompat.Builder().setState(PlaybackStateCompat.STATE_CONNECTING, playbackService.time, 1.0f).build())
playbackService.mediaSession.setPlaybackState(PlaybackStateCompat.Builder().setState(PlaybackStateCompat.STATE_CONNECTING, playbackService.getTime(), 1.0f).build())
playbackService.lifecycleScope.launch(Dispatchers.IO) {
if (!isActive) return@launch
playbackService.awaitMedialibraryStarted()
@ -273,11 +273,11 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
override fun onSkipToPrevious() = playbackService.previous(false)
override fun onSeekTo(pos: Long) = playbackService.seek(if (pos < 0) playbackService.time + pos else pos, fromUser = true)
override fun onSeekTo(pos: Long) = playbackService.seek(if (pos < 0) playbackService.getTime() + pos else pos, fromUser = true)
override fun onFastForward() = playbackService.seek((playbackService.time + TEN_SECONDS).coerceAtMost(playbackService.length), fromUser = true)
override fun onFastForward() = playbackService.seek((playbackService.getTime() + TEN_SECONDS).coerceAtMost(playbackService.length), fromUser = true)
override fun onRewind() = playbackService.seek((playbackService.time - TEN_SECONDS).coerceAtLeast(0), fromUser = true)
override fun onRewind() = playbackService.seek((playbackService.getTime() - TEN_SECONDS).coerceAtLeast(0), fromUser = true)
override fun onSkipToQueueItem(id: Long) = playbackService.playIndexOrLoadLastPlaylist(id.toInt())
}

29
application/vlc-android/src/org/videolan/vlc/PlaybackService.kt

@ -176,7 +176,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
if (BuildConfig.DEBUG) Log.i(TAG, "MediaPlayer.Event.Playing")
executeUpdate()
publishState()
lastTime = time
lastTime = getTime()
audioFocusHelper.changeAudioFocus(true)
if (!wakeLock.isHeld) wakeLock.acquire()
showNotification()
@ -198,8 +198,8 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
}
MediaPlayer.Event.PositionChanged -> {
if (length == 0L) position = (NO_LENGTH_PROGRESS_MAX.toLong() * event.positionChanged).toLong()
if (time < 1000L && time < lastTime) publishState()
lastTime = time
if (getTime() < 1000L && getTime() < lastTime) publishState()
lastTime = getTime()
if (widget != 0) updateWidgetPosition(event.positionChanged)
}
MediaPlayer.Event.ESAdded -> if (event.esChangedType == IMedia.Track.Type.Video && (playlistManager.videoBackground || !playlistManager.switchToVideo())) {
@ -384,15 +384,6 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
return tracks.toList()
}
var time: Long
@MainThread
get() = playlistManager.player.getCurrentTime()
@MainThread
set(time) {
playlistManager.player.setTime(time)
publishState(time)
}
val length: Long
@MainThread
get() = playlistManager.player.getLength()
@ -711,6 +702,12 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
playlistManager.isHardware = true
}
fun setTime(time:Long, fast:Boolean = false) {
playlistManager.player.setTime(time, fast)
}
fun getTime() = playlistManager.player.getCurrentTime()
fun onMediaPlayerEvent(event: MediaPlayer.Event) = mediaPlayerListener.onEvent(event)
fun onPlaybackStopped(systemExit: Boolean) {
@ -951,7 +948,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
val pscb = PlaybackStateCompat.Builder()
var actions = PLAYBACK_BASE_ACTIONS
val hasMedia = playlistManager.hasCurrentMedia()
var time = position ?: time
var time = position ?: getTime()
var state = PlayerController.playbackState
when (state) {
PlaybackStateCompat.STATE_PLAYING -> actions = actions or (PlaybackStateCompat.ACTION_PAUSE or PlaybackStateCompat.ACTION_STOP)
@ -1294,7 +1291,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
/* HACK: flush when activating a video track. This will force an
* I-Frame to be displayed right away. */
if (isSeekable) {
val time = time
val time = getTime()
if (time > 0)
seek(time)
}
@ -1418,8 +1415,8 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
@MainThread
@JvmOverloads
fun seek(time: Long, length: Double = this.length.toDouble(), fromUser: Boolean = false) {
if (length > 0.0) this.time = time else setPosition((time.toFloat() / NO_LENGTH_PROGRESS_MAX.toFloat()))
fun seek(time: Long, length: Double = this.length.toDouble(), fromUser: Boolean = false, fast:Boolean = false) {
if (length > 0.0) this.setTime(time, fast) else setPosition((time.toFloat() / NO_LENGTH_PROGRESS_MAX.toFloat()))
if (fromUser) {
publishState(time)
}

24
application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt

@ -109,6 +109,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
lateinit var abRepeatAddMarker: Button
private var audioPlayProgressMode:Boolean = false
private var lastEndsAt = -1L
private var isDragging = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -369,7 +370,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
val displayTime = if (showRemainingTime) Tools.millisToString(progress.time - progress.length) else progress.timeText
binding.headerTime.text = displayTime
binding.time.text = displayTime
binding.timeline.progress = progress.time.toInt()
if (!isDragging) binding.timeline.progress = progress.time.toInt()
binding.progressBar.progress = progress.time.toInt()
}
@ -432,18 +433,18 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
fun onRewind10(view: View) {
playlistModel.service ?.let { service ->
var position = service.time - 10000
var position = service.getTime() - 10000
if (position < 0) position = 0
if (position > service.length) position = service.length
service.seek(position, service.length.toDouble(), true)
if (service.playlistManager.player.lastPosition == 0.0f && service.time > 0)
if (service.playlistManager.player.lastPosition == 0.0f && service.getTime() > 0)
UiTools.snacker(requireActivity(), getString(R.string.unseekable_stream))
}
}
fun onForward10(view: View) {
playlistModel.service ?.let { service ->
var position = service.time + 10000
var position = service.getTime() + 10000
if (position < 0) position = 0
if (position > service.length) position = service.length
service.seek(position, service.length.toDouble(), true)
@ -624,7 +625,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
override fun onTouch(v: View, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
possibleSeek = playlistModel.time.toInt()
possibleSeek = playlistModel.getTime().toInt()
previewingSeek = true
vibrated = false
length = playlistModel.length
@ -636,7 +637,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
handler.removeCallbacks(seekRunnable)
previewingSeek = false
if (event.eventTime - event.downTime >= 1000L) {
playlistModel.time = possibleSeek.toLong().coerceAtLeast(0L).coerceAtMost(playlistModel.length)
playlistModel.setTime(possibleSeek.toLong().coerceAtLeast(0L).coerceAtMost(playlistModel.length))
v.isPressed = false
return true
}
@ -669,13 +670,18 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
private var timelineListener: OnSeekBarChangeListener = object : OnSeekBarChangeListener {
override fun onStopTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {
playlistModel.setTime(seekBar.progress.toLong())
isDragging = false
}
override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStartTrackingTouch(seekBar: SeekBar) {
isDragging = true
}
override fun onProgressChanged(sb: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
playlistModel.time = progress.toLong()
playlistModel.setTime(progress.toLong(), true)
binding.time.text = Tools.millisToString(if (showRemainingTime) progress - playlistModel.length else progress.toLong())
binding.headerTime.text = Tools.millisToString(progress.toLong())
}

2
application/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.kt

@ -38,7 +38,7 @@ class JumpToTimeDialog : PickTimeFragment() {
val minutes = if (minutes != "") java.lang.Long.parseLong(minutes) * MINUTES_IN_MICROS else 0L
val seconds = if (seconds != "") java.lang.Long.parseLong(seconds) * SECONDS_IN_MICROS else 0L
val newTime = (hours + minutes + seconds) / 1000L //Time in ms
playbackService.time = newTime
playbackService.setTime(newTime)
playbackService.playlistManager.player.updateProgress(newTime)
dismiss()
}

2
application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt

@ -155,7 +155,7 @@ class BookmarkListDelegate(val activity: FragmentActivity, val service: Playback
}
override fun onBookmarkClick(position: Int, item: Bookmark) {
service.time = item.time
service.setTime(item.time)
}
fun setProgressHeight(y: Float) {

2
application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt

@ -229,7 +229,7 @@ class PopupManager constructor(private val service: PlaybackService) : PlaybackS
}
private fun stopPlayback() {
var time = service.time
var time = service.getTime()
if (time != -1L) {
// remove saved position if in the last 5 seconds
// else, go back 2 seconds, to compensate loading time

16
application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt

@ -55,7 +55,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.BaseContextWrappingDelegate
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.ViewStubCompat
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.Guideline
@ -268,11 +267,12 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
override fun onStopTrackingTouch(seekBar: SeekBar) {
isDragging = false
overlayDelegate.showOverlay(true)
seek(seekBar.progress.toLong(), fromUser = true, fast = false)
}
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (!isFinishing && fromUser && service?.isSeekable == true) {
seek(progress.toLong(), fromUser)
seek(progress.toLong(), fromUser, isDragging)
if (service?.length != 0L) overlayDelegate.showInfo(Tools.millisToString(progress.toLong()), 1000)
}
if (fromUser) {
@ -298,7 +298,7 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
*/
val time: Long
get() {
var time = service?.time ?: 0L
var time = service?.getTime() ?: 0L
if (forcedTime != -1L && lastTime != -1L) {
if (lastTime > forcedTime) {
if (time in (forcedTime + 1)..lastTime || time > lastTime) {
@ -1595,11 +1595,15 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
service?.let { seek(position, it.length, fromUser) }
}
internal fun seek(position: Long, length: Long, fromUser: Boolean = false) {
fun seek(position: Long, fromUser: Boolean = false, fast:Boolean = false) {
service?.let { seek(position, it.length, fromUser, fast) }
}
internal fun seek(position: Long, length: Long, fromUser: Boolean = false, fast:Boolean = false) {
service?.let { service ->
forcedTime = position
lastTime = service.time
service.seek(position, length.toDouble(), fromUser)
lastTime = service.getTime()
service.seek(position, length.toDouble(), fromUser, fast)
service.playlistManager.player.updateProgress(position)
}
}

2
application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerOverlayDelegate.kt

@ -155,7 +155,7 @@ class VideoPlayerOverlayDelegate (private val player: VideoPlayerActivity) {
}
VideoTracksDialog.TrackType.VIDEO -> {
player.service?.let { service ->
player.seek(service.time)
player.seek(service.getTime())
service.setVideoTrack(trackID)
runIO {
val mw = player.medialibrary.findMedia(service.currentMediaWrapper)

6
application/vlc-android/src/org/videolan/vlc/gui/video/VideoTouchDelegate.kt

@ -317,7 +317,7 @@ class VideoTouchDelegate(private val player: VideoPlayerActivity,
touchAction = TOUCH_SEEK
val length = player.service!!.length
val time = player.service!!.time
val time = player.service!!.getTime()
// Size of the jump, 10 minutes max (600000), with a bi-cubic progression, for a 8cm gesture
var jump = (sign(gesturesize) * (600000 * (gesturesize / 8).toDouble().pow(4.0) + 3000) / coef).toInt()
@ -455,9 +455,9 @@ class VideoTouchDelegate(private val player: VideoPlayerActivity,
nbTimesTaped++
lastSeekWasForward = seekForward
if (service.time > 0 && service.time < service.length) sb.append(if (nbTimesTaped == -1) (delta / 1000f).toInt() else (nbTimesTaped * (delta / 1000f).toInt()))
if (service.getTime() > 0 && service.getTime() < service.length) sb.append(if (nbTimesTaped == -1) (delta / 1000f).toInt() else (nbTimesTaped * (delta / 1000f).toInt()))
.append("s ")
sb.append("(").append(Tools.millisToString(service.time))
sb.append("(").append(Tools.millisToString(service.getTime()))
.append(')')
val container = if (seekForward) player.rightContainer else player.leftContainer

8
application/vlc-android/src/org/videolan/vlc/media/PlayerController.kt

@ -109,16 +109,12 @@ class PlayerController(val context: Context) : IVLCVout.Callback, MediaPlayer.Ev
release(mp)
}
fun seek(time: Long, length: Double = getLength().toDouble()) {
if (length > 0.0) setTime(time) else setPosition((time / NO_LENGTH_PROGRESS_MAX).toFloat())
}
fun setPosition(position: Float) {
if (seekable && mediaplayer.hasMedia() && !mediaplayer.isReleased) mediaplayer.position = position
}
fun setTime(time: Long) {
if (seekable && mediaplayer.hasMedia() && !mediaplayer.isReleased) mediaplayer.time = time
fun setTime(time: Long, fast:Boolean = false) {
if (seekable && mediaplayer.hasMedia() && !mediaplayer.isReleased) mediaplayer.setTime(time, fast)
}
fun isPlaying() = playbackState == PlaybackStateCompat.STATE_PLAYING

2
application/vlc-android/src/org/videolan/vlc/media/PlaylistManager.kt

@ -908,7 +908,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
}
MediaPlayer.Event.TimeChanged -> {
abRepeat.value?.let {
if (it.stop != -1L && player.getCurrentTime() > it.stop) player.seek(it.start)
if (it.stop != -1L && player.getCurrentTime() > it.stop) player.setTime(it.start)
}
if (player.getCurrentTime() % 10 == 0L) savePosition()
}

2
application/vlc-android/src/org/videolan/vlc/viewmodels/BookmarkModel.kt

@ -113,7 +113,7 @@ class BookmarkModel : ViewModel(), PlaybackService.Callback {
service?.currentMediaWrapper?.let {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val bookmark = it.addBookmark(service!!.time)
val bookmark = it.addBookmark(service!!.getTime())
bookmark?.setName(context.getString(R.string.bookmark_name, it.bookmarks.size.toString()))
}
refresh()

12
application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt

@ -154,12 +154,6 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
} else false
} ?: false
var time
get() = service?.time ?: 0L
set(value) {
service?.time = value
}
val length : Long
get() = service?.length ?: 0L
@ -192,6 +186,12 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
fun shuffle() = service?.shuffle()
fun getTime() = service?.getTime() ?: 0L
fun setTime(time:Long, fast:Boolean = false) {
service?.setTime(time, fast)
}
fun load(medialist: List<MediaWrapper>, position: Int) = service?.load(medialist, position)
suspend fun switchToVideo() : Boolean {

Loading…
Cancel
Save