Merge branch 'unstable' into post-task-device-profile

This commit is contained in:
Charles Ewert 2023-09-12 19:05:05 -04:00 committed by GitHub
commit 037a6d01af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1316 additions and 336 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
* @jellyfin/roku

View File

@ -12,7 +12,7 @@ jobs:
dev: dev:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3 - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
with: with:
node-version: "lts/*" node-version: "lts/*"
@ -23,7 +23,7 @@ jobs:
run: npm run ropm run: npm run ropm
- name: Build app - name: Build app
run: npm run build run: npm run build
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3 - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
with: with:
name: Jellyfin-Roku-dev-${{ github.sha }} name: Jellyfin-Roku-dev-${{ github.sha }}
path: ${{ github.workspace }}/build/staging path: ${{ github.workspace }}/build/staging

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout master (the latest release) - name: Checkout master (the latest release)
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
ref: master ref: master
- name: Install jq to parse json - name: Install jq to parse json
@ -33,7 +33,7 @@ jobs:
- name: Save old Makefile version - name: Save old Makefile version
run: awk 'BEGIN { FS=" = " } /^VERSION/ { print "oldMakeVersion="$2; }' Makefile >> $GITHUB_ENV run: awk 'BEGIN { FS=" = " } /^VERSION/ { print "oldMakeVersion="$2; }' Makefile >> $GITHUB_ENV
- name: Checkout PR branch - name: Checkout PR branch
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- name: Save new package.json version - name: Save new package.json version
run: echo "newPackVersion=$(jq -r ".version" package.json)" >> $GITHUB_ENV run: echo "newPackVersion=$(jq -r ".version" package.json)" >> $GITHUB_ENV
- name: package.json version must be updated - name: package.json version must be updated
@ -61,7 +61,7 @@ jobs:
prod: prod:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3 - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
with: with:
node-version: "lts/*" node-version: "lts/*"
@ -72,7 +72,7 @@ jobs:
run: npm run ropm run: npm run ropm
- name: Build app for production - name: Build app for production
run: npm run build-prod run: npm run build-prod
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3 - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
with: with:
name: Jellyfin-Roku-v${{ env.newManVersion }}-${{ github.sha }} name: Jellyfin-Roku-v${{ env.newManVersion }}-${{ github.sha }}
path: ${{ github.workspace }}/build/staging path: ${{ github.workspace }}/build/staging

39
.github/workflows/roku-analysis.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: roku-analysis
on:
pull_request:
push:
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
jobs:
static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
with:
node-version: "lts/*"
cache: "npm"
- name: NPM install
run: npm ci
- name: Install roku module dependencies
run: npm run ropm
- name: Build dev app
if: env.BRANCH_NAME != 'master'
run: npm run build
- name: Build app for production
if: env.BRANCH_NAME == 'master'
run: npm run build-prod
- name: Use Java 17
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3
with:
distribution: "temurin"
java-version: "17"
- name: Download the Static Channel Analysis CLI
run: |
curl -sSL "https://devtools.web.roku.com/static-channel-analysis/sca-cmd.zip" -o sca-cmd.zip
unzip sca-cmd.zip
- name: Run Roku Static Analysis
run: ./sca-cmd/bin/sca-cmd ${{ github.workspace }}/build/staging --exit error

View File

@ -188,7 +188,6 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
if not fully_external if not fully_external
video.content = authRequest(video.content) video.content = authRequest(video.content)
end if end if
end sub end sub
sub addVideoContentURL(video, mediaSourceId, audio_stream_idx, fully_external) sub addVideoContentURL(video, mediaSourceId, audio_stream_idx, fully_external)
@ -406,8 +405,10 @@ function FindPreferredAudioStream(streams as dynamic) as integer
if preferredLanguage <> invalid if preferredLanguage <> invalid
for i = 0 to streams.Count() - 1 for i = 0 to streams.Count() - 1
if LCase(streams[i].Type) = "audio" and LCase(streams[i].Language) = LCase(preferredLanguage) if LCase(streams[i].Type) = "audio"
return i if streams[i].Language <> invalid and LCase(streams[i].Language) = LCase(preferredLanguage)
return i
end if
end if end if
end for end for
end if end if

View File

