diff --git a/components/ItemGrid/GridItem.brs b/components/ItemGrid/GridItem.brs
index 4c4a6178..c89dd79c 100644
--- a/components/ItemGrid/GridItem.brs
+++ b/components/ItemGrid/GridItem.brs
@@ -37,26 +37,37 @@ sub itemContentChanged()
if itemData.type = "Movie"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
else if itemData.type = "Series"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
else if itemData.type = "Boxset"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
else if itemData.type = "TvChannel"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
else if itemData.type = "Folder"
m.itemPoster.uri = itemData.PosterUrl
- m.itemIcon.uri = itemData.iconUrl
+ 'm.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
+ m.itemPoster.loadDisplayMode = m.topParent.imageDisplayMode
else if itemData.type = "Video"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
else if itemData.type = "Photo"
m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
m.itemText.text = itemData.Title
+ else if itemData.type = "Episode"
+ m.itemPoster.uri = itemData.PosterUrl
+ m.itemIcon.uri = itemData.iconUrl
+ m.itemText.text = itemData.json.SeriesName + " - " + itemData.Title
else if itemData.type = "MusicArtist"
m.itemPoster.uri = itemData.PosterUrl
m.itemText.text = itemData.Title
diff --git a/components/ItemGrid/ItemGrid.brs b/components/ItemGrid/ItemGrid.brs
index 7c8bd48e..5934cddd 100644
--- a/components/ItemGrid/ItemGrid.brs
+++ b/components/ItemGrid/ItemGrid.brs
@@ -42,9 +42,9 @@ sub init()
'set inital counts for overhang before content is loaded.
m.loadItemsTask.totalRecordCount = 0
+
m.spinner = m.top.findNode("spinner")
m.spinner.visible = true
-
m.Alpha = m.top.findNode("AlphaMenu")
m.AlphaSelected = m.top.findNode("AlphaSelected")
@@ -55,7 +55,9 @@ end sub
'
'Load initial set of Data
sub loadInitialItems()
-
+ if m.top.parentItem.json.Type = "CollectionFolder" 'or m.top.parentItem.json.Type = "Folder"
+ m.top.HomeLibraryItem = m.top.parentItem.Id
+ end if
if m.top.parentItem.backdropUrl <> invalid
SetBackground(m.top.parentItem.backdropUrl)
end if
@@ -78,10 +80,10 @@ sub loadInitialItems()
sortAscendingStr = get_user_setting("display." + m.top.parentItem.Id + ".sortAscending")
m.filter = get_user_setting("display." + m.top.parentItem.Id + ".filter")
else
- m.view = invalid
m.sortField = get_user_setting("display." + m.top.parentItem.Id + ".sortField")
sortAscendingStr = get_user_setting("display." + m.top.parentItem.Id + ".sortAscending")
m.filter = get_user_setting("display." + m.top.parentItem.Id + ".filter")
+ m.view = get_user_setting("display." + m.top.parentItem.Id + ".landing")
end if
if m.sortField = invalid then m.sortField = "SortName"
@@ -92,28 +94,42 @@ sub loadInitialItems()
else
m.sortAscending = false
end if
+ 'Set Stuido Id
+ if m.top.parentItem.json.type = "Studio"
+ m.loadItemsTask.studioIds = m.top.parentItem.Id
+ m.loadItemsTask.itemId = m.top.parentItem.parentFolder
+ m.loadItemsTask.genreIds = ""
+ 'set Genre Id
+ else if m.top.parentItem.json.type = "Genre"
+ m.loadItemsTask.genreIds = m.top.parentItem.Id
+ m.loadItemsTask.itemId = m.top.parentItem.parentFolder
+ m.loadItemsTask.studioIds = ""
+ else if (m.view = "Shows" or m.options.view = "Shows") or (m.view = "Movies" or m.options.view = "Movies")
+ m.loadItemsTask.studioIds = ""
+ m.loadItemsTask.genreIds = ""
+ end if
+ updateTitle()
m.loadItemsTask.nameStartsWith = m.top.AlphaSelected
m.emptyText.visible = false
-
- updateTitle()
-
- m.loadItemsTask.itemId = m.top.parentItem.Id
m.loadItemsTask.sortField = m.sortField
m.loadItemsTask.sortAscending = m.sortAscending
m.loadItemsTask.filter = m.filter
m.loadItemsTask.startIndex = 0
-
+ 'Load Item Types
if m.top.parentItem.collectionType = "movies"
m.loadItemsTask.itemType = "Movie"
+ m.loadItemsTask.itemId = m.top.parentItem.Id
else if m.top.parentItem.collectionType = "tvshows"
m.loadItemsTask.itemType = "Series"
+ m.loadItemsTask.itemId = m.top.parentItem.Id
else if m.top.parentItem.collectionType = "music"
' Default Settings
m.loadItemsTask.recursive = false
m.itemGrid.itemSize = "[290, 290]"
m.itemGrid.itemSpacing = "[ 0, 20]"
m.loadItemsTask.itemType = "MusicArtist,MusicAlbum"
+ m.loadItemsTask.itemId = m.top.parentItem.Id
m.view = get_user_setting("display.music.view")
@@ -134,26 +150,51 @@ sub loadInitialItems()
showTvGuide()
end if
+
else if m.top.parentItem.collectionType = "CollectionFolder" or m.top.parentItem.type = "CollectionFolder" or m.top.parentItem.collectionType = "boxsets" or m.top.parentItem.Type = "Boxset" or m.top.parentItem.Type = "Folder" or m.top.parentItem.Type = "Channel"
+
' Non-recursive, to not show subfolder contents
m.loadItemsTask.recursive = false
- else if m.top.parentItem.collectionType = "Channel"
+ m.loadItemsTask.itemId = m.top.parentItem.parentFolder
+ else if m.top.parentItem.Type = "Channel"
m.top.imageDisplayMode = "scaleToFit"
+ else if m.top.parentItem.json.type = "Studio"
+ m.loadItemsTask.itemId = m.top.parentItem.parentFolder
+ m.loadItemsTask.itemType = "Series,Movie"
+ m.top.imageDisplayMode = "scaleToFit"
+ else if m.top.parentItem.json.type = "Genre"
+ m.loadItemsTask.itemType = "Series,Movie"
+ m.loadItemsTask.itemId = m.top.parentItem.parentFolder
else
print "[ItemGrid] Unknown Type: " m.top.parentItem
end if
+ 'end if
+ if m.top.parentItem.type <> "Folder" and (m.options.view = "Networks" or m.view = "Networks" or m.options.view = "Studios" or m.view = "Studios")
+ m.loadItemsTask.view = "Networks"
+ m.top.imageDisplayMode = "scaleToFit"
+ else if m.top.parentItem.type <> "Folder" and (m.options.view = "Genres" or m.view = "Genres")
+ m.loadItemsTask.StudioIds = m.top.parentItem.Id
+ m.loadItemsTask.view = "Genres"
+ else if m.top.parentItem.type <> "Folder" and (m.options.view = "Shows" or m.view = "Shows")
+ m.loadItemsTask.studioIds = ""
+ m.loadItemsTask.view = "Shows"
+ else if m.top.parentItem.type <> "Folder" and (m.options.view = "Movies" or m.view = "Movies")
+ m.loadItemsTask.studioIds = ""
+ m.loadItemsTask.view = "Movies"
+ end if
m.loadItemsTask.observeField("content", "ItemDataLoaded")
+ m.spinner.visible = true
m.loadItemsTask.control = "RUN"
-
SetUpOptions()
-
end sub
' Set Movies view, sort, and filter options
sub setMoviesOptions(options)
options.views = [
- { "Title": tr("Movies"), "Name": "movies" },
+ { "Title": tr("Movies"), "Name": "Movies" },
+ { "Title": tr("Studios"), "Name": "Studios" },
+ { "Title": tr("Genres"), "Name": "Genres" }
]
options.sort = [
{ "Title": tr("TITLE"), "Name": "SortName" },
@@ -189,7 +230,12 @@ end sub
' Set TV Show view, sort, and filter options
sub setTvShowsOptions(options)
- options.views = [{ "Title": tr("Shows"), "Name": "shows" }]
+ options.views = [
+ { "Title": tr("Shows"), "Name": "Shows" },
+ { "Title": tr("Networks"), "Name": "Networks" },
+ { "Title": tr("Genres"), "Name": "Genres" }
+
+ ]
options.sort = [
{ "Title": tr("TITLE"), "Name": "SortName" },
{ "Title": tr("IMDB_RATING"), "Name": "CommunityRating" },
@@ -281,10 +327,10 @@ end function
' Data to display when options button selected
sub SetUpOptions()
-
options = {}
options.filter = []
options.favorite = []
+
if getCollectionType() = "movies"
setMoviesOptions(options)
else if inStringArray(["boxsets", "Boxset"], getCollectionType())
@@ -297,6 +343,7 @@ sub SetUpOptions()
setPhotoAlbumOptions(options)
else if getCollectionType() = "music"
setMusicOptions(options)
+
else
setDefaultOptions(options)
end if
@@ -352,7 +399,6 @@ sub ItemDataLoaded(msg)
m.loadedItems = m.itemGrid.content.getChildCount()
m.loadedRows = m.loadedItems / m.itemGrid.numColumns
m.Loading = false
-
'If there are no items to display, show message
if m.loadedItems = 0
m.emptyText.text = tr("NO_ITEMS").Replace("%1", m.top.parentItem.Type)
@@ -396,7 +442,7 @@ sub onItemFocused()
' Set Background to item backdrop
SetBackground(m.itemGrid.content.getChild(m.itemGrid.itemFocused).backdropUrl)
- ' Load more data if focus is within last 3 rows, and there are more items to load
+ ' Load more data if focus is within last 5 rows, and there are more items to load
if focusedRow >= m.loadedRows - 5 and m.loadeditems < m.loadItemsTask.totalRecordCount
loadMoreData()
end if
@@ -433,9 +479,8 @@ end sub
'
'Load next set of items
sub loadMoreData()
-
+ m.spinner.visible = true
if m.Loading = true then return
-
m.Loading = true
m.loadItemsTask.startIndex = m.loadedItems
m.loadItemsTask.observeField("content", "ItemDataLoaded")
@@ -453,6 +498,7 @@ sub onItemAlphaSelected()
m.loadedItems = 0
m.data = CreateObject("roSGNode", "ContentNode")
m.itemGrid.content = m.data
+ m.spinner.visible = true
loadInitialItems()
end sub
@@ -460,7 +506,6 @@ end sub
'
'Check if options updated and any reloading required
sub optionsClosed()
-
if m.top.parentItem.collectionType = "livetv" and m.options.view <> m.view
if m.options.view = "tvGuide"
m.view = "tvGuide"
@@ -503,6 +548,14 @@ sub optionsClosed()
set_user_setting("display.music.view", m.view)
reload = true
end if
+ else
+ m.view = get_user_setting("display." + m.top.parentItem.Id + ".landing")
+ if m.options.view <> m.view
+ 'reload and store new view setting
+ m.view = m.options.view
+ set_user_setting("display." + m.top.parentItem.Id + ".landing", m.view)
+ reload = true
+ end if
end if
if m.options.sortField <> m.sortField or m.options.sortAscending <> m.sortAscending
@@ -653,6 +706,15 @@ sub updateTitle()
m.top.overhangTitle = m.top.parentItem.title + " " + tr("(Filtered)")
end if
+ if m.options.view = "Networks" or m.view = "Networks"
+ m.top.overhangTitle = "%s (%s)".Format(m.top.parentItem.title, tr("Networks"))
+ end if
+ if m.options.view = "Studios" or m.view = "Studios"
+ m.top.overhangTitle = "%s (%s)".Format(m.top.parentItem.title, tr("Studios"))
+ end if
+ if m.options.view = "Genres" or m.view = "Genres"
+ m.top.overhangTitle = "%s (%s)".Format(m.top.parentItem.title, tr("Genres"))
+ end if
actInt = m.itemGrid.itemFocused + 1
if m.showItemCount and m.loadItemsTask.totalRecordCount > 0
m.top.overhangTitle += " (" + tr("%1 of %2").Replace("%1", actInt.toStr()).Replace("%2", m.loadItemsTask.totalRecordCount.toStr()) + ")"
diff --git a/components/ItemGrid/ItemGrid.xml b/components/ItemGrid/ItemGrid.xml
index b8af2ca3..99a2dd19 100644
--- a/components/ItemGrid/ItemGrid.xml
+++ b/components/ItemGrid/ItemGrid.xml
@@ -34,6 +34,7 @@
+
@@ -44,6 +45,7 @@
+
diff --git a/components/ItemGrid/ItemGridOptions.brs b/components/ItemGrid/ItemGridOptions.brs
index 347fcae9..64d6ecb0 100644
--- a/components/ItemGrid/ItemGridOptions.brs
+++ b/components/ItemGrid/ItemGridOptions.brs
@@ -36,7 +36,7 @@ sub optionsSet()
if m.top.options.views <> invalid
viewContent = CreateObject("roSGNode", "ContentNode")
index = 0
- selectedViewIndex = 0
+ selectedViewIndex = m.selectedViewIndex
for each view in m.top.options.views
entry = viewContent.CreateChild("ContentNode")
diff --git a/components/ItemGrid/LoadItemsTask2.brs b/components/ItemGrid/LoadItemsTask2.brs
index f91802ca..6f99cdce 100644
--- a/components/ItemGrid/LoadItemsTask2.brs
+++ b/components/ItemGrid/LoadItemsTask2.brs
@@ -22,9 +22,10 @@ sub loadItems()
SortBy: sort_field,
SortOrder: sort_order,
recursive: m.top.recursive,
- Fields: "Overview"
+ Fields: "Overview",
+ StudioIds: m.top.studioIds,
+ genreIds: m.top.genreIds
}
-
' Handle special case when getting names starting with numeral
if m.top.NameStartsWith <> ""
if m.top.NameStartsWith = "#"
@@ -49,12 +50,17 @@ sub loadItems()
if m.top.ItemType = "LiveTV"
url = "LiveTv/Channels"
params.append({ UserId: get_setting("active_user") })
+ else if m.top.view = "Networks"
+ url = "Studios"
+ params.append({ UserId: get_setting("active_user") })
+ else if m.top.view = "Genres"
+ url = "Genres"
+ params.append({ UserId: get_setting("active_user") })
else
url = Substitute("Users/{0}/Items/", get_setting("active_user"))
end if
resp = APIRequest(url, params)
data = getJson(resp)
-
if data <> invalid
if data.TotalRecordCount <> invalid then m.top.totalRecordCount = data.TotalRecordCount
@@ -77,6 +83,12 @@ sub loadItems()
tmp = CreateObject("roSGNode", "PhotoData")
else if item.type = "PhotoAlbum"
tmp = CreateObject("roSGNode", "FolderData")
+ else if item.type = "Episode"
+ tmp = CreateObject("roSGNode", "TVEpisode")
+ else if item.Type = "Genre"
+ tmp = CreateObject("roSGNode", "FolderData")
+ else if item.Type = "Studio"
+ tmp = CreateObject("roSGNode", "FolderData")
else if item.Type = "MusicArtist" or item.Type = "MusicAlbum"
tmp = CreateObject("roSGNode", "MusicArtistData")
else if item.Type = "Audio"
@@ -84,8 +96,8 @@ sub loadItems()
else
print "[LoadItems] Unknown Type: " item.Type
end if
-
if tmp <> invalid
+ tmp.parentFolder = m.top.itemId
tmp.json = item
if item.UserData <> invalid and item.UserData.isFavorite <> invalid
tmp.favorite = item.UserData.isFavorite
@@ -94,7 +106,5 @@ sub loadItems()
end if
end for
end if
-
m.top.content = results
-
end sub
diff --git a/components/ItemGrid/LoadItemsTask2.xml b/components/ItemGrid/LoadItemsTask2.xml
index 91780ea1..38cc0759 100644
--- a/components/ItemGrid/LoadItemsTask2.xml
+++ b/components/ItemGrid/LoadItemsTask2.xml
@@ -12,7 +12,9 @@
-
+
+
+
diff --git a/components/data/FolderData.brs b/components/data/FolderData.brs
index 4a90dda8..4239de2a 100644
--- a/components/data/FolderData.brs
+++ b/components/data/FolderData.brs
@@ -17,8 +17,13 @@ end sub
sub setPoster()
if m.top.image <> invalid
m.top.posterURL = m.top.image.url
+ else if m.top.json.Type = "Studio"
+ imgParams = { "maxHeight": 440, "maxWidth": 295, "Tag": m.top.json.ParentThumbImageTag }
+ m.top.posterURL = ImageURL(m.top.json.id, "Thumb", imgParams)
else if m.top.json.ImageTags.Primary <> invalid
imgParams = { "maxHeight": 440, "maxWidth": 295 }
m.top.posterURL = ImageURL(m.top.json.id, "Primary", imgParams)
end if
end sub
+
+'TODO Set network Poster image
diff --git a/components/data/JFContentItem.xml b/components/data/JFContentItem.xml
index 98e87198..5bbcf662 100644
--- a/components/data/JFContentItem.xml
+++ b/components/data/JFContentItem.xml
@@ -8,6 +8,7 @@
+
diff --git a/components/data/SceneManager.brs b/components/data/SceneManager.brs
index 36199389..f621ae4d 100755
--- a/components/data/SceneManager.brs
+++ b/components/data/SceneManager.brs
@@ -9,6 +9,7 @@ end sub
' Push a new group onto the stack, replacing the existing group on the screen
sub pushScene(newGroup)
currentGroup = m.groups.peek()
+
if currentGroup <> invalid
'Search through group and store off last focused item
if currentGroup.focusedChild <> invalid
@@ -16,10 +17,10 @@ sub pushScene(newGroup)
while focused.hasFocus() = false
focused = focused.focusedChild
end while
+
currentGroup.lastFocus = focused
currentGroup.setFocus(false)
else
- currentGroup.lastFocus = invalid
currentGroup.setFocus(false)
end if
@@ -104,12 +105,15 @@ sub popScene()
if group.isSubType("JFScreen")
group.callFunc("OnScreenShown")
else
-
' Restore focus
if group.lastFocus <> invalid
group.lastFocus.setFocus(true)
else
- group.setFocus(true)
+ if group.focusedChild <> invalid
+ group.focusedChild.setFocus(true)
+ else
+ group.setFocus(true)
+ end if
end if
end if
else
@@ -134,6 +138,12 @@ sub clearScenes()
m.groups = []
end sub
+'
+' Clear previous scene from group stack
+sub clearPreviousScene()
+ m.groups.pop()
+end sub
+
'
' Display user/device settings screen
sub settings()
diff --git a/components/data/SceneManager.xml b/components/data/SceneManager.xml
index 6f947341..52cc6684 100755
--- a/components/data/SceneManager.xml
+++ b/components/data/SceneManager.xml
@@ -6,6 +6,7 @@
+
diff --git a/components/data/TVEpisode.brs b/components/data/TVEpisode.brs
new file mode 100644
index 00000000..13c2980b
--- /dev/null
+++ b/components/data/TVEpisode.brs
@@ -0,0 +1,21 @@
+sub setFields()
+ json = m.top.json
+
+ m.top.id = json.id
+ m.top.Title = json.name
+ m.top.Description = json.overview
+ m.top.favorite = json.UserData.isFavorite
+ m.top.watched = json.UserData.played
+ m.top.Type = json.Type
+
+ setPoster()
+end sub
+
+sub setPoster()
+ if m.top.image <> invalid
+ m.top.posterURL = m.top.image.url
+ else if m.top.json.ImageTags.Primary <> invalid
+ imgParams = { "maxHeight": 440, "maxWidth": 295 }
+ m.top.posterURL = ImageURL(m.top.json.id, "Primary", imgParams)
+ end if
+end sub
diff --git a/components/data/TVEpisode.xml b/components/data/TVEpisode.xml
new file mode 100644
index 00000000..5ce6d0fa
--- /dev/null
+++ b/components/data/TVEpisode.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/data/TVEpisodeData.brs b/components/data/TVEpisodeData.brs
index 4045afbe..8991446a 100644
--- a/components/data/TVEpisodeData.brs
+++ b/components/data/TVEpisodeData.brs
@@ -6,6 +6,7 @@ sub setFields()
m.top.showID = datum.SeriesID
m.top.seasonID = datum.SeasonID
m.top.overview = datum.overview
+ m.top.favorite = datum.UserData.isFavorite
end sub
sub setPoster()
diff --git a/images/spinner.png b/images/spinner.png
index 4663c4ff..25e9523c 100644
Binary files a/images/spinner.png and b/images/spinner.png differ
diff --git a/locale/de_DE/translations.ts b/locale/de_DE/translations.ts
index 5525e53e..89a2c581 100644
--- a/locale/de_DE/translations.ts
+++ b/locale/de_DE/translations.ts
@@ -4487,5 +4487,464 @@
Server wechseln
+
+
+ Verwenden Sie das generierte Splashscreen-Bild als Jellyfin-Hintergrund. Jellyfin muss geschlossen und erneut geöffnet werden, damit die Änderung wirksam wird.
+ Description for option in Setting Screen
+
+
+
+ Splashscreen als Hintergrund für die Startseite verwenden
+ Option Title in user setting screen
+
+
+
+ Optionen, die das Design von Jellyfin verändern.
+ Description for Design Elements user settings.
+
+
+
+ Designelemente
+
+
+
+ Verwenden Sie das generierte Splashscreen-Bild als Hintergrund für Jellyfin's Bildschirmschoner.
+
+
+
+ Optionen für Jellyfin's Bildschirmschoner.
+ Description for Screensaver user settings.
+
+
+
+ Splashscreen als Bildschirmschoner-Hintergrund verwenden
+ Option Title in user setting screen
+
+
+
+ Bildschirmschoner
+
+
+
+ Wenn diese Option aktiviert ist, werden die Bilder von nicht angesehenen Episoden unscharf dargestellt.
+
+
+
+ Optionen für Serien.
+ Description for TV Shows user settings.
+
+
+
+ Optionen für Detailseiten.
+ Description for Detail Page user settings.
+
+
+
+ Detailseite
+
+
+
+ Verwenden Sie die Schaltfläche "Wiederholen", um langsam zum ersten Element im Ordner zu animieren. (Wenn diese Funktion deaktiviert ist, wird der Ordner sofort auf das erste Element zurückgesetzt)
+ Description for option in Setting Screen
+
+
+
+ Zurück zum Seitenanfang
+ UI -> Media Grid -> Item Title in user setting screen.
+
+
+
+ Bei der Authentifizierung über Quick Connect ist ein Fehler aufgetreten.
+
+
+
+ (Dialog wird automatisch geschlossen)
+
+
+
+ Hier ist dein Quick Connect Code:
+
+
+
+ Quick Connect
+
+
+
+ %1 von %2
+ Item position and count. %1 = current item. %2 = total number of items
+
+
+
+ Zur Episode gehen
+ Continue Watching Popup Menu - Navigate to the Episode Detail Page
+
+
+
+ Zur Staffel gehen
+ Continue Watching Popup Menu - Navigate to the Season Page
+
+
+
+ Zur Serie gehen
+ Continue Watching Popup Menu - Navigate to the Series Detail Page
+
+
+
+ Als Gesehen markieren
+ Button Text - When pressed, marks item as Warched
+
+
+
+ Als Favoriten markieren
+ Button Text - When pressed, sets item as Favorite
+
+
+
+ Zeigt die Anzahl der Objekte in der Bibliothek und den Index des ausgewählten Objekts an.
+ Description for option in Setting Screen
+
+
+
+ Die Titel werden immer unter den Plakatbildern angezeigt. (Wenn deaktiviert, wird der Titel nur unter dem hervorgehobenen Element angezeigt)
+ Description for option in Setting Screen
+
+
+
+ Benutzeroberfläche
+ Title for User Interface section in user setting screen.
+
+
+
+ Deaktiviert
+
+
+
+ Aktiviert
+
+
+
+ Unterstützung der direkten Wiedergabe von MPEG-2-Inhalten (z. B. Live-TV). Dies verhindert die Transkodierung von MPEG-2-Inhalten, verbraucht aber deutlich mehr Bandbreite
+ Settings Menu - Description for option
+
+
+
+ MPEG-2-Support
+ Settings Menu - Title for option
+
+
+
+ Wiedergabe
+ Title for Playback section in user setting screen.
+
+
+
+ Version
+
+
+
+ Beim Abspielen des Titels ist ein Fehler aufgetreten. Der Server hat zur Transkodierung erforderliche Daten nicht zur Verfügung gestellt.
+ Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url
+
+
+
+ Fehler beim Abruf von Wiedergabe-Informationen
+ Dialog Title: Received error from server when trying to get information about the selected item for playback
+
+
+
+ ...oder gebe die URL per Hand ein:
+ Instructions on initial app launch when the user is asked to manually enter a server URL
+
+
+
+ Wähle einen Jellyfin-Server aus dem lokalen Netzwerk
+ Instructions on initial app launch when the user is asked to pick a server from a list
+
+
+
+ Gebe den Servernamen oder die IP-Adresse ein
+ Title of KeyboardDialog when manually entering a server URL
+
+
+
+ Der angefragte Inhalt konnte auf dem Server nicht gefunden werden
+ Content of message box when the requested content is not found on the server
+
+
+
+ Unbekannt
+ Title for a cast member for which we have no information for
+
+
+
+ Nicht gefunden
+ Title of message box when the requested content is not found on the server
+
+
+
+ Verbindungsaufbau mit dem Server
+ Message to display to user while client is attempting to connect to the server
+
+
+
+ Schließen
+
+
+
+ Serienaufnahme abbrechen
+
+
+
+ Aufnahme abbrechen
+
+
+
+ Serie aufnehmen
+
+
+
+ Aufnehmen
+
+
+
+ Kanal anzeigen
+
+
+
+ TV-Programm
+ Menu option for showing Live TV Guide / Schedule
+
+
+
+ Kanäle
+ Menu option for showing Live TV Channel List
+
+
+
+ Wiederholung
+ If TV Shows has previously been broadcasted
+
+
+
+ Live
+ If TV Show is being broadcast live (not pre-recorded)
+
+
+
+ Endet um
+ (Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00)
+
+
+
+ Endete um
+ (Past Tense) For defining time when a program will ended (e.g. Ended at 08:00)
+
+
+
+ Startet
+ (Future Tense) For defining a day and time when a program will start (e.g. Starts Wednesday, 08:00)
+
+
+
+ Startet um
+ (Future Tense) For defining time when a program will start today (e.g. Starts at 08:00)
+
+
+
+ Gestartet
+ (Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00)
+
+
+
+ Gestartet um
+ (Past Tense) For defining time when a program started today (e.g. Started at 08:00)
+
+
+
+ Samstag
+ Day of Week
+
+
+
+ Freitag
+ Day of Week
+
+
+
+ Donnerstag
+ Day of Week
+
+
+
+ Mittwoch
+ Day of Week
+
+
+
+ Dienstag
+ Day of Week
+
+
+
+ Montag
+ Day of Week
+
+
+
+ Sonntag
+ Day of Week
+
+
+
+ morgen
+ Next day
+
+
+
+ gestern
+ Previous day
+
+
+
+ heute
+ Current day
+
+
+
+ TV-Sendungen
+
+
+
+ Filme
+
+
+
+ Ähnliches
+
+
+
+ Besetzung & Mitwirkende
+
+
+
+ Alter
+
+
+
+ Gestorben
+
+
+
+ Geboren
+
+
+ Title of Tab for options to filter library content
+
+ Filter
+
+
+ Title of Tab for options to sort library content
+
+ Sortieren
+
+
+ Title of Tab for switching "views" when looking at a library
+
+ Anzeigen
+
+
+
+ Laufzeit
+
+
+
+ Erscheinungsdatum
+
+
+
+ Wiedergabeanzahl
+
+
+
+ Altersfreigabe
+
+
+
+ Abgespielt am
+
+
+
+ Hinzugefügt am
+
+
+
+ Kritikerwertung
+
+
+
+ IMDb Bewertung
+
+
+ Name or Title field of media item
+
+ Name
+
+
+ Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)
+
+ %1 enthält keine Einträge
+
+
+
+ Laden der Kanaldaten vom Server nicht möglich
+
+
+
+ Fehler beim Laden der Kanaldaten
+
+
+
+ Lade Kanaldaten
+
+
+
+ Beim Abspielen des Inhalts ist ein Problem aufgetreten.
+ Dialog detail when error occurs during playback
+
+
+
+ Es ist ein Fehler beim Abrufen der Daten vom Server für diesen Eintrag aufgetreten.
+ Dialog detail when unable to load Content from Server
+
+
+
+ Fehler beim Abspielen
+ Dialog title when error occurs during playback
+
+
+
+ Fehler beim Abrufen der Inhalte
+ Dialog title when unable to load Content from Server
+
+
+
+ Läuft gerade
+
+
+
+ Gespeicherte Löschen
+
+
+
+ Login-Daten speichern?
+
+
+
+ Abmelden
+
+
+
+ Server wechseln
+
diff --git a/locale/en_GB/translations.ts b/locale/en_GB/translations.ts
index 32c18212..8a8f3b21 100644
--- a/locale/en_GB/translations.ts
+++ b/locale/en_GB/translations.ts
@@ -729,5 +729,111 @@
Save Credentials?
+
+
+ Version
+
+
+
+ An error was encountered while playing this item. Server did not provide required transcoding data.
+ Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url
+
+
+
+ Error Getting Playback Information
+ Dialog Title: Received error from server when trying to get information about the selected item for playback
+
+
+
+ …or enter server URL manually:
+ Instructions on initial app launch when the user is asked to manually enter a server URL
+
+
+
+ Pick a Jellyfin server from the local network
+ Instructions on initial app launch when the user is asked to pick a server from a list
+
+
+
+ Enter the server name or IP address
+ Title of KeyboardDialog when manually entering a server URL
+
+
+
+ Unknown
+ Title for a cast member for which we have no information for
+
+
+
+ Close
+
+
+
+ Cancel Series Recording
+
+
+
+ Cancel Recording
+
+
+
+ Record Series
+
+
+
+ Record
+
+
+
+ View Channel
+
+
+
+ TV Shows
+
+
+
+ Films
+
+
+
+ Special Features
+
+
+ Press 'OK' to Close
+
+
+
+
+ More Like This
+
+
+
+ Cast & Crew
+
+
+
+ Age
+
+
+
+ Died
+
+
+
+ Born
+
+
+
+ On Now
+
+
+
+ Delete Saved
+
+
+
+ Save Credentials?
+
diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts
index 8bf7cc24..3a20ab52 100644
--- a/locale/en_US/translations.ts
+++ b/locale/en_US/translations.ts
@@ -574,6 +574,17 @@
There was an error authenticating via Quick Connect.
+
+ Networks
+
+
+
+ Studios
+
+
+
+ Shows
+ Return to TopUI -> Media Grid -> Item Title in user setting screen.
@@ -656,5 +667,15 @@
Use generated splashscreen image as Jellyfin home background. Jellyfin will need to be closed and reopened for change to take effect.Description for option in Setting Screen
+
+
+ Cinema mode
+ Settings Menu - Title for option
+
+
+
+ Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.
+ Settings Menu - Description for option
+
diff --git a/locale/fr/translations.ts b/locale/fr/translations.ts
index 27e62357..97dc5c6d 100644
--- a/locale/fr/translations.ts
+++ b/locale/fr/translations.ts
@@ -1990,5 +1990,269 @@
Supprimer les valeurs enregistrées
+
+
+ Âge
+
+
+
+ Décès
+
+
+
+ Naissance
+
+
+ Title of Tab for options to filter library content
+
+ Filtre
+
+
+ Title of Tab for options to sort library content
+
+ Trier
+
+
+
+ Durée
+
+
+
+ Date de sortie
+
+
+
+ Nombre de lecture
+
+
+
+ Date de lecture
+
+
+
+ Date d'ajout
+
+
+
+ Note des critiques
+
+
+
+ Classement IMDb
+
+
+ Name or Title field of media item
+
+ Nom
+
+
+ Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)
+
+ %1 ne contient aucun élément
+
+
+
+ Impossible de charger les données de la chaîne à partir du serveur
+
+
+
+ Erreur lors du chargement des données de la chaîne
+
+
+
+ Chargement des données de la chaîne
+
+
+
+ Une erreur s'est produite lors de la lecture de cet élément.
+ Dialog detail when error occurs during playback
+
+
+
+ Une erreur s'est produite lors de la récupération des données de cet élément à partir du serveur.
+ Dialog detail when unable to load Content from Server
+
+
+
+ Erreur pendant la lecture
+ Dialog title when error occurs during playback
+
+
+
+ Erreur pendant la récupération du contenant
+ Dialog title when unable to load Content from Server
+
+
+
+ Actifs actuellement
+
+
+
+ Supprimer les valeurs enregistrées
+
+
+
+ Enregistrer les identifiants ?
+
+
+
+ Une erreur s'est produite lors de la lecture de cet élément. Le serveur n'a pas fourni les données de transcodage nécessaires.
+ Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url
+
+
+
+ Impossible de récupérer les informations de lecture
+ Dialog Title: Received error from server when trying to get information about the selected item for playback
+
+
+
+ ...ou entrez l'URL du serveur manuellement :
+ Instructions on initial app launch when the user is asked to manually enter a server URL
+
+
+
+ Choisissiez un serveur Jellyfin depuis le réseau local
+ Instructions on initial app launch when the user is asked to pick a server from a list
+
+
+
+ Entrer le nom ou l'adresse IP du serveur
+ Title of KeyboardDialog when manually entering a server URL
+
+
+
+ Le contenu demandé n'existe pas sur le serveur
+ Content of message box when the requested content is not found on the server
+
+
+
+ Non trouvé
+ Title of message box when the requested content is not found on the server
+
+
+
+ Connexion au serveur en cours
+ Message to display to user while client is attempting to connect to the server
+
+
+
+ Annuler l'enregistrement
+
+
+
+ Enregistrer une série
+
+
+
+ Enregistrer
+
+
+
+ Voir la chaîne
+
+
+
+ Guide des chaînes
+ Menu option for showing Live TV Guide / Schedule
+
+
+
+ Chaînes
+ Menu option for showing Live TV Channel List
+
+
+
+ Rediffusion
+ If TV Shows has previously been broadcasted
+
+
+
+ Direct
+ If TV Show is being broadcast live (not pre-recorded)
+
+
+
+ Terminé à
+ (Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00)
+
+
+
+ Termine à
+ (Past Tense) For defining time when a program will ended (e.g. Ended at 08:00)
+
+
+
+ Débutera
+ (Future Tense) For defining a day and time when a program will start (e.g. Starts Wednesday, 08:00)
+
+
+
+ Commencé à
+ (Past Tense) For defining time when a program started today (e.g. Started at 08:00)
+
+
+
+ Samedi
+ Day of Week
+
+
+
+ Vendredi
+ Day of Week
+
+
+
+ Jeudi
+ Day of Week
+
+
+
+ Mercredi
+ Day of Week
+
+
+
+ Mardi
+ Day of Week
+
+
+
+ Lundi
+ Day of Week
+
+
+
+ Dimanche
+ Day of Week
+
+
+
+ demain
+ Next day
+
+
+
+ hier
+ Previous day
+
+
+
+ aujourd'hui
+ Current day
+
+
+
+ Classification parentale
+
+
+
+ Erreur lors de la lecture
+ Dialog title when error occurs during playback
+
+
+
+ Erreur lors de la récupération du contenu
+ Dialog title when unable to load Content from Server
+
diff --git a/locale/hu/translations.ts b/locale/hu/translations.ts
index 2e4b71d8..c1044ac6 100644
--- a/locale/hu/translations.ts
+++ b/locale/hu/translations.ts
@@ -4284,5 +4284,480 @@ elemeket
Most
+
+
+ Használja a generált indítóképernyős képet Jellyfin kezdőképernyőjének háttereként. A Jellyfint újra kell indítani, hogy a változás életbe lépjen.
+ Description for option in Setting Screen
+
+
+
+ Használja a Splashscreent a kezdőképernyő háttereként
+ Option Title in user setting screen
+
+
+
+ Opciók, amelyek megváltoztatják a Jellyfin designját.
+ Description for Design Elements user settings.
+
+
+
+ Design elemek
+
+
+
+ Használja a generált splashscreen képet, a Jellyfin képernyővédő háttereként.
+
+
+
+ Használja a Splashscreent képernyővédő háttereként
+ Option Title in user setting screen
+
+
+
+ Jellyfin képernyővédőjének beállításai.
+ Description for Screensaver user settings.
+
+
+
+ Képernyőkímélő
+
+
+
+ Ha engedélyezve van, a meg nem nézett epizódok képei elmosódnak.
+
+
+
+ A nem megtekintett epizódok elhomályosítása
+ Option Title in user setting screen
+
+
+
+ TV-műsorok beállításai.
+ Description for TV Shows user settings.
+
+
+
+ Elrejti a címszó szövegét a részletező oldalakon.
+
+
+
+ Címsorok elrejtése
+ Option Title in user setting screen
+
+
+
+ Lehetőségek a részletező oldalakhoz.
+ Description for Detail Page user settings.
+
+
+
+ Részletező Oldal
+
+
+
+ A visszajátszás gombbal lassan lapozhatsz a mappa első elemére. (Ha le van tiltva, a mappa azonnal visszaáll az első elemre)
+ Description for option in Setting Screen
+
+
+
+ Vissza a tetejére
+ UI -> Media Grid -> Item Title in user setting screen.
+
+
+
+ Hiba történt a gyorscsatlakozás segítségével történő hitelesítés során.
+
+
+
+ (A párbeszédablak automatikusan bezárul)
+
+
+
+ Íme a gyorscsatlakozási kódod:
+
+
+
+ Gyorscsatlakozás
+
+
+
+ %1 a %2 -ból
+ Item position and count. %1 = current item. %2 = total number of items
+
+
+
+ Ugrás az epizódra
+ Continue Watching Popup Menu - Navigate to the Episode Detail Page
+
+
+
+ Ugrás az évadra
+ Continue Watching Popup Menu - Navigate to the Season Page
+
+
+
+ Ugrás a sorozatra
+ Continue Watching Popup Menu - Navigate to the Series Detail Page
+
+
+
+ Megnézve
+ Button Text - When pressed, marks item as Warched
+
+
+
+ Kedvenc hozzáadása
+ Button Text - When pressed, sets item as Favorite
+
+
+
+ Elemszám megjelenítése a könyvtárban.
+ Description for option in Setting Screen
+
+
+
+ Elemek száma
+ UI -> Media Grid -> Item Count in user setting screen.
+
+
+
+ Mindig mutasd a címeket a plakátképek alatt. (Ha le van tiltva, a cím csak a kiemelt elem alatt jelenik meg)
+ Description for option in Setting Screen
+
+
+
+ Fájl Címek
+ UI -> Media Grid -> Item Title in user setting screen.
+
+
+
+ Média Rács beállítások
+
+
+
+ Média Rács
+ UI -> Media Grid section in user setting screen.
+
+
+
+ Felhasználói felület
+ Title for User Interface section in user setting screen.
+
+
+
+ Kikapcsolva
+
+
+
+ Engedélyezve
+
+
+
+ Támogatja az MPEG 2 tartalom közvetlen lejátszását (pl. Élő TV). Ez megakadályozza az MPEG 2 tartalom átkódolását, de lényegesen nagyobb sávszélességet használ fel
+ Settings Menu - Description for option
+
+
+
+ MPEG 2 Támogatás
+ Settings Menu - Title for option
+
+
+
+ Lejátszás
+ Title for Playback section in user setting screen.
+
+
+
+ Verzió
+
+
+
+ Hiba történt az elem lejátszása közben. A szerver nem biztosította a szükséges transzkódolási adatokat.
+ Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url
+
+
+
+ Hiba a lejátszási információk lekérésekor
+ Dialog Title: Received error from server when trying to get information about the selected item for playback
+
+
+
+ …vagy add meg kézzel a szerver URL-jét:
+ Instructions on initial app launch when the user is asked to manually enter a server URL
+
+
+
+ Válassz ki egy Jellyfin szervert a helyi hálózatról
+ Instructions on initial app launch when the user is asked to pick a server from a list
+
+
+
+ Írd be a Szerver nevét vagy IP-címét
+ Title of KeyboardDialog when manually entering a server URL
+
+
+
+ A kért tartalom nem található a szerveren
+ Content of message box when the requested content is not found on the server
+
+
+
+ Ismeretlen
+ Title for a cast member for which we have no information for
+
+
+
+ Nem található
+ Title of message box when the requested content is not found on the server
+
+
+
+ Csatlakozás a szerverhez
+ Message to display to user while client is attempting to connect to the server
+
+
+
+ Bezárás
+
+
+
+ Sorozatfelvétel leállítása
+
+
+
+ Felvétel megállítása
+
+
+
+ Sorozat felvétele
+
+
+
+ Felvétel
+
+
+
+ Csatorna Megtekintése
+
+
+
+ Műsorújság
+ Menu option for showing Live TV Guide / Schedule
+
+
+
+ Csatornák
+ Menu option for showing Live TV Channel List
+
+
+
+ Ismétlés
+ If TV Shows has previously been broadcasted
+
+
+
+ Élő
+ If TV Show is being broadcast live (not pre-recorded)
+
+
+
+ Vége volt
+ (Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00)
+
+
+
+ Vége lett
+ (Past Tense) For defining time when a program will ended (e.g. Ended at 08:00)
+
+
+
+ Kezdődni fog
+ (Future Tense) For defining a day and time when a program will start (e.g. Starts Wednesday, 08:00)
+
+
+
+ Kezdődik majd
+ (Future Tense) For defining time when a program will start today (e.g. Starts at 08:00)
+
+
+
+ Kezdődött
+ (Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00)
+
+
+
+ Ekkor kezdődött
+ (Past Tense) For defining time when a program started today (e.g. Started at 08:00)
+
+
+
+ Szombat
+ Day of Week
+
+
+
+ Péntek
+ Day of Week
+
+
+
+ Csütörtök
+ Day of Week
+
+
+
+ Szerda
+ Day of Week
+
+
+
+ Kedd
+ Day of Week
+
+
+
+ Hétfő
+ Day of Week
+
+
+
+ Vasárnap
+ Day of Week
+
+
+
+ holnap
+ Next day
+
+
+
+ tegnap
+ Previous day
+
+
+
+ ma
+ Current day
+
+
+
+ TV Sorozatok
+
+
+
+ Filmek
+
+
+
+ Sajátosságok
+
+
+ Press 'OK' to Close
+
+
+
+
+ Több hasonló
+
+
+
+ Szereplők & Stáb
+
+
+
+ Kor
+
+
+
+ Elhunyt
+
+
+
+ Született
+
+
+ Title of Tab for options to filter library content
+
+ Szűrő
+
+
+ Title of Tab for options to sort library content
+
+ Rendezés
+
+
+ Title of Tab for switching "views" when looking at a library
+
+ Nézet
+
+
+
+ Játékidő
+
+
+
+ Megjelenés dátuma
+
+
+
+ Lejátszások Száma
+
+
+
+ Korhatár
+
+
+
+ Utoljára lejátszva
+
+
+
+ Hozzáadva
+
+
+
+ Kritikusok Értékelése
+
+
+
+ IMDb Értékelés
+
+
+ Name or Title field of media item
+
+ Név
+
+
+ Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)
+
+ Ez a(z) %1 nem tartalmaz elemeket
+
+
+
+ Nem lehet betölteni a csatornaadatokat a szerverről
+
+
+
+ Hiba történt a csatornaadatok betöltésekor
+
+
+
+ Csatornaadatok betöltése
+
+
+
+ Hiba történt az elem lejátszása közben.
+ Dialog detail when error occurs during playback
+
+
+
+ Hiba történt az elem(ek) betöltése során a szerverről.
+ Dialog detail when unable to load Content from Server
+
+
+
+ Hiba történt a lejátszás közben
+ Dialog title when error occurs during playback
+
diff --git a/package-lock.json b/package-lock.json
index 8a2ccffe..34f440b3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,7 +13,7 @@
},
"devDependencies": {
"@rokucommunity/bslint": "0.7.1",
- "brighterscript": "0.51.4",
+ "brighterscript": "0.52.3",
"rooibos-cli": "1.4.0"
}
},
@@ -760,9 +760,9 @@
}
},
"node_modules/brighterscript": {
- "version": "0.51.4",
- "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.51.4.tgz",
- "integrity": "sha512-/mxXy+fU8HM6u3B0lO8mBsgucTXgVz3dyeaVHwvF0N0MS36Q1CQWI4KliLQ8ko1uVP6Csax9ZOGCJF8hW0GcGg==",
+ "version": "0.52.3",
+ "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.52.3.tgz",
+ "integrity": "sha512-kglNHAfthxv+SFAjddu1h6NqdWJ0p+InfRuAFfUMwr+EigcwKuATkpzPticWQt1tWuOTm3J8v2RJ0JvPpV/jiA==",
"dev": true,
"dependencies": {
"@rokucommunity/bslib": "^0.1.1",
@@ -775,9 +775,9 @@
"cross-platform-clear-console": "^2.3.0",
"debounce-promise": "^3.1.0",
"eventemitter3": "^4.0.0",
+ "fast-glob": "^3.2.11",
"file-url": "^3.0.0",
- "fs-extra": "^7.0.1",
- "glob": "^7.1.6",
+ "fs-extra": "^8.0.0",
"jsonc-parser": "^2.3.0",
"long": "^3.2.0",
"luxon": "^1.8.3",
@@ -785,7 +785,7 @@
"moment": "^2.23.0",
"p-settle": "^2.1.0",
"parse-ms": "^2.1.0",
- "roku-deploy": "^3.7.0",
+ "roku-deploy": "^3.7.1",
"serialize-error": "^7.0.1",
"source-map": "^0.7.3",
"vscode-languageserver": "7.0.0",
@@ -1173,12 +1173,12 @@
}
},
"node_modules/brighterscript/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"dependencies": {
- "graceful-fs": "^4.1.2",
+ "graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
@@ -1250,9 +1250,9 @@
}
},
"node_modules/brighterscript/node_modules/source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
"dev": true,
"engines": {
"node": ">= 8"
@@ -4109,9 +4109,9 @@
}
},
"node_modules/moment": {
- "version": "2.29.3",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
- "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==",
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"engines": {
"node": "*"
}
@@ -4802,9 +4802,9 @@
}
},
"node_modules/roku-deploy": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/roku-deploy/-/roku-deploy-3.7.0.tgz",
- "integrity": "sha512-+MBppc3q7ZEhzXu86O43mITxa+ro4hkCCXt4UhsWDqvCNx7w4b6CHzjrRAXYtdGQoDe6xqZjJhqCqC/YytJqWA==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/roku-deploy/-/roku-deploy-3.7.1.tgz",
+ "integrity": "sha512-xXTYNr4Ug+Kr+bnhDqlJDcbuu6rg8x0MFIpA+36jbpJcqsI6ekbWzRh2QhUG6aZ4F8+zKt8jZFIkZDeyooJJfQ==",
"dependencies": {
"chalk": "^2.4.2",
"dateformat": "^3.0.3",
@@ -6471,9 +6471,9 @@
}
},
"brighterscript": {
- "version": "0.51.4",
- "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.51.4.tgz",
- "integrity": "sha512-/mxXy+fU8HM6u3B0lO8mBsgucTXgVz3dyeaVHwvF0N0MS36Q1CQWI4KliLQ8ko1uVP6Csax9ZOGCJF8hW0GcGg==",
+ "version": "0.52.3",
+ "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.52.3.tgz",
+ "integrity": "sha512-kglNHAfthxv+SFAjddu1h6NqdWJ0p+InfRuAFfUMwr+EigcwKuATkpzPticWQt1tWuOTm3J8v2RJ0JvPpV/jiA==",
"dev": true,
"requires": {
"@rokucommunity/bslib": "^0.1.1",
@@ -6486,9 +6486,9 @@
"cross-platform-clear-console": "^2.3.0",
"debounce-promise": "^3.1.0",
"eventemitter3": "^4.0.0",
+ "fast-glob": "^3.2.11",
"file-url": "^3.0.0",
- "fs-extra": "^7.0.1",
- "glob": "^7.1.6",
+ "fs-extra": "^8.0.0",
"jsonc-parser": "^2.3.0",
"long": "^3.2.0",
"luxon": "^1.8.3",
@@ -6496,7 +6496,7 @@
"moment": "^2.23.0",
"p-settle": "^2.1.0",
"parse-ms": "^2.1.0",
- "roku-deploy": "^3.7.0",
+ "roku-deploy": "^3.7.1",
"serialize-error": "^7.0.1",
"source-map": "^0.7.3",
"vscode-languageserver": "7.0.0",
@@ -6578,12 +6578,12 @@
}
},
"fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
- "graceful-fs": "^4.1.2",
+ "graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
@@ -6634,9 +6634,9 @@
"dev": true
},
"source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
"dev": true
},
"supports-color": {
@@ -9134,9 +9134,9 @@
}
},
"moment": {
- "version": "2.29.3",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
- "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"ms": {
"version": "2.0.0",
@@ -9653,9 +9653,9 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
},
"roku-deploy": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/roku-deploy/-/roku-deploy-3.7.0.tgz",
- "integrity": "sha512-+MBppc3q7ZEhzXu86O43mITxa+ro4hkCCXt4UhsWDqvCNx7w4b6CHzjrRAXYtdGQoDe6xqZjJhqCqC/YytJqWA==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/roku-deploy/-/roku-deploy-3.7.1.tgz",
+ "integrity": "sha512-xXTYNr4Ug+Kr+bnhDqlJDcbuu6rg8x0MFIpA+36jbpJcqsI6ekbWzRh2QhUG6aZ4F8+zKt8jZFIkZDeyooJJfQ==",
"requires": {
"chalk": "^2.4.2",
"dateformat": "^3.0.3",
diff --git a/package.json b/package.json
index 342ce708..0bd4abba 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
},
"devDependencies": {
"@rokucommunity/bslint": "0.7.1",
- "brighterscript": "0.51.4",
+ "brighterscript": "0.52.3",
"rooibos-cli": "1.4.0"
},
"scripts": {
diff --git a/settings/settings.json b/settings/settings.json
index 0eb5594c..b934e760 100644
--- a/settings/settings.json
+++ b/settings/settings.json
@@ -16,6 +16,13 @@
"settingName": "playback.tryDirect.h264ProfileLevel",
"type": "bool",
"default": "true"
+ },
+ {
+ "title": "Cinema mode",
+ "description": "Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.",
+ "settingName": "playback.cinemamode",
+ "type": "bool",
+ "default": "false"
}
]
},
diff --git a/source/Main.brs b/source/Main.brs
index a14eb3c4..687ef9ff 100644
--- a/source/Main.brs
+++ b/source/Main.brs
@@ -63,7 +63,7 @@ sub Main (args as dynamic) as void
if (args.mediaType <> invalid) and (args.contentId <> invalid)
video = CreateVideoPlayerGroup(args.contentId)
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
@@ -104,7 +104,7 @@ sub Main (args as dynamic) as void
else
video = CreateVideoPlayerGroup(itemNode.id)
end if
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
end if
end if
@@ -123,7 +123,7 @@ sub Main (args as dynamic) as void
else
video = CreateVideoPlayerGroup(video_id)
end if
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
end if
else if selectedItem.type = "Series"
@@ -145,7 +145,7 @@ sub Main (args as dynamic) as void
video = CreateVideoPlayerGroup(video_id)
dialog.close = true
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
@@ -217,7 +217,7 @@ sub Main (args as dynamic) as void
else
video = CreateVideoPlayerGroup(video_id)
end if
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
end if
else if isNodeEvent(msg, "search_value")
@@ -263,7 +263,7 @@ sub Main (args as dynamic) as void
video_id = group.id
video = CreateVideoPlayerGroup(video_id, mediaSourceId, audio_stream_idx)
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
end if
@@ -383,7 +383,7 @@ sub Main (args as dynamic) as void
info = msg.GetInfo()
if info.DoesExist("mediatype") and info.DoesExist("contentid")
video = CreateVideoPlayerGroup(info.contentId)
- if video <> invalid
+ if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs
index d2005413..b67291cc 100644
--- a/source/ShowScenes.brs
+++ b/source/ShowScenes.brs
@@ -455,10 +455,13 @@ sub CreateSidePanel(buttons, options)
group.options = options
end sub
-function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1, forceTranscoding = false)
+function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1, forceTranscoding = false, showIntro = true)
+
' Video is Playing
- video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), forceTranscoding)
+ video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), showIntro)
+
if video = invalid then return invalid
+ if video.errorMsg = "introaborted" then return video
video.observeField("selectSubtitlePressed", m.port)
video.observeField("state", m.port)
diff --git a/source/VideoPlayer.brs b/source/VideoPlayer.brs
index 774de6e1..1243c8f6 100644
--- a/source/VideoPlayer.brs
+++ b/source/VideoPlayer.brs
@@ -1,9 +1,12 @@
-function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1, forceTranscoding = false)
-
+function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1, forceTranscoding = false, showIntro = true)
' Get video controls and UI
video = CreateObject("roSGNode", "JFVideo")
video.id = id
- AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx, -1, forceTranscoding)
+ AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx, -1, forceTranscoding, showIntro)
+
+ if video.errorMsg = "introaborted"
+ return video
+ end if
if video.content = invalid
return invalid
@@ -16,8 +19,7 @@ function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle
return video
end function
-sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1, forceTranscoding = false)
-
+sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1, forceTranscoding = false, showIntro = true)
video.content = createObject("RoSGNode", "ContentNode")
meta = ItemMetaData(video.id)
m.videotype = meta.type
@@ -140,6 +142,16 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
end if
end if
+ ' Don't attempt to play an intro for an intro video
+ if showIntro
+ ' Do not play intros when resuming playback
+ if playbackPosition = 0
+ if not PlayIntroVideo(video.id, audio_stream_idx)
+ video.errorMsg = "introaborted"
+ return
+ end if
+ end if
+ end if
video.content.PlayStart = int(playbackPosition / 10000000)
@@ -170,6 +182,10 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
video.container = getContainerType(meta)
+ if playbackInfo.MediaSources[0] = invalid
+ playbackInfo = meta.json
+ end if
+
subtitles = sortSubtitles(meta.id, playbackInfo.MediaSources[0].MediaStreams)
video.Subtitles = subtitles["all"]
@@ -259,6 +275,43 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
end sub
+function PlayIntroVideo(video_id, audio_stream_idx) as boolean
+ ' Intro videos only play if user has cinema mode setting enabled
+ if get_user_setting("playback.cinemamode") = "true"
+
+ ' Check if server has intro videos setup and available
+ introVideos = GetIntroVideos(video_id)
+
+ if introVideos = invalid then return true
+
+ if introVideos.TotalRecordCount > 0
+ ' Bypass joke pre-roll
+ if lcase(introVideos.items[0].name) = "rick roll'd" then return true
+
+ introVideo = VideoPlayer(introVideos.items[0].id, introVideos.items[0].id, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), false)
+
+ port = CreateObject("roMessagePort")
+ introVideo.observeField("state", port)
+ m.global.sceneManager.callFunc("pushScene", introVideo)
+ introPlaying = true
+
+ while introPlaying
+ msg = wait(0, port)
+ if type(msg) = "roSGNodeEvent"
+ if msg.GetData() = "finished"
+ m.global.sceneManager.callFunc("clearPreviousScene")
+ introPlaying = false
+ else if msg.GetData() = "stopped"
+ introPlaying = false
+ return false
+ end if
+ end if
+ end while
+ end if
+ end if
+ return true
+end function
+
'
' Extract array of Transcode Reasons from the content URL
' @returns Array of Strings
@@ -360,7 +413,7 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
' remove finished video node
m.global.sceneManager.callFunc("popScene")
' setup new video node
- nextVideo = CreateVideoPlayerGroup(data.Items[1].Id)
+ nextVideo = CreateVideoPlayerGroup(data.Items[1].Id, invalid, 1, false)
if nextVideo <> invalid
m.global.sceneManager.callFunc("pushScene", nextVideo)
else
diff --git a/source/api/Items.brs b/source/api/Items.brs
index fb5fa77d..5311b0df 100644
--- a/source/api/Items.brs
+++ b/source/api/Items.brs
@@ -220,6 +220,16 @@ function CreateInstantMix(id as string)
return getJson(resp)
end function
+' Get Intro Videos for an item
+function GetIntroVideos(id as string)
+ url = Substitute("Users/{0}/Items/{1}/Intros", get_setting("active_user"), id)
+ resp = APIRequest(url, {
+ "UserId": get_setting("active_user")
+ })
+
+ return getJson(resp)
+end function
+
function AudioStream(id as string)
songData = AudioItem(id)