From 39c73755b45c8999f61f8a0ba83b439576261a82 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Sat, 6 Jan 2024 18:23:02 -0500
Subject: [PATCH 1/4] Add scrub function to audio trickplay bar
---
components/music/AudioPlayerView.bs | 178 ++++++++++++++++++++++++---
components/music/AudioPlayerView.xml | 5 +-
images/icons/circle.png | Bin 0 -> 2429 bytes
3 files changed, 161 insertions(+), 22 deletions(-)
create mode 100644 images/icons/circle.png
diff --git a/components/music/AudioPlayerView.bs b/components/music/AudioPlayerView.bs
index d9c3e1f9..3391395a 100644
--- a/components/music/AudioPlayerView.bs
+++ b/components/music/AudioPlayerView.bs
@@ -5,6 +5,7 @@ import "pkg:/source/utils/config.bs"
sub init()
m.top.optionsAvailable = false
+ m.inScrubMode = false
setupAudioNode()
setupAnimationTasks()
@@ -32,6 +33,8 @@ sub init()
pageContentChanged()
setShuffleIconState()
setLoopButtonImage()
+
+ m.buttons.setFocus(true)
end sub
sub onScreensaverTimeoutLoaded()
@@ -117,6 +120,7 @@ sub setupInfoNodes()
m.playPosition = m.top.findNode("playPosition")
m.bufferPosition = m.top.findNode("bufferPosition")
m.seekBar = m.top.findNode("seekBar")
+ m.thumb = m.top.findNode("thumb")
m.shuffleIndicator = m.top.findNode("shuffleIndicator")
m.loopIndicator = m.top.findNode("loopIndicator")
m.positionTimestamp = m.top.findNode("positionTimestamp")
@@ -124,6 +128,8 @@ sub setupInfoNodes()
end sub
sub bufferPositionChanged()
+ if m.inScrubMode then return
+
if not isValid(m.global.audioPlayer.bufferingStatus)
bufferPositionBarWidth = m.seekBar.width
else
@@ -141,6 +147,10 @@ sub bufferPositionChanged()
end sub
sub audioPositionChanged()
+ if m.inScrubMode then return
+
+ stopLoadingSpinner()
+
if m.global.audioPlayer.position = 0
m.playPosition.width = 0
end if
@@ -159,6 +169,8 @@ sub audioPositionChanged()
playPositionBarWidth = m.seekBar.width
end if
+ moveSeekbarThumb(playPositionBarWidth)
+
' Use animation to make the display smooth
m.playPositionAnimationWidth.keyValue = [m.playPosition.width, playPositionBarWidth]
m.playPositionAnimation.control = "start"
@@ -217,6 +229,7 @@ sub audioStateChanged()
if m.global.audioPlayer.state = "finished"
' User has enabled single song loop, play current song again
if m.global.audioPlayer.loopMode = "one"
+ m.global.audioPlayer.content.playStart = 0
playAction()
return
end if
@@ -255,6 +268,13 @@ function playAction() as boolean
' Write screen tracker for screensaver
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
MoveFile("tmp:/scene.temp", "tmp:/scene")
+ else if m.global.audioPlayer.state = "buffering"
+ m.inScrubMode = false
+ startLoadingSpinner()
+ m.global.audioPlayer.control = "play"
+ ' Write screen tracker for screensaver
+ WriteAsciiFile("tmp:/scene.temp", "nowplaying")
+ MoveFile("tmp:/scene.temp", "tmp:/scene")
end if
return true
@@ -540,6 +560,72 @@ sub setBackdropImage(data)
end if
end sub
+' setSelectedButtonState: Changes the icon state url for the currently selected button
+'
+' @param {string} oldState - current state to replace in icon url
+' @param {string} newState - state to replace {oldState} with in icon url
+sub setSelectedButtonState(oldState as string, newState as string)
+ selectedButton = m.buttons.getChild(m.top.selectedButtonIndex)
+ selectedButton.uri = selectedButton.uri.Replace(oldState, newState)
+end sub
+
+' processScrubAction: Handles +/- seeking for the audio trickplay bar
+'
+' @param {integer} seekStep - seconds to move the trickplay position (negative values allowed)
+sub processScrubAction(seekStep as integer)
+ m.inScrubMode = true
+ ' Change audio player control method
+ m.global.audioPlayer.control = "prebuffer"
+
+ ' Prepare starting playStart property value
+ if m.global.audioPlayer.position <> 0
+ m.global.audioPlayer.content.playStart = m.global.audioPlayer.position
+ end if
+
+ ' Don't let seek to go past the end of the song
+ if m.global.audioPlayer.content.playStart + seekStep > m.songDuration
+ return
+ end if
+
+ if seekStep > 0
+ ' Move seek forward
+ m.global.audioPlayer.content.playStart += seekStep
+ else if m.global.audioPlayer.content.playStart >= Abs(seekStep)
+ ' If back seek won't go below 0, move seek back
+ m.global.audioPlayer.content.playStart += seekStep
+ else
+ ' Back seek would go below 0, set to 0 directly
+ m.global.audioPlayer.content.playStart = 0
+ end if
+
+ ' Move the seedbar thumb forward
+ songPercentComplete = m.global.audioPlayer.content.playStart / m.songDuration
+ playPositionBarWidth = m.seekBar.width * songPercentComplete
+
+ moveSeekbarThumb(playPositionBarWidth)
+
+ ' Change the displayed position timestamp
+ m.positionTimestamp.text = secondsToHuman(m.global.audioPlayer.content.playStart, false)
+end sub
+
+' moveSeekbarThumb: Positions the thumb on the seekbar
+'
+' @param {float} playPositionBarWidth - width of the play position bar
+sub moveSeekbarThumb(playPositionBarWidth as float)
+ ' Center the thumb on the play position bar
+ thumbPostionLeft = playPositionBarWidth - 10
+
+ ' Don't let thumb go below 0
+ if thumbPostionLeft < 0 then thumbPostionLeft = 0
+
+ ' Don't let thumb go past end of seekbar
+ if thumbPostionLeft > m.seekBar.width - 25
+ thumbPostionLeft = m.seekBar.width - 25
+ end if
+
+ m.thumb.translation = [thumbPostionLeft, m.thumb.translation[1]]
+end sub
+
' Process key press events
function onKeyEvent(key as string, press as boolean) as boolean
@@ -551,9 +637,55 @@ function onKeyEvent(key as string, press as boolean) as boolean
return true
end if
+ ' Key Event handler when m.thumb is in focus
+ if m.thumb.hasFocus()
+ if key = "right"
+ processScrubAction(10)
+ return true
+ end if
+
+ if key = "left"
+ processScrubAction(-10)
+ return true
+ end if
+
+ if key = "OK" or key = "play"
+ if m.inScrubMode
+ startLoadingSpinner()
+ m.inScrubMode = false
+ m.global.audioPlayer.control = "play"
+ end if
+ return true
+ end if
+ end if
+
if key = "play"
return playAction()
- else if key = "back"
+ end if
+
+ if key = "up"
+ if not m.thumb.visible
+ m.thumb.visible = true
+ setSelectedButtonState("-selected", "-default")
+ end if
+
+ m.thumb.setFocus(true)
+ m.buttons.setFocus(false)
+ return true
+ end if
+
+ if key = "down"
+ if m.thumb.visible
+ m.thumb.visible = false
+ setSelectedButtonState("-default", "-selected")
+ end if
+
+ m.buttons.setFocus(true)
+ m.thumb.setFocus(false)
+ return true
+ end if
+
+ if key = "back"
m.global.audioPlayer.control = "stop"
m.global.audioPlayer.loopMode = ""
else if key = "rewind"
@@ -561,30 +693,36 @@ function onKeyEvent(key as string, press as boolean) as boolean
else if key = "fastforward"
return nextClicked()
else if key = "left"
- if m.global.queueManager.callFunc("getCount") = 1 then return false
+ if m.buttons.hasFocus()
+ if m.global.queueManager.callFunc("getCount") = 1 then return false
- if m.top.selectedButtonIndex > 0
- m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
- m.top.selectedButtonIndex = m.top.selectedButtonIndex - 1
+ if m.top.selectedButtonIndex > 0
+ m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
+ m.top.selectedButtonIndex = m.top.selectedButtonIndex - 1
+ end if
+ return true
end if
- return true
else if key = "right"
- if m.global.queueManager.callFunc("getCount") = 1 then return false
+ if m.buttons.hasFocus()
+ if m.global.queueManager.callFunc("getCount") = 1 then return false
- m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
- if m.top.selectedButtonIndex < m.buttonCount - 1 then m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
- return true
+ m.previouslySelectedButtonIndex = m.top.selectedButtonIndex
+ if m.top.selectedButtonIndex < m.buttonCount - 1 then m.top.selectedButtonIndex = m.top.selectedButtonIndex + 1
+ return true
+ end if
else if key = "OK"
- if m.buttons.getChild(m.top.selectedButtonIndex).id = "play"
- return playAction()
- else if m.buttons.getChild(m.top.selectedButtonIndex).id = "previous"
- return previousClicked()
- else if m.buttons.getChild(m.top.selectedButtonIndex).id = "next"
- return nextClicked()
- else if m.buttons.getChild(m.top.selectedButtonIndex).id = "shuffle"
- return shuffleClicked()
- else if m.buttons.getChild(m.top.selectedButtonIndex).id = "loop"
- return loopClicked()
+ if m.buttons.hasFocus()
+ if m.buttons.getChild(m.top.selectedButtonIndex).id = "play"
+ return playAction()
+ else if m.buttons.getChild(m.top.selectedButtonIndex).id = "previous"
+ return previousClicked()
+ else if m.buttons.getChild(m.top.selectedButtonIndex).id = "next"
+ return nextClicked()
+ else if m.buttons.getChild(m.top.selectedButtonIndex).id = "shuffle"
+ return shuffleClicked()
+ else if m.buttons.getChild(m.top.selectedButtonIndex).id = "loop"
+ return loopClicked()
+ end if
end if
end if
end if
diff --git a/components/music/AudioPlayerView.xml b/components/music/AudioPlayerView.xml
index 3ef06156..aaa4f03c 100644
--- a/components/music/AudioPlayerView.xml
+++ b/components/music/AudioPlayerView.xml
@@ -4,8 +4,8 @@
-
-
+
+
@@ -16,6 +16,7 @@
+
diff --git a/images/icons/circle.png b/images/icons/circle.png
new file mode 100644
index 0000000000000000000000000000000000000000..3669a4d5521e82ad173a31077d85d548c92e9c91
GIT binary patch
literal 2429
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
literal 0
HcmV?d00001
From 03b2768d58d07c42f979a88cf25c95623522d9af Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Sun, 7 Jan 2024 19:40:01 -0500
Subject: [PATCH 2/4] Rework seek method to reduce buffer
---
components/music/AudioPlayerView.bs | 101 ++++++++++++++++++---------
components/music/AudioPlayerView.xml | 4 ++
2 files changed, 73 insertions(+), 32 deletions(-)
diff --git a/components/music/AudioPlayerView.bs b/components/music/AudioPlayerView.bs
index 3391395a..0579abb5 100644
--- a/components/music/AudioPlayerView.bs
+++ b/components/music/AudioPlayerView.bs
@@ -6,6 +6,8 @@ import "pkg:/source/utils/config.bs"
sub init()
m.top.optionsAvailable = false
m.inScrubMode = false
+ m.lastRecordedPositionTimestamp = 0
+ m.scrubTimestamp = 0
setupAudioNode()
setupAnimationTasks()
@@ -17,6 +19,7 @@ sub init()
m.playlistTypeCount = m.global.queueManager.callFunc("getQueueUniqueTypes").count()
m.buttonCount = m.buttons.getChildCount()
+ m.seekPosition.translation = [720 - (m.seekPosition.width / 2), m.seekPosition.translation[1]]
m.screenSaverTimeout = 300
@@ -124,6 +127,8 @@ sub setupInfoNodes()
m.shuffleIndicator = m.top.findNode("shuffleIndicator")
m.loopIndicator = m.top.findNode("loopIndicator")
m.positionTimestamp = m.top.findNode("positionTimestamp")
+ m.seekPosition = m.top.findNode("seekPosition")
+ m.seekTimestamp = m.top.findNode("seekTimestamp")
m.totalLengthTimestamp = m.top.findNode("totalLengthTimestamp")
end sub
@@ -147,8 +152,6 @@ sub bufferPositionChanged()
end sub
sub audioPositionChanged()
- if m.inScrubMode then return
-
stopLoadingSpinner()
if m.global.audioPlayer.position = 0
@@ -169,7 +172,11 @@ sub audioPositionChanged()
playPositionBarWidth = m.seekBar.width
end if
- moveSeekbarThumb(playPositionBarWidth)
+ if not m.inScrubMode
+ moveSeekbarThumb(playPositionBarWidth)
+ ' Change the seek position timestamp
+ m.seekTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
+ end if
' Use animation to make the display smooth
m.playPositionAnimationWidth.keyValue = [m.playPosition.width, playPositionBarWidth]
@@ -177,8 +184,10 @@ sub audioPositionChanged()
' Update displayed position timestamp
if isValid(m.global.audioPlayer.position)
+ m.lastRecordedPositionTimestamp = m.global.audioPlayer.position
m.positionTimestamp.text = secondsToHuman(m.global.audioPlayer.position, false)
else
+ m.lastRecordedPositionTimestamp = 0
m.positionTimestamp.text = "0:00"
end if
@@ -229,8 +238,9 @@ sub audioStateChanged()
if m.global.audioPlayer.state = "finished"
' User has enabled single song loop, play current song again
if m.global.audioPlayer.loopMode = "one"
- m.global.audioPlayer.content.playStart = 0
+ m.scrubTimestamp = 0
playAction()
+ exitScrubMode()
return
end if
@@ -268,13 +278,6 @@ function playAction() as boolean
' Write screen tracker for screensaver
WriteAsciiFile("tmp:/scene.temp", "nowplaying")
MoveFile("tmp:/scene.temp", "tmp:/scene")
- else if m.global.audioPlayer.state = "buffering"
- m.inScrubMode = false
- startLoadingSpinner()
- m.global.audioPlayer.control = "play"
- ' Write screen tracker for screensaver
- WriteAsciiFile("tmp:/scene.temp", "nowplaying")
- MoveFile("tmp:/scene.temp", "tmp:/scene")
end if
return true
@@ -284,6 +287,11 @@ function previousClicked() as boolean
if m.playlistTypeCount > 1 then return false
if m.global.queueManager.callFunc("getPosition") = 0 then return false
+ exitScrubMode()
+
+ m.lastRecordedPositionTimestamp = 0
+ m.positionTimestamp.text = "0:00"
+
if m.global.audioPlayer.state = "playing"
m.global.audioPlayer.control = "stop"
end if
@@ -296,7 +304,6 @@ function previousClicked() as boolean
m.global.queueManager.callFunc("moveBack")
pageContentChanged()
-
return true
end function
@@ -334,6 +341,11 @@ end sub
function nextClicked() as boolean
if m.playlistTypeCount > 1 then return false
+ exitScrubMode()
+
+ m.lastRecordedPositionTimestamp = 0
+ m.positionTimestamp.text = "0:00"
+
' Reset loop mode due to manual user interaction
if m.global.audioPlayer.loopMode = "one"
resetLoopModeToDefault()
@@ -399,6 +411,8 @@ sub LoadNextSong()
m.global.audioPlayer.control = "stop"
end if
+ exitScrubMode()
+
' Reset playPosition bar without animation
m.playPosition.width = 0
m.global.queueManager.callFunc("moveForward")
@@ -573,39 +587,40 @@ end sub
'
' @param {integer} seekStep - seconds to move the trickplay position (negative values allowed)
sub processScrubAction(seekStep as integer)
- m.inScrubMode = true
- ' Change audio player control method
- m.global.audioPlayer.control = "prebuffer"
-
' Prepare starting playStart property value
- if m.global.audioPlayer.position <> 0
- m.global.audioPlayer.content.playStart = m.global.audioPlayer.position
+ if m.scrubTimestamp = 0
+ m.scrubTimestamp = m.lastRecordedPositionTimestamp
end if
' Don't let seek to go past the end of the song
- if m.global.audioPlayer.content.playStart + seekStep > m.songDuration
+ if m.scrubTimestamp + seekStep > m.songDuration
return
end if
if seekStep > 0
' Move seek forward
- m.global.audioPlayer.content.playStart += seekStep
- else if m.global.audioPlayer.content.playStart >= Abs(seekStep)
+ m.scrubTimestamp += seekStep
+ else if m.scrubTimestamp >= Abs(seekStep)
' If back seek won't go below 0, move seek back
- m.global.audioPlayer.content.playStart += seekStep
+ m.scrubTimestamp += seekStep
else
' Back seek would go below 0, set to 0 directly
- m.global.audioPlayer.content.playStart = 0
+ m.scrubTimestamp = 0
end if
' Move the seedbar thumb forward
- songPercentComplete = m.global.audioPlayer.content.playStart / m.songDuration
+ songPercentComplete = m.scrubTimestamp / m.songDuration
playPositionBarWidth = m.seekBar.width * songPercentComplete
moveSeekbarThumb(playPositionBarWidth)
' Change the displayed position timestamp
- m.positionTimestamp.text = secondsToHuman(m.global.audioPlayer.content.playStart, false)
+ m.seekTimestamp.text = secondsToHuman(m.scrubTimestamp, false)
+end sub
+
+sub resetSeekbarThumb()
+ m.scrubTimestamp = m.lastRecordedPositionTimestamp
+ moveSeekbarThumb(m.playPosition.width)
end sub
' moveSeekbarThumb: Positions the thumb on the seekbar
@@ -623,7 +638,26 @@ sub moveSeekbarThumb(playPositionBarWidth as float)
thumbPostionLeft = m.seekBar.width - 25
end if
+ ' Move the thumb
m.thumb.translation = [thumbPostionLeft, m.thumb.translation[1]]
+
+ ' Move the seek position element so it follows the thumb
+ m.seekPosition.translation = [720 + thumbPostionLeft - (m.seekPosition.width / 2), m.seekPosition.translation[1]]
+end sub
+
+sub exitScrubMode()
+ m.buttons.setFocus(true)
+ m.thumb.setFocus(false)
+
+ if m.seekPosition.visible
+ m.seekPosition.visible = false
+ end if
+
+ resetSeekbarThumb()
+
+ m.inScrubMode = false
+ m.thumb.visible = false
+ setSelectedButtonState("-default", "-selected")
end sub
' Process key press events
@@ -640,11 +674,13 @@ function onKeyEvent(key as string, press as boolean) as boolean
' Key Event handler when m.thumb is in focus
if m.thumb.hasFocus()
if key = "right"
+ m.inScrubMode = true
processScrubAction(10)
return true
end if
if key = "left"
+ m.inScrubMode = true
processScrubAction(-10)
return true
end if
@@ -653,9 +689,11 @@ function onKeyEvent(key as string, press as boolean) as boolean
if m.inScrubMode
startLoadingSpinner()
m.inScrubMode = false
- m.global.audioPlayer.control = "play"
+ m.global.audioPlayer.seek = m.scrubTimestamp
+ return true
end if
- return true
+
+ return playAction()
end if
end if
@@ -668,6 +706,9 @@ function onKeyEvent(key as string, press as boolean) as boolean
m.thumb.visible = true
setSelectedButtonState("-selected", "-default")
end if
+ if not m.seekPosition.visible
+ m.seekPosition.visible = true
+ end if
m.thumb.setFocus(true)
m.buttons.setFocus(false)
@@ -676,12 +717,8 @@ function onKeyEvent(key as string, press as boolean) as boolean
if key = "down"
if m.thumb.visible
- m.thumb.visible = false
- setSelectedButtonState("-default", "-selected")
+ exitScrubMode()
end if
-
- m.buttons.setFocus(true)
- m.thumb.setFocus(false)
return true
end if
diff --git a/components/music/AudioPlayerView.xml b/components/music/AudioPlayerView.xml
index aaa4f03c..9501b21b 100644
--- a/components/music/AudioPlayerView.xml
+++ b/components/music/AudioPlayerView.xml
@@ -6,6 +6,7 @@
+
@@ -38,6 +39,9 @@
+
+
+
From 0d8f9d127b559bb2d1651d1326c533b8deee70c3 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Mon, 8 Jan 2024 20:05:45 -0500
Subject: [PATCH 3/4] Add 5 second buffer to end of track as duration may be
inaccurate
---
components/music/AudioPlayerView.bs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/music/AudioPlayerView.bs b/components/music/AudioPlayerView.bs
index 0579abb5..db96216b 100644
--- a/components/music/AudioPlayerView.bs
+++ b/components/music/AudioPlayerView.bs
@@ -593,7 +593,7 @@ sub processScrubAction(seekStep as integer)
end if
' Don't let seek to go past the end of the song
- if m.scrubTimestamp + seekStep > m.songDuration
+ if m.scrubTimestamp + seekStep > m.songDuration - 5
return
end if
From 7396d53746c95622545064873f54926f808bdc93 Mon Sep 17 00:00:00 2001
From: 1hitsong <3330318+1hitsong@users.noreply.github.com>
Date: Thu, 11 Jan 2024 19:39:29 -0500
Subject: [PATCH 4/4] Make left scrub stop at 0
---
components/music/AudioPlayerView.bs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/components/music/AudioPlayerView.bs b/components/music/AudioPlayerView.bs
index db96216b..e0b1f8b7 100644
--- a/components/music/AudioPlayerView.bs
+++ b/components/music/AudioPlayerView.bs
@@ -7,7 +7,7 @@ sub init()
m.top.optionsAvailable = false
m.inScrubMode = false
m.lastRecordedPositionTimestamp = 0
- m.scrubTimestamp = 0
+ m.scrubTimestamp = -1
setupAudioNode()
setupAnimationTasks()
@@ -238,7 +238,7 @@ sub audioStateChanged()
if m.global.audioPlayer.state = "finished"
' User has enabled single song loop, play current song again
if m.global.audioPlayer.loopMode = "one"
- m.scrubTimestamp = 0
+ m.scrubTimestamp = -1
playAction()
exitScrubMode()
return
@@ -588,7 +588,7 @@ end sub
' @param {integer} seekStep - seconds to move the trickplay position (negative values allowed)
sub processScrubAction(seekStep as integer)
' Prepare starting playStart property value
- if m.scrubTimestamp = 0
+ if m.scrubTimestamp = -1
m.scrubTimestamp = m.lastRecordedPositionTimestamp
end if
@@ -618,8 +618,10 @@ sub processScrubAction(seekStep as integer)
m.seekTimestamp.text = secondsToHuman(m.scrubTimestamp, false)
end sub
+' resetSeekbarThumb: Resets the thumb to the playing position
+'
sub resetSeekbarThumb()
- m.scrubTimestamp = m.lastRecordedPositionTimestamp
+ m.scrubTimestamp = -1
moveSeekbarThumb(m.playPosition.width)
end sub
@@ -645,6 +647,8 @@ sub moveSeekbarThumb(playPositionBarWidth as float)
m.seekPosition.translation = [720 + thumbPostionLeft - (m.seekPosition.width / 2), m.seekPosition.translation[1]]
end sub
+' exitScrubMode: Moves player out of scrub mode state, resets back to standard play mode
+'
sub exitScrubMode()
m.buttons.setFocus(true)
m.thumb.setFocus(false)