@ -22,7 +22,7 @@ sub init()
m.nextEpisodeButton = m.top.findNode("nextEpisode") m.nextEpisodeButton = m.top.findNode("nextEpisode")
m.nextEpisodeButton.text = tr("Next Episode") m.nextEpisodeButton.text = tr("Next Episode")
m.nextEpisodeButton.setFocus(false) m.nextEpisodeButton.setFocus(false)
m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"] m.nextupbuttonseconds = m.global.session.user.settings["playback.nextupbuttonseconds"].ToInt()
m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton") m.showNextEpisodeButtonAnimation = m.top.findNode("showNextEpisodeButton")
m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton") m.hideNextEpisodeButtonAnimation = m.top.findNode("hideNextEpisodeButton")

View File

@ -73,7 +73,7 @@ sub loadItems()
params["limit"] = 24 params["limit"] = 24
params["EnableTotalRecordCount"] = false params["EnableTotalRecordCount"] = false
maxDaysInNextUp = m.global.session.user.settings["ui.details.maxdaysnextup"] maxDaysInNextUp = m.global.session.user.settings["ui.details.maxdaysnextup"].ToInt()
if isValid(maxDaysInNextUp) if isValid(maxDaysInNextUp)
if maxDaysInNextUp > 0 if maxDaysInNextUp > 0
dateToday = CreateObject("roDateTime") dateToday = CreateObject("roDateTime")

View File

@ -11337,5 +11337,107 @@
<translation>Auswählen, wann Titel angezeigt werden sollen</translation> <translation>Auswählen, wann Titel angezeigt werden sollen</translation>
<extracomment>Settings Menu - Description for option</extracomment> <extracomment>Settings Menu - Description for option</extracomment>
</message> </message>
<message>
<source>Movies (Presentation)</source>
<translation>Filme (Präsentation)</translation>
<extracomment>Movie library view option</extracomment>
</message>
<message>
<source>Started at</source>
<translation>Gestartet um</translation>
<extracomment>(Past Tense) For defining time when a program started today (e.g. Started at 08:00) </extracomment>
</message>
<message>
<source>Movies (Grid)</source>
<translation>Filme (Raster)</translation>
<extracomment>Movie library view option</extracomment>
</message>
<message>
<source>An error was encountered while playing this item. Server did not provide required transcoding data.</source>
<translation>Bei der Wiedergabe dieses Elements ist ein Fehler aufgetreten. Der Server hat die erforderlichen Transcodierungsdaten nicht bereitgestellt.</translation>
<extracomment>Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url</extracomment>
</message>
<message>
<source>Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.</source>
<translation>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</translation>
<extracomment>Settings Menu - Description for option</extracomment>
</message>
<message>
<source>Version</source>
<translation>Version</translation>
</message>
<message>
<source>MPEG-2</source>
<translation>MPEG-2</translation>
<extracomment>Name of codec used in settings menu</extracomment>
</message>
<message>
<source>MPEG-4</source>
<translation>MPEG-4</translation>
<extracomment>Name of codec used in settings menu</extracomment>
</message>
<message>
<source>Playback</source>
<translation>Wiedergabe</translation>
<extracomment>Title for Playback section in user setting screen.</extracomment>
</message>
<message>
<source>Special Features</source>
<translation>Extras</translation>
</message>
<message>
<source>Error Getting Playback Information</source>
<translation>Fehler beim Abrufen der Wiedergabeinformationen</translation>
<extracomment>Dialog Title: Received error from server when trying to get information about the selected item for playback</extracomment>
</message>
<message>
<source>Additional Parts</source>
<translation>Zusätzliche Inhalte</translation>
<extracomment>Additional parts of a video</extracomment>
</message>
<message>
<source>Started</source>
<translation>Gestartet</translation>
<extracomment>(Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00) </extracomment>
</message>
<message>
<source>Channels</source>
<translation>Sender</translation>
<extracomment>Menu option for showing Live TV Channel List</extracomment>
</message>
<message>
<source>View Channel</source>
<translation>Sender ansehen</translation>
</message>
<message>
<source>Codec Support</source>
<translation>Codec Unterstützung</translation>
<extracomment>Settings Menu - Title for settings group related to codec support</extracomment>
</message>
<message>
<source>Enter the server name or IP address</source>
<translation>Geben Sie den Servernamen oder die IP-Adresse ein</translation>
<extracomment>Title of KeyboardDialog when manually entering a server URL</extracomment>
</message>
<message>
<source>The requested content does not exist on the server</source>
<translation>Der angeforderte Inhalt existiert nicht auf dem Server</translation>
<extracomment>Content of message box when the requested content is not found on the server</extracomment>
</message>
<message>
<source>Pick a Jellyfin server from the local network</source>
<translation>Wählen Sie einen verfügbaren Jellyfin-Server in Ihrem lokalen Netzwerk aus:</translation>
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
</message>
<message>
<source>...or enter server URL manually:</source>
<translation>Fügen Sie bitte die Server-URL manuell ein, falls kein Server vorhanden ist:</translation>
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
</message>
<message>
<source>Enable or disable Direct Play for optional codecs</source>
<translation>Aktivieren oder Deaktivieren von Direct Play für optionale Codecs</translation>
<extracomment>Settings Menu - Title for settings group related to codec support</extracomment>
</message>
</context> </context>
</TS> </TS>

