jf-roku/source/utils/quickplay.bs
2023-09-23 08:09:36 -04:00

429 lines
17 KiB
Plaintext

' All of the Quick Play logic seperated by media type
namespace quickplay
' Takes an array of items and adds to global queue.
' Stop loading items if memory level becomes low
sub pushToQueue(queueArray as object, limitValue = 200 as integer)
if isValidAndNotEmpty(queueArray)
itemCount = queueArray.count()
if limitValue >= itemCount
' load everything
for each item in queueArray
m.global.queueManager.callFunc("push", item)
end for
else
newLimit = limitValue
for i = 0 to itemCount - 1
m.global.queueManager.callFunc("push", queueArray[i])
if i = newLimit
' hit the item limit. check memory level
newLimit = newLimit + limitValue
print "m.global.session.memoryLevel=", m.global.session.memoryLevel
if m.global.session.memoryLevel = "low" or m.global.session.memoryLevel = "critical"
print "Memory is low. Stop loading items in the playlist..."
exit for
end if
end if
end for
end if
end if
end sub
' A single video file.
sub video(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) or not isValid(itemNode.json) then return
' attempt to play video file. resume if possible
if isValid(itemNode.selectedVideoStreamId)
itemNode.id = itemNode.selectedVideoStreamId
end if
audio_stream_idx = 0
if isValid(itemNode.selectedAudioStreamIndex) and itemNode.selectedAudioStreamIndex > 0
audio_stream_idx = itemNode.selectedAudioStreamIndex
end if
itemNode.selectedAudioStreamIndex = audio_stream_idx
playbackPosition = 0
if isValid(itemNode.json.userdata) and isValid(itemNode.json.userdata.PlaybackPositionTicks)
playbackPosition = itemNode.json.userdata.PlaybackPositionTicks
end if
itemNode.startingPoint = playbackPosition
m.global.queueManager.callFunc("push", itemNode)
end sub
' A single audio file.
sub audio(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
m.global.queueManager.callFunc("push", itemNode)
end sub
' A music album.
' Play the entire album starting with track 1.
sub album(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
' grab list of songs in the album
albumSongs = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"imageTypeLimit": 1,
"sortBy": "SortName",
"enableUserData": false,
"EnableTotalRecordCount": false
})
if isValid(albumSongs) and isValidAndNotEmpty(albumSongs.items)
' add every song to the queue
for each song in albumSongs.items
m.global.queueManager.callFunc("push", song)
end for
end if
end sub
' A music artist.
' Shuffle play all songs by artist.
sub artist(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
' get all songs by artist
artistSongs = api.users.GetItemsByQuery(m.global.session.user.id, {
"artistIds": itemNode.id,
"includeItemTypes": "Audio",
"sortBy": "Album",
"imageTypeLimit": 1,
"Recursive": true,
"enableUserData": false,
"EnableTotalRecordCount": false
})
print "artistSongs=", artistSongs
if isValid(artistSongs) and isValidAndNotEmpty(artistSongs.items)
pushToQueue(artistSongs.items)
' don't show shuffle icon for 1 song
if artistSongs.items > 1
m.global.queueManager.callFunc("toggleShuffle")
end if
end if
end sub
' A boxset.
' Shuffle play all items inside.
sub boxset(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
data = api.items.GetByQuery({
"userid": m.global.session.user.id,
"parentid": itemNode.id,
"EnableTotalRecordCount": false
})
if isValid(data) and isValidAndNotEmpty(data.Items)
' there are videos inside
pushToQueue(data.items)
end if
end sub
' A TV Show Series.
' Play the first unwatched episode.
' If none, shuffle play the whole series.
sub series(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
data = api.shows.GetNextUp({
"seriesId": itemNode.id,
"recursive": true,
"SortBy": "DatePlayed",
"SortOrder": "Descending",
"ImageTypeLimit": 1,
"UserId": m.global.session.user.id,
"EnableRewatching": false,
"DisableFirstEpisode": false,
"EnableTotalRecordCount": false
})
if isValid(data) and isValidAndNotEmpty(data.Items)
' there are unwatched episodes
for each item in data.Items
m.global.queueManager.callFunc("push", item)
end for
else
' next up check was empty
' check for a resumable episode
data = api.users.GetResumeItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"userid": m.global.session.user.id,
"SortBy": "DatePlayed",
"recursive": true,
"SortOrder": "Descending",
"Filters": "IsResumable",
"EnableTotalRecordCount": false
})
print "resumeitems data=", data
if isValid(data) and isValidAndNotEmpty(data.Items)
' play the resumable episode
for each item in data.Items
if isValid(item.UserData) and isValid(item.UserData.PlaybackPositionTicks)
item.startingPoint = item.userdata.PlaybackPositionTicks
end if
m.global.queueManager.callFunc("push", item)
end for
else
' shuffle all episodes
data = api.shows.GetEpisodes(itemNode.id, {
"userid": m.global.session.user.id,
"SortBy": "Random",
"EnableTotalRecordCount": false
})
if isValid(data) and isValidAndNotEmpty(data.Items)
' add all episodes found to a playlist
pushToQueue(data.Items)
end if
end if
end if
end sub
' A TV Show Season.
' Play the first unwatched episode.
' If none, play the whole season starting with episode 1.
sub season(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
unwatchedData = api.shows.GetEpisodes(itemNode.json.SeriesId, {
"seasonId": itemNode.id,
"userid": m.global.session.user.id,
"EnableTotalRecordCount": false
})
if isValid(unwatchedData) and isValidAndNotEmpty(unwatchedData.Items)
' find the first unwatched episode
firstUnwatchedEpisodeIndex = invalid
for each item in unwatchedData.Items
if isValid(item.UserData)
if isValid(item.UserData.Played) and item.UserData.Played = false
firstUnwatchedEpisodeIndex = item.IndexNumber - 1
if isValid(item.UserData.PlaybackPositionTicks)
item.startingPoint = item.UserData.PlaybackPositionTicks
end if
exit for
end if
end if
end for
if isValid(firstUnwatchedEpisodeIndex)
' add the first unwatched episode and the rest of the season to a playlist
for i = firstUnwatchedEpisodeIndex to unwatchedData.Items.count() - 1
m.global.queueManager.callFunc("push", unwatchedData.Items[i])
end for
else
' try to find a "continue watching" episode
continueData = api.users.GetResumeItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"userid": m.global.session.user.id,
"SortBy": "DatePlayed",
"recursive": true,
"SortOrder": "Descending",
"Filters": "IsResumable",
"EnableTotalRecordCount": false
})
if isValid(continueData) and isValidAndNotEmpty(continueData.Items)
' play the resumable episode
for each item in continueData.Items
if isValid(item.UserData) and isValid(item.UserData.PlaybackPositionTicks)
item.startingPoint = item.userdata.PlaybackPositionTicks
end if
m.global.queueManager.callFunc("push", item)
end for
else
' play the whole season in order
if isValid(unwatchedData) and isValidAndNotEmpty(unwatchedData.Items)
' add all episodes found to a playlist
pushToQueue(unwatchedData.Items)
end if
end if
end if
end if
end sub
' Quick Play A Playlist.
' Play the first unwatched episode.
' If none, play the whole season starting with episode 1.
sub playlist(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
' get playlist items
myPlaylist = api.playlists.GetItems(itemNode.id, {
"userId": m.global.session.user.id
})
if isValid(myPlaylist) and isValidAndNotEmpty(myPlaylist.Items)
' add each item to the queue
pushToQueue(myPlaylist.Items)
m.global.queueManager.callFunc("toggleShuffle")
end if
end sub
' Quick Play A CollectionFolder.
' Shuffle play the items inside
' with some differences based on collectionType.
sub collectionFolder(itemNode as object)
if not isValid(itemNode) or not isValid(itemNode.id) then return
' play depends on the kind of files inside the collectionfolder
print "attempting to quickplay a collection folder"
collectionType = LCase(itemNode.collectionType)
print "collectionType=", collectionType
if collectionType = "movies"
' get randomized list of movies inside
data = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id
})
if isValid(data) and isValidAndNotEmpty(data.items)
' add each item to the queue
for each item in data.Items
' only add movies we're not currently watching
if isValid(item.userdata) and isValid(item.userdata.PlaybackPositionTicks)
if item.userdata.PlaybackPositionTicks = 0
m.global.queueManager.callFunc("push", item)
end if
end if
end for
m.global.queueManager.callFunc("toggleShuffle")
end if
else if collectionType = "music"
' get all audio files under this collection
' sort songs by album then artist
songsData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"includeItemTypes": "Audio",
"sortBy": "Album",
"Recursive": true,
"imageTypeLimit": 1,
"enableUserData": false,
"EnableTotalRecordCount": false
})
print "songsData=", songsData
if isValid(songsData) and isValidAndNotEmpty(songsData.items)
pushToQueue(songsData.Items)
m.global.queueManager.callFunc("toggleShuffle")
end if
else if collectionType = "boxsets"
' get list of all boxsets inside
boxsetData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"imageTypeLimit": 0,
"enableUserData": false,
"EnableTotalRecordCount": false,
"enableImages": false
})
print "boxsetData=", boxsetData
if isValid(boxsetData) and isValidAndNotEmpty(boxsetData.items)
' pick a random boxset
arrayIndex = Rnd(boxsetData.items.count()) - 1
myBoxset = boxsetData.items[arrayIndex]
' grab list of items from boxset
print "myBoxset=", myBoxset
boxsetData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": myBoxset.id,
"EnableTotalRecordCount": false
})
if isValid(boxsetData) and isValidAndNotEmpty(boxsetData.items)
' add all boxset items to queue
pushToQueue(boxsetData.Items)
end if
end if
else if collectionType = "tvshows"
' get list of tv shows inside
tvshowsData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"imageTypeLimit": 0,
"enableUserData": false,
"EnableTotalRecordCount": false,
"enableImages": false
})
print "tvshowsData=", tvshowsData
if isValid(tvshowsData) and isValidAndNotEmpty(tvshowsData.items)
for each tvshow in tvshowsData.items
' grab all watched episodes for each series
showData = api.shows.GetEpisodes(tvshow.id, {
"userId": m.global.session.user.id,
"imageTypeLimit": 0,
"EnableTotalRecordCount": false,
"enableImages": false
})
if isValid(showData) and isValidAndNotEmpty(showData.items)
' add all played episodes to queue
for each episode in showData.items
if isValid(episode.userdata) and isValid(episode.userdata.Played)
if episode.userdata.Played
m.global.queueManager.callFunc("push", episode)
end if
end if
end for
end if
end for
m.global.queueManager.callFunc("toggleShuffle")
end if
' else if collectionType = "homevideos" ' also used for a "Photo" library
else
print "Quick Play WARNING: Unknown collection type"
end if
end sub
' Quick Play A UserView.
' Play logic depends on "collectionType".
sub userView(itemNode as object)
' play depends on the kind of files inside the collectionfolder
collectionType = LCase(itemNode.collectionType)
print "collectionType=", collectionType
if collectionType = "playlists"
' get list of all playlists inside
playlistData = api.users.GetItemsByQuery(m.global.session.user.id, {
"parentId": itemNode.id,
"imageTypeLimit": 0,
"enableUserData": false,
"EnableTotalRecordCount": false,
"enableImages": false
})
print "playlistData=", playlistData
if isValid(playlistData) and isValidAndNotEmpty(playlistData.items)
' pick a random playlist
arrayIndex = Rnd(playlistData.items.count()) - 1
myPlaylist = playlistData.items[arrayIndex]
' grab list of items from playlist
print "myPlaylist=", myPlaylist
playlistItems = api.playlists.GetItems(myPlaylist.id, {
"userId": m.global.session.user.id,
"EnableTotalRecordCount": false
})
' validate api results
if isValid(playlistItems) and isValidAndNotEmpty(playlistItems.items)
for each item in playlistItems.items
m.global.queueManager.callFunc("push", item)
end for
' don't show shuffle icon for 1 item
if playlistItems.items > 1
m.global.queueManager.callFunc("toggleShuffle")
end if
end if
end if
else
print "Quick Play CollectionFolder WARNING: Unknown collection type"
end if
end sub
end namespace