2023-09-19 02:39:44 +00:00
|
|
|
' All of the Quick Play logic seperated by media type
|
|
|
|
namespace quickplay
|
|
|
|
|
2023-09-23 12:09:36 +00:00
|
|
|
' 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
|
|
|
|
|
2023-09-19 02:39:44 +00:00
|
|
|
' 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)
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(artistSongs.items)
|
2023-09-19 02:39:44 +00:00
|
|
|
|
2023-09-23 12:09:36 +00:00
|
|
|
' don't show shuffle icon for 1 song
|
2023-09-23 13:47:21 +00:00
|
|
|
if artistSongs.items.count() > 1
|
2023-09-23 12:09:36 +00:00
|
|
|
m.global.queueManager.callFunc("toggleShuffle")
|
|
|
|
end if
|
|
|
|
end if
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(data.items)
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(data.Items)
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(unwatchedData.Items)
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(myPlaylist.Items)
|
2023-09-19 02:39:44 +00:00
|
|
|
m.global.queueManager.callFunc("toggleShuffle")
|
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
2023-09-23 13:47:21 +00:00
|
|
|
' Quick Play A folder.
|
|
|
|
' Shuffle play all items found
|
|
|
|
sub folder(itemNode as object)
|
|
|
|
if not isValid(itemNode) or not isValid(itemNode.id) then return
|
|
|
|
print "itemNode.json=", itemNode.json
|
|
|
|
|
|
|
|
paramArray = {
|
2023-09-23 14:06:52 +00:00
|
|
|
"includeItemTypes": ["Episode", "Movie", "Video"],
|
2023-09-23 13:47:21 +00:00
|
|
|
"videoTypes": "VideoFile",
|
|
|
|
"sortBy": "Random",
|
|
|
|
"imageTypeLimit": 1,
|
|
|
|
"Recursive": true,
|
|
|
|
"enableUserData": false,
|
|
|
|
"EnableTotalRecordCount": false
|
|
|
|
}
|
|
|
|
' modify api query based on folder type
|
|
|
|
folderType = Lcase(itemNode.json.type)
|
|
|
|
if folderType = "studio"
|
|
|
|
paramArray["studioIds"] = itemNode.id
|
|
|
|
else if folderType = "genre"
|
|
|
|
paramArray["genreIds"] = itemNode.id
|
2023-09-23 14:06:52 +00:00
|
|
|
else if folderType = "musicgenre"
|
|
|
|
paramArray["genreIds"] = itemNode.id
|
|
|
|
paramArray.delete("videoTypes")
|
|
|
|
paramArray["includeItemTypes"] = "Audio"
|
2023-09-23 13:47:21 +00:00
|
|
|
else
|
|
|
|
paramArray["parentId"] = itemNode.id
|
|
|
|
end if
|
|
|
|
' get folder items
|
|
|
|
folderData = api.users.GetItemsByQuery(m.global.session.user.id, paramArray)
|
|
|
|
print "folderData=", folderData
|
|
|
|
|
|
|
|
if isValid(folderData) and isValidAndNotEmpty(folderData.items)
|
|
|
|
pushToQueue(folderData.items)
|
|
|
|
|
|
|
|
' don't show shuffle icon for 1 item
|
|
|
|
if folderData.items.count() > 1
|
|
|
|
m.global.queueManager.callFunc("toggleShuffle")
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
2023-09-19 02:39:44 +00:00
|
|
|
' 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)
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(songsData.Items)
|
2023-09-23 13:47:21 +00:00
|
|
|
if songsData.Items.count() > 1
|
|
|
|
m.global.queueManager.callFunc("toggleShuffle")
|
|
|
|
end if
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
pushToQueue(boxsetData.Items)
|
2023-09-19 02:39:44 +00:00
|
|
|
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
|
2023-09-23 12:09:36 +00:00
|
|
|
' don't show shuffle icon for 1 item
|
2023-09-23 13:47:21 +00:00
|
|
|
if playlistItems.items.count() > 1
|
2023-09-23 12:09:36 +00:00
|
|
|
m.global.queueManager.callFunc("toggleShuffle")
|
|
|
|
end if
|
2023-09-19 02:39:44 +00:00
|
|
|
end if
|
|
|
|
end if
|
|
|
|
else
|
|
|
|
print "Quick Play CollectionFolder WARNING: Unknown collection type"
|
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
|
|
|
end namespace
|