View File

@ -1114,14 +1114,99 @@
<translation>Set how many seconds before the end of an episode the Next Episode button should appear. Set to 0 to disable.</translation> <translation>Set how many seconds before the end of an episode the Next Episode button should appear. Set to 0 to disable.</translation>
<extracomment>Settings Menu - Description for option</extracomment> <extracomment>Settings Menu - Description for option</extracomment>
</message> </message>
<message> <message>
<source>Direct playing</source> <source>Choose your preferred audio codec when transcoding multichannel audio.</source>
<translation>Direct playing</translation> <translation>Choose your preferred audio codec when transcoding multichannel audio.</translation>
</message> <extracomment>Settings Menu - Description for option</extracomment>
</message>
<message>
<source>Force all transcodes to use DTS instead of the default EAC3. The device must support DTS for this setting to have an effect.</source>
<translation>Force all transcodes to use DTS instead of the default EAC3. The device must support DTS for this setting to have an effect.</translation>
<extracomment>Settings Menu - Description for option</extracomment>
</message>
<message>
<source>Audio Codec Support</source>
<translation>Audio Codec Support</translation>
<extracomment>Settings Menu - Title of option</extracomment>
</message>
<message>
<source>Direct playing</source>
<translation>Direct playing</translation>
</message>
<message> <message>
<source>The source file is entirely compatible with this client and the session is receiving the file without modifications.</source> <source>The source file is entirely compatible with this client and the session is receiving the file without modifications.</source>
<translation>The source file is entirely compatible with this client and the session is receiving the file without modifications.</translation> <translation>The source file is entirely compatible with this client and the session is receiving the file without modifications.</translation>
<extracomment>Direct play info box text in GetPlaybackInfoTask.brs</extracomment> <extracomment>Direct play info box text in GetPlaybackInfoTask.brs</extracomment>
</message> </message>
<message>
<source>Maximum Resolution</source>
<translation>Maximum Resolution</translation>
<extracomment>User Setting - Title</extracomment>
</message>
<message>
<source>Set the maximum resolution when playing video files on this device.</source>
<translation>Set the maximum resolution when playing video files on this device.</translation>
<extracomment>User Setting - Description</extracomment>
</message>
<message>
<source>Off - Attempt to play all resolutions</source>
<translation>Off - Attempt to play all resolutions</translation>
<extracomment>User Setting - Option title</extracomment>
</message>
<message>
<source>Auto - Use TV resolution</source>
<translation>Auto - Use TV resolution</translation>
<extracomment>User Setting - Option title</extracomment>
</message>
<message>
<source>Mode</source>
<translation>Mode</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Value</source>
<translation>Value</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Configure the maximum resolution when playing video files on this device.</source>
<translation>Configure the maximum resolution when playing video files on this device.</translation>
<extracomment>User Setting - Description</extracomment>
</message>
<message>
<source>Apply max resolution to all files or only transcoded files.</source>
<translation>Apply max resolution to all files or only transcoded files.</translation>
<extracomment>User Setting - Description</extracomment>
</message>
<message>
<source>All files</source>
<translation>All files</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Only transcoded files</source>
<translation>Only transcoded files</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Compatibility</source>
<translation>Compatibility</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Attempt to prevent playback failures.</source>
<translation>Attempt to prevent playback failures.</translation>
<extracomment>User Setting - Setting description</extracomment>
</message>
<message>
<source>Disable HEVC</source>
<translation>Disable HEVC</translation>
<extracomment>User Setting - Setting title</extracomment>
</message>
<message>
<source>Disable the HEVC codec on this device. This may improve playback for some devices (ultra).</source>
<translation>Disable the HEVC codec on this device. This may improve playback for some devices (ultra).</translation>
<extracomment>User Setting - Setting description</extracomment>
</message>
</context> </context>
</TS> </TS>

