2023-10-03 16:11:25 +00:00
|
|
|
import "pkg:/source/utils/misc.bs"
|
|
|
|
import "ViewCreator.bs"
|
|
|
|
import "pkg:/source/api/Items.bs"
|
|
|
|
import "pkg:/source/api/baserequest.bs"
|
|
|
|
import "pkg:/source/utils/config.bs"
|
|
|
|
import "pkg:/source/api/Image.bs"
|
|
|
|
import "pkg:/source/utils/deviceCapabilities.bs"
|
2023-05-03 21:21:04 +00:00
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
sub init()
|
2023-05-07 01:26:02 +00:00
|
|
|
m.hold = []
|
2022-11-29 22:05:46 +00:00
|
|
|
m.queue = []
|
2023-04-08 17:48:57 +00:00
|
|
|
m.originalQueue = []
|
2023-02-25 16:43:36 +00:00
|
|
|
m.queueTypes = []
|
2023-09-19 02:39:44 +00:00
|
|
|
m.isPlaying = false
|
2023-05-07 01:26:02 +00:00
|
|
|
' Preroll videos only play if user has cinema mode setting enabled
|
2023-06-01 12:43:27 +00:00
|
|
|
m.isPrerollActive = m.global.session.user.settings["playback.cinemamode"]
|
2022-12-02 00:22:00 +00:00
|
|
|
m.position = 0
|
2023-04-08 17:48:57 +00:00
|
|
|
m.shuffleEnabled = false
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
|
|
|
|
|
|
|
' Clear all content from play queue
|
|
|
|
sub clear()
|
2023-09-19 02:39:44 +00:00
|
|
|
m.isPlaying = false
|
2022-11-29 22:05:46 +00:00
|
|
|
m.queue = []
|
2023-02-25 16:43:36 +00:00
|
|
|
m.queueTypes = []
|
2023-06-01 12:43:27 +00:00
|
|
|
m.isPrerollActive = m.global.session.user.settings["playback.cinemamode"]
|
2022-12-02 00:22:00 +00:00
|
|
|
setPosition(0)
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
' Clear all hold content
|
|
|
|
sub clearHold()
|
|
|
|
m.hold = []
|
|
|
|
end sub
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Delete item from play queue at passed index
|
|
|
|
sub deleteAtIndex(index)
|
|
|
|
m.queue.Delete(index)
|
2023-02-25 16:43:36 +00:00
|
|
|
m.queueTypes.Delete(index)
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
|
|
|
|
2022-12-02 00:22:00 +00:00
|
|
|
' Return the number of items in the play queue
|
|
|
|
function getCount()
|
|
|
|
return m.queue.count()
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Return the item currently in focus from the play queue
|
|
|
|
function getCurrentItem()
|
|
|
|
return getItemByIndex(m.position)
|
|
|
|
end function
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
' Return the items in the hold
|
|
|
|
function getHold()
|
|
|
|
return m.hold
|
|
|
|
end function
|
|
|
|
|
2023-04-08 17:48:57 +00:00
|
|
|
' Return whether or not shuffle is enabled
|
|
|
|
function getIsShuffled()
|
|
|
|
return m.shuffleEnabled
|
|
|
|
end function
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Return the item in the passed index from the play queue
|
|
|
|
function getItemByIndex(index)
|
|
|
|
return m.queue[index]
|
|
|
|
end function
|
|
|
|
|
2022-12-02 00:22:00 +00:00
|
|
|
' Returns current playback position within the queue
|
|
|
|
function getPosition()
|
|
|
|
return m.position
|
|
|
|
end function
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
' Hold an item
|
|
|
|
sub hold(newItem)
|
|
|
|
m.hold.push(newItem)
|
|
|
|
end sub
|
|
|
|
|
2022-12-02 00:22:00 +00:00
|
|
|
' Move queue position back one
|
|
|
|
sub moveBack()
|
|
|
|
m.position--
|
|
|
|
end sub
|
|
|
|
|
|
|
|
' Move queue position ahead one
|
|
|
|
sub moveForward()
|
|
|
|
m.position++
|
|
|
|
end sub
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Return the current play queue
|
|
|
|
function getQueue()
|
|
|
|
return m.queue
|
|
|
|
end function
|
|
|
|
|
2023-02-25 16:43:36 +00:00
|
|
|
' Return the types of items in current play queue
|
|
|
|
function getQueueTypes()
|
|
|
|
return m.queueTypes
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Return the unique types of items in current play queue
|
|
|
|
function getQueueUniqueTypes()
|
|
|
|
itemTypes = []
|
|
|
|
|
|
|
|
for each item in getQueueTypes()
|
|
|
|
if not inArray(itemTypes, item)
|
|
|
|
itemTypes.push(item)
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
|
|
|
|
return itemTypes
|
|
|
|
end function
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Return item at end of play queue without removing
|
|
|
|
function peek()
|
|
|
|
return m.queue.peek()
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Play items in queue
|
|
|
|
sub playQueue()
|
2023-09-19 02:39:44 +00:00
|
|
|
m.isPlaying = true
|
2023-02-25 16:43:36 +00:00
|
|
|
nextItem = getCurrentItem()
|
2023-05-07 01:26:02 +00:00
|
|
|
if not isValid(nextItem) then return
|
2022-11-29 22:05:46 +00:00
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
nextItemMediaType = getItemType(nextItem)
|
|
|
|
if nextItemMediaType = "" then return
|
2022-11-29 22:05:46 +00:00
|
|
|
|
|
|
|
if nextItemMediaType = "audio"
|
|
|
|
CreateAudioPlayerView()
|
2023-05-07 01:26:02 +00:00
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-09-23 14:52:29 +00:00
|
|
|
if nextItemMediaType = "musicvideo"
|
|
|
|
CreateVideoPlayerView()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
if nextItemMediaType = "video"
|
2023-02-25 16:43:36 +00:00
|
|
|
CreateVideoPlayerView()
|
2023-05-07 01:26:02 +00:00
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-09-16 21:18:03 +00:00
|
|
|
if nextItemMediaType = "movie"
|
|
|
|
CreateVideoPlayerView()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
if nextItemMediaType = "episode"
|
|
|
|
CreateVideoPlayerView()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2024-02-08 20:09:57 +00:00
|
|
|
if nextItemMediaType = "recording"
|
2024-02-08 16:50:05 +00:00
|
|
|
CreateVideoPlayerView()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
if nextItemMediaType = "trailer"
|
2023-02-25 16:43:36 +00:00
|
|
|
CreateVideoPlayerView()
|
2023-05-07 01:26:02 +00:00
|
|
|
return
|
2022-11-29 22:05:46 +00:00
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
|
|
|
' Remove item at end of play queue
|
|
|
|
sub pop()
|
|
|
|
m.queue.pop()
|
2023-02-25 16:43:36 +00:00
|
|
|
m.queueTypes.pop()
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
|
|
|
|
2023-05-09 17:06:17 +00:00
|
|
|
' Return isPrerollActive status
|
|
|
|
function isPrerollActive() as boolean
|
|
|
|
return m.isPrerollActive
|
2023-05-07 01:26:02 +00:00
|
|
|
end function
|
|
|
|
|
|
|
|
' Set prerollActive status
|
2023-05-11 01:47:54 +00:00
|
|
|
sub setPrerollStatus(newStatus as boolean)
|
2023-05-09 17:06:17 +00:00
|
|
|
m.isPrerollActive = newStatus
|
2023-05-07 01:26:02 +00:00
|
|
|
end sub
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Push new items to the play queue
|
|
|
|
sub push(newItem)
|
|
|
|
m.queue.push(newItem)
|
2023-02-25 16:43:36 +00:00
|
|
|
m.queueTypes.push(getItemType(newItem))
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
|
|
|
|
2022-12-02 00:22:00 +00:00
|
|
|
' Set the queue position
|
|
|
|
sub setPosition(newPosition)
|
|
|
|
m.position = newPosition
|
|
|
|
end sub
|
|
|
|
|
2023-04-08 17:48:57 +00:00
|
|
|
' Reset shuffle to off state
|
|
|
|
sub resetShuffle()
|
|
|
|
m.shuffleEnabled = false
|
|
|
|
end sub
|
|
|
|
|
|
|
|
' Toggle shuffleEnabled state
|
|
|
|
sub toggleShuffle()
|
|
|
|
m.shuffleEnabled = not m.shuffleEnabled
|
|
|
|
|
|
|
|
if m.shuffleEnabled
|
|
|
|
shuffleQueueItems()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
|
|
|
resetQueueItemOrder()
|
|
|
|
end sub
|
|
|
|
|
|
|
|
' Reset queue items back to original, unshuffled order
|
|
|
|
sub resetQueueItemOrder()
|
|
|
|
set(m.originalQueue)
|
|
|
|
end sub
|
|
|
|
|
|
|
|
' Return original, unshuffled queue
|
|
|
|
function getUnshuffledQueue()
|
|
|
|
return m.originalQueue
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Save a copy of the original queue and randomize order of queue items
|
|
|
|
sub shuffleQueueItems()
|
|
|
|
' By calling getQueue 2 different ways, Roku avoids needing to do a deep copy
|
|
|
|
m.originalQueue = m.global.queueManager.callFunc("getQueue")
|
2023-09-19 02:39:44 +00:00
|
|
|
itemIDArray = getQueue()
|
|
|
|
temp = invalid
|
|
|
|
|
|
|
|
if m.isPlaying
|
|
|
|
' Save the currently playing item
|
|
|
|
temp = getCurrentItem()
|
|
|
|
' remove currently playing item from itemIDArray
|
|
|
|
itemIDArray.Delete(m.position)
|
|
|
|
end if
|
|
|
|
|
|
|
|
' shuffle all items
|
|
|
|
itemIDArray = shuffleArray(itemIDArray)
|
|
|
|
|
|
|
|
if m.isPlaying
|
|
|
|
' Put currently playing item in front of itemIDArray
|
|
|
|
itemIDArray.Unshift(temp)
|
|
|
|
end if
|
2023-04-08 17:48:57 +00:00
|
|
|
|
2023-09-19 02:39:44 +00:00
|
|
|
set(itemIDArray)
|
2023-04-08 17:48:57 +00:00
|
|
|
end sub
|
|
|
|
|
2022-11-29 22:05:46 +00:00
|
|
|
' Return the fitst item in the play queue
|
|
|
|
function top()
|
|
|
|
return getItemByIndex(0)
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Replace play queue with passed array
|
|
|
|
sub set(items)
|
2023-04-08 17:48:57 +00:00
|
|
|
clear()
|
2022-11-29 22:05:46 +00:00
|
|
|
m.queue = items
|
2023-02-25 16:43:36 +00:00
|
|
|
for each item in items
|
|
|
|
m.queueTypes.push(getItemType(item))
|
|
|
|
end for
|
2022-11-29 22:05:46 +00:00
|
|
|
end sub
|
2023-02-25 16:43:36 +00:00
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
' Set starting point for top item in the queue
|
|
|
|
sub setTopStartingPoint(positionTicks)
|
|
|
|
m.queue[0].startingPoint = positionTicks
|
|
|
|
end sub
|
|
|
|
|
2023-02-25 16:43:36 +00:00
|
|
|
function getItemType(item) as string
|
2023-03-09 19:35:29 +00:00
|
|
|
if isValid(item) and isValid(item.json) and isValid(item.json.mediatype) and item.json.mediatype <> ""
|
2023-02-25 16:43:36 +00:00
|
|
|
return LCase(item.json.mediatype)
|
2023-03-09 19:35:29 +00:00
|
|
|
else if isValid(item) and isValid(item.type) and item.type <> ""
|
2023-02-25 16:43:36 +00:00
|
|
|
return LCase(item.type)
|
|
|
|
end if
|
|
|
|
|
2023-05-07 01:26:02 +00:00
|
|
|
return ""
|
2023-02-25 16:43:36 +00:00
|
|
|
end function
|