View File

@ -2190,5 +2190,13 @@
<translation>In onda</translation> <translation>In onda</translation>
<extracomment>Aired date label</extracomment> <extracomment>Aired date label</extracomment>
</message> </message>
<message>
<source>Change Server</source>
<translation>Cambia Server</translation>
</message>
<message>
<source>Sign Out</source>
<translation>Scollegamento</translation>
</message>
</context> </context>
</TS> </TS>

View File

@ -2613,5 +2613,98 @@
<source>Save Credentials?</source> <source>Save Credentials?</source>
<translation>Salvezi credenţialele?</translation> <translation>Salvezi credenţialele?</translation>
</message> </message>
<message>
<source>Error During Playback</source>
<translation>Eroare în timpul redării</translation>
<extracomment>Dialog title when error occurs during playback</extracomment>
</message>
<message>
<comment>Title of Tab for options to sort library content</comment>
<source>TAB_SORT</source>
<translation>Sortați</translation>
</message>
<message>
<comment>Title of Tab for options to filter library content</comment>
<source>TAB_FILTER</source>
<translation>Filtrați</translation>
</message>
<message>
<source>On Now</source>
<translation>Pornit acum</translation>
</message>
<message>
<source>Special Features</source>
<translation>Caracteristici Speciale</translation>
</message>
<message>
<source>Error Retrieving Content</source>
<translation>Eroare în obținerea conținutului</translation>
<extracomment>Dialog title when unable to load Content from Server</extracomment>
</message>
<message>
<source>Born</source>
<translation>Născut/ă</translation>
</message>
<message>
<source>More Like This</source>
<translation>Mai Multe Ca Acesta</translation>
</message>
<message>
<source>Age</source>
<translation>Vârstă</translation>
</message>
<message>
<source>Movies</source>
<translation>Filme</translation>
</message>
<message>
<source>There was an error retrieving the data for this item from the server.</source>
<translation>A avut loc o eroare în obținerea datelor despre acest item al serverului.</translation>
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
</message>
<message>
<source>An error was encountered while playing this item.</source>
<translation>A avut loc o eroare în timpul redării.</translation>
<extracomment>Dialog detail when error occurs during playback</extracomment>
</message>
<message>
<source>Loading Channel Data</source>
<translation>Se încarcă datele canalului</translation>
</message>
<message>
<source>Error loading Channel Data</source>
<translation>Eroare în încărcarea datelor canalului</translation>
</message>
<message>
<source>IMDB_RATING</source>
<translation>Recenzie IMDb</translation>
</message>
<message>
<source>RELEASE_DATE</source>
<translation>Data lansării</translation>
</message>
<message>
<source>Died</source>
<translation>Decedat/ă</translation>
</message>
<message>
<source>Press &apos;OK&apos; to Close</source>
<translation>Apăsați &apos;OK&apos; pentru a închide</translation>
</message>
<message>
<source>Additional Parts</source>
<translation>Părţi Adiţionale</translation>
<extracomment>Additional parts of a video</extracomment>
</message>
<message>
<source>Sunday</source>
<translation>duminică</translation>
<extracomment>Day of Week</extracomment>
</message>
<message>
<comment>Name or Title field of media item</comment>
<source>TITLE</source>
<translation>Nume</translation>
</message>
</context> </context>
</TS> </TS>

83
package-lock.json generated
View File

@ -12,14 +12,14 @@
"dependencies": { "dependencies": {
"@rokucommunity/bslib": "0.1.1", "@rokucommunity/bslib": "0.1.1",
"bgv": "npm:button-group-vert@1.0.2", "bgv": "npm:button-group-vert@1.0.2",
"brighterscript-formatter": "1.6.31", "brighterscript-formatter": "1.6.32",
"intKeyboard": "npm:integer-keyboard@1.0.12", "intKeyboard": "npm:integer-keyboard@1.0.12",
"log": "npm:roku-log@0.11.1", "log": "npm:roku-log@0.11.1",
"sob": "npm:slide-out-button@1.0.1" "sob": "npm:slide-out-button@1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@rokucommunity/bslint": "0.8.9", "@rokucommunity/bslint": "0.8.10",
"brighterscript": "0.65.4", "brighterscript": "0.65.5",
"jshint": "2.13.6", "jshint": "2.13.6",
"markdownlint-cli2": "0.9.2", "markdownlint-cli2": "0.9.2",
"rimraf": "5.0.1", "rimraf": "5.0.1",
@ -125,9 +125,9 @@
"integrity": "sha512-2ox6EUL+UTtccTbD4dbVjZK3QHa0PHCqpoKMF8lZz9ayzzEP3iVPF8KZR6hOi6bxsIcbGXVjqmtCVkpC4P9SrA==" "integrity": "sha512-2ox6EUL+UTtccTbD4dbVjZK3QHa0PHCqpoKMF8lZz9ayzzEP3iVPF8KZR6hOi6bxsIcbGXVjqmtCVkpC4P9SrA=="
}, },
"node_modules/@rokucommunity/bslint": { "node_modules/@rokucommunity/bslint": {
"version": "0.8.9", "version": "0.8.10",
"resolved": "https://registry.npmjs.org/@rokucommunity/bslint/-/bslint-0.8.9.tgz", "resolved": "https://registry.npmjs.org/@rokucommunity/bslint/-/bslint-0.8.10.tgz",
"integrity": "sha512-7rXHcGL8XVguqzjKtsUoRvnm/g6ySJwV+xGO9n8Mc1r1zNIvjMi9Spfz1Kh8zJTXwfxOkG1X68lMAtp9bk/gxA==", "integrity": "sha512-2aaWPtt5xACm7sIaKR5ctF7f3HrjKGfTVSAT6ZGdojDsXPQanHK2+XyYX20fQVdjJFVn414UCfVkUiaO0PTtog==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
@ -533,9 +533,9 @@
} }
}, },
"node_modules/brighterscript": { "node_modules/brighterscript": {
"version": "0.65.4", "version": "0.65.5",
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.4.tgz", "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.5.tgz",
"integrity": "sha512-bp2aVhLOM1xRuZiyKx1WQp4JS8Fm6wfD7kAI4rE3YYMYeMhZ/SxTCvBtmTsaW/Z40oB8bBJXuKSuXgz2uF+ywQ==", "integrity": "sha512-xDkWIZhjTLhp6dVZ6lX7zWRyNvjdiAwZncJRnErSbqRhteNJFL7ic2UDJew9zCOYTQDrG7B85lpPpXc/1JlV+Q==",
"dependencies": { "dependencies": {
"@rokucommunity/bslib": "^0.1.1", "@rokucommunity/bslib": "^0.1.1",
"@xml-tools/parser": "^1.0.7", "@xml-tools/parser": "^1.0.7",
@ -575,11 +575,11 @@
} }
}, },
"node_modules/brighterscript-formatter": { "node_modules/brighterscript-formatter": {
"version": "1.6.31", "version": "1.6.32",
"resolved": "https://registry.npmjs.org/brighterscript-formatter/-/brighterscript-formatter-1.6.31.tgz", "resolved": "https://registry.npmjs.org/brighterscript-formatter/-/brighterscript-formatter-1.6.32.tgz",
"integrity": "sha512-XOc1LVAUXrWtCwAZeOUS/7gH5TbiEqZ0IwyAJcM7J5CxrFpMrw6NKg/Yox1oKaH1m11kcLR7KgckK5CTha0eYQ==", "integrity": "sha512-7rbNmSsj2v8iv+iSWXczSg4hC7L1zxMEwo+jZcDaMDPu0TBt4zmmCpaT0WvvvYcE8fD9I1tJ4dlTaj61QnH0QQ==",
"dependencies": { "dependencies": {
"brighterscript": "^0.65.4", "brighterscript": "^0.65.5",
"glob-all": "^3.3.0", "glob-all": "^3.3.0",
"jsonc-parser": "^3.0.0", "jsonc-parser": "^3.0.0",
"source-map": "^0.7.3", "source-map": "^0.7.3",
@ -4452,63 +4452,6 @@
"chevrotain": "7.1.1" "chevrotain": "7.1.1"
} }
}, },
"node_modules/ropm/node_modules/brighterscript": {
"version": "0.65.4",
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.4.tgz",
"integrity": "sha512-bp2aVhLOM1xRuZiyKx1WQp4JS8Fm6wfD7kAI4rE3YYMYeMhZ/SxTCvBtmTsaW/Z40oB8bBJXuKSuXgz2uF+ywQ==",
"dev": true,
"dependencies": {
"@rokucommunity/bslib": "^0.1.1",
"@xml-tools/parser": "^1.0.7",
"array-flat-polyfill": "^1.0.1",
"chalk": "^2.4.2",
"chevrotain": "^7.0.1",
"chokidar": "^3.5.1",
"clear": "^0.1.0",
"coveralls-next": "^4.2.0",
"cross-platform-clear-console": "^2.3.0",
"debounce-promise": "^3.1.0",
"eventemitter3": "^4.0.0",
"fast-glob": "^3.2.12",
"file-url": "^3.0.0",
"fs-extra": "^8.1.0",
"jsonc-parser": "^2.3.0",
"long": "^3.2.0",
"luxon": "^2.5.2",
"minimatch": "^3.0.4",
"moment": "^2.23.0",
"p-settle": "^2.1.0",
"parse-ms": "^2.1.0",
"readline": "^1.3.0",
"require-relative": "^0.8.7",
"roku-deploy": "^3.10.3",
"serialize-error": "^7.0.1",
"source-map": "^0.7.4",
"vscode-languageserver": "7.0.0",
"vscode-languageserver-protocol": "3.16.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-uri": "^2.1.1",
"xml2js": "^0.5.0",
"yargs": "^16.2.0"
},
"bin": {
"bsc": "dist/cli.js"
}
},
"node_modules/ropm/node_modules/brighterscript/node_modules/fs-extra": {
"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.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/ropm/node_modules/chevrotain": { "node_modules/ropm/node_modules/chevrotain": {
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz", "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz",

View File

@ -5,14 +5,14 @@
"dependencies": { "dependencies": {
"@rokucommunity/bslib": "0.1.1", "@rokucommunity/bslib": "0.1.1",
"bgv": "npm:button-group-vert@1.0.2", "bgv": "npm:button-group-vert@1.0.2",
"brighterscript-formatter": "1.6.31", "brighterscript-formatter": "1.6.32",
"intKeyboard": "npm:integer-keyboard@1.0.12", "intKeyboard": "npm:integer-keyboard@1.0.12",
"log": "npm:roku-log@0.11.1", "log": "npm:roku-log@0.11.1",
"sob": "npm:slide-out-button@1.0.1" "sob": "npm:slide-out-button@1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@rokucommunity/bslint": "0.8.9", "@rokucommunity/bslint": "0.8.10",
"brighterscript": "0.65.4", "brighterscript": "0.65.5",
"jshint": "2.13.6", "jshint": "2.13.6",
"markdownlint-cli2": "0.9.2", "markdownlint-cli2": "0.9.2",
"rimraf": "5.0.1", "rimraf": "5.0.1",

View File

@ -3,6 +3,19 @@
"title": "Playback", "title": "Playback",
"description": "Settings relating to playback and supported codec and media types.", "description": "Settings relating to playback and supported codec and media types.",
"children": [ "children": [
{
"title": "Audio Codec Support",
"description": "Choose your preferred audio codec when transcoding multichannel audio.",
"children": [
{
"title": "DTS",
"description": "Force all transcodes to use DTS instead of the default EAC3. The device must support DTS for this setting to have an effect.",
"settingName": "playback.forceDTS",
"type": "bool",
"default": "false"
}
]
},
{ {
"title": "Bitrate Limit", "title": "Bitrate Limit",
"description": "Configure the maximum playback bitrate.", "description": "Configure the maximum playback bitrate.",
@ -24,7 +37,85 @@
] ]
}, },
{ {
"title": "Codec Support", "title": "Compatibility",
"description": "Attempt to prevent playback failures.",
"children": [
{
"title": "Disable HEVC",
"description": "Disable the HEVC codec on this device. This may improve playback for some devices (ultra).",
"settingName": "playback.compatibility.disablehevc",
"type": "bool",
"default": "false"
}
]
},
{
"title": "Maximum Resolution",
"description": "Configure the maximum resolution when playing video files on this device.",
"children": [
{
"title": "Mode",
"description": "Apply max resolution to all files or only transcoded files.",
"settingName": "playback.resolution.mode",
"type": "radio",
"default": "transcoding",
"options": [
{
"title": "All files",
"id": "everything"
},
{
"title": "Only transcoded files",
"id": "transcoding"
}
]
},
{
"title": "Value",
"description": "Set the maximum resolution when playing video files on this device.",
"settingName": "playback.resolution.max",
"type": "radio",
"default": "auto",
"options": [
{
"title": "Off - Attempt to play all resolutions",
"id": "off"
},
{
"title": "Auto - Use TV resolution",
"id": "auto"
},
{
"title": "360p",
"id": "360"
},
{
"title": "480p",
"id": "480"
},
{
"title": "720p",
"id": "720"
},
{
"title": "1080p",
"id": "1080"
},
{
"title": "4k",
"id": "2160"
},
{
"title": "8k",
"id": "4320"
}
]
}
]
},
{
"title": "Video Codec Support",
"description": "Enable or disable Direct Play support for certain codecs.", "description": "Enable or disable Direct Play support for certain codecs.",
"children": [ "children": [
{ {
@ -51,7 +142,7 @@
] ]
}, },
{ {
"title": "Profile Level Support", "title": "Video Profile Level Support",
"description": "Attempt Direct Play of potentially unsupported profile levels", "description": "Attempt Direct Play of potentially unsupported profile levels",
"children": [ "children": [
{ {
@ -59,14 +150,14 @@
"description": "Attempt Direct Play for H.264 media with unsupported profile levels before falling back to transcoding if it fails.", "description": "Attempt Direct Play for H.264 media with unsupported profile levels before falling back to transcoding if it fails.",
"settingName": "playback.tryDirect.h264ProfileLevel", "settingName": "playback.tryDirect.h264ProfileLevel",
"type": "bool", "type": "bool",
"default": "true" "default": "false"
}, },
{ {
"title": "HEVC", "title": "HEVC",
"description": "Attempt Direct Play for HEVC media with unsupported profile levels before falling back to transcoding if it fails.", "description": "Attempt Direct Play for HEVC media with unsupported profile levels before falling back to transcoding if it fails.",
"settingName": "playback.tryDirect.hevcProfileLevel", "settingName": "playback.tryDirect.hevcProfileLevel",
"type": "bool", "type": "bool",
"default": "true" "default": "false"
} }
] ]
}, },

View File

@ -198,7 +198,7 @@ end sub
function authRequest(request as object) as object function authRequest(request as object) as object
QUOTE = Chr(34) QUOTE = Chr(34)
auth = "MediaBrowser" + " Client=" + QUOTE + "Jellyfin Roku" + QUOTE auth = "MediaBrowser" + " Client=" + QUOTE + "Jellyfin Roku" + QUOTE
auth = auth + ", Device=" + QUOTE + m.global.device.name + " (" + m.global.device.friendlyName + ")" + QUOTE auth = auth + ", Device=" + QUOTE + m.global.device.name + " (" + m.global.device.model + ")" + QUOTE
auth = auth + ", Version=" + QUOTE + m.global.app.version + QUOTE auth = auth + ", Version=" + QUOTE + m.global.app.version + QUOTE
if m.global.session.user.id <> invalid if m.global.session.user.id <> invalid

File diff suppressed because it is too large Load Diff

View File

@ -40,17 +40,75 @@ end sub
' Save information from roDeviceInfo to m.global.device ' Save information from roDeviceInfo to m.global.device
sub SaveDeviceToGlobal() sub SaveDeviceToGlobal()
deviceInfo = CreateObject("roDeviceInfo") deviceInfo = CreateObject("roDeviceInfo")
' remove special characters ' remove special characters
regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "")
filteredFriendly = regex.ReplaceAll(deviceInfo.getFriendlyName(), "") filteredFriendly = regex.ReplaceAll(deviceInfo.getFriendlyName(), "")
' parse out serial
displayName = deviceInfo.getModelDisplayName()
deviceSerial = Mid(filteredFriendly, len(displayName) + 4)
' determine max playback resolution
' https://developer.roku.com/en-ca/docs/references/brightscript/interfaces/ifdeviceinfo.md#getvideomode-as-string
videoMode = deviceInfo.GetVideoMode()
iPos = Instr(1, videoMode, "i")
pPos = Instr(1, videoMode, "p")
videoHeight = invalid
videoWidth = invalid
refreshRate = "0"
bitDepth = 8
extraData = invalid
heightToWidth = {
"480": "720",
"576": "720",
"720": "1280",
"1080": "1920",
"2160": "3840",
"4320": "7680"
}
if iPos > 0 and pPos = 0
' videMode = 000i
videoHeight = mid(videoMode, 1, iPos - 1)
' save refresh rate
if Len(videoMode) > iPos
refreshRate = mid(videoMode, iPos + 1, 2)
end if
' save whats left of string
if Len(videoMode) > iPos + 2
extraData = mid(videoMode, iPos + 3)
end if
else if iPos = 0 and pPos > 0
' videMode = 000p
videoHeight = mid(videoMode, 1, pPos - 1)
' save refresh rate
if Len(videoMode) > pPos
refreshRate = mid(videoMode, pPos + 1, 2)
end if
' save whats left of string
if Len(videoMode) > pPos + 2
extraData = mid(videoMode, pPos + 3)
end if
else
'i and p not present in videoMode
print "ERROR parsing deviceInfo.GetVideoMode()"
end if
videoWidth = heightToWidth[videoHeight]
if videoHeight = "2160" and extraData = "b10"
bitDepth = 10
else if videoHeight = "4320"
bitDepth = 12
end if
m.global.addFields({ m.global.addFields({
device: { device: {
id: deviceInfo.getChannelClientID(), id: deviceInfo.getChannelClientID(),
uuid: deviceInfo.GetRandomUUID(), uuid: deviceInfo.GetRandomUUID(),
name: deviceInfo.getModelDisplayName(), name: displayName,
friendlyName: filteredFriendly, friendlyName: filteredFriendly,
model: deviceInfo.GetModel(), model: deviceInfo.GetModel(),
modelType: deviceInfo.GetModelType(), modelType: deviceInfo.GetModelType(),
modelDetails: deviceInfo.GetModelDetails(),
serial: deviceSerial,
osVersion: deviceInfo.GetOSVersion(), osVersion: deviceInfo.GetOSVersion(),
locale: deviceInfo.GetCurrentLocale(), locale: deviceInfo.GetCurrentLocale(),
clockFormat: deviceInfo.GetClockFormat(), clockFormat: deviceInfo.GetClockFormat(),
@ -58,7 +116,12 @@ sub SaveDeviceToGlobal()
hasVoiceRemote: deviceInfo.HasFeature("voice_remote"), hasVoiceRemote: deviceInfo.HasFeature("voice_remote"),
displayType: deviceInfo.GetDisplayType(), displayType: deviceInfo.GetDisplayType(),
displayMode: deviceInfo.GetDisplayMode() displayMode: deviceInfo.GetDisplayMode(),
videoMode: videoMode,
videoHeight: videoHeight,
videoWidth: videoWidth,
videoRefresh: StrToI(refreshRate),
videoBitDepth: bitDepth
} }
}) })
end sub end sub

View File

@ -382,3 +382,13 @@ sub stopLoadingSpinner()
m.scene.dialog.close = true m.scene.dialog.close = true
end if end if
end sub end sub
' Check if a specific value is inside of an array
function arrayHasValue(arr as object, value as dynamic) as boolean
for each entry in arr
if entry = value
return true
end if
end for
return false
end function

View File

@ -234,25 +234,17 @@ namespace session
end sub end sub
' Saves the user setting to the global session. ' Saves the user setting to the global session.
' This also converts strings to boolean and integer as necessary before saving to global session ' This also converts strings to boolean as necessary before saving to global session
sub Save(name as string, value as string) sub Save(name as string, value as string)
if name = invalid or value = invalid then return if name = invalid or value = invalid then return
tmpSettingArray = m.global.session.user.settings tmpSettingArray = m.global.session.user.settings
convertedValue = value convertedValue = value
' convert to int
valueInteger = value.ToInt()
if value = "0" or valueInteger <> 0
convertedValue = valueInteger
end if
' convert to boolean ' convert to boolean
if type(value) = "String" if value = "true"
if value = "true" convertedValue = true
convertedValue = true else if value = "false"
else if value = "false" convertedValue = false
convertedValue = false
end if
end if end if
tmpSettingArray[name] = convertedValue tmpSettingArray[name] = convertedValue