Skip to content

Commit

Permalink
force aac main and he-aacv1 to be transcoded to mp3. save currently p…
Browse files Browse the repository at this point in the history
…laying video meta data to global session
  • Loading branch information
cewert committed Oct 4, 2024
1 parent 6939c1d commit a5baa30
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
7 changes: 3 additions & 4 deletions components/ItemGrid/LoadVideoContentTask.bs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "pkg:/source/utils/config.bs"
import "pkg:/source/api/Image.bs"
import "pkg:/source/api/userauth.bs"
import "pkg:/source/utils/deviceCapabilities.bs"
import "pkg:/source/utils/session.bs"

enum SubtitleSelection
notset = -2
Expand Down Expand Up @@ -71,14 +72,14 @@ end function
sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_stream_idx = 1 as integer, forceTranscoding = false as boolean)

meta = ItemMetaData(video.id)
subtitle_idx = m.top.selectedSubtitleIndex

if not isValid(meta)
video.errorMsg = "Error loading metadata"
video.content = invalid
return
end if

session.video.Update(meta)
subtitle_idx = m.top.selectedSubtitleIndex
videotype = LCase(meta.type)

' Check for any Live TV streams or Recordings coming from other places other than the TV Guide
Expand Down Expand Up @@ -196,12 +197,10 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
}
end if


' 'TODO: allow user selection of subtitle track before playback initiated, for now set to no subtitles
video.directPlaySupported = m.playbackInfo.MediaSources[0].SupportsDirectPlay
fully_external = false


' For h264/hevc video, Roku spec states that it supports specfic encoding levels
' The device can decode content with a Higher Encoding level but may play it back with certain
' artifacts. If the user preference is set, and the only reason the server says we need to
Expand Down
12 changes: 10 additions & 2 deletions components/video/VideoPlayerView.bs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "pkg:/source/utils/misc.bs"
import "pkg:/source/utils/config.bs"
import "pkg:/source/utils/session.bs"
import "pkg:/source/roku_modules/log/LogMixin.brs"

sub init()
Expand Down Expand Up @@ -102,6 +103,7 @@ sub handleItemSkipAction(action as string)
' If there is something next in the queue, play it
if m.global.queueManager.callFunc("getPosition") < m.global.queueManager.callFunc("getCount") - 1
m.top.control = "stop"
session.video.Delete()
m.global.sceneManager.callFunc("clearPreviousScene")
m.global.queueManager.callFunc("moveForward")
m.global.queueManager.callFunc("playQueue")
Expand All @@ -114,6 +116,7 @@ sub handleItemSkipAction(action as string)
' If there is something previous in the queue, play it
if m.global.queueManager.callFunc("getPosition") > 0
m.top.control = "stop"
session.video.Delete()
m.global.sceneManager.callFunc("clearPreviousScene")
m.global.queueManager.callFunc("moveBack")
m.global.queueManager.callFunc("playQueue")
Expand Down Expand Up @@ -626,10 +629,10 @@ sub onState(msg)
else
' If an error was encountered, Display dialog
showPlaybackErrorDialog(tr("Error During Playback"))
session.video.Delete()
end if

' Stop playback and exit player
m.top.control = "stop"

else if m.top.state = "playing"

' Check if next episode is available
Expand All @@ -655,9 +658,11 @@ sub onState(msg)
m.playbackTimer.control = "stop"
ReportPlayback("stop")
m.playReported = false
session.video.Delete()
else if m.top.state = "finished"
m.playbackTimer.control = "stop"
ReportPlayback("finished")
session.video.Delete()
else
m.log.warning("Unhandled state", m.top.state, m.playReported, m.playFinished)
end if
Expand Down Expand Up @@ -716,6 +721,7 @@ sub bufferCheck(msg)

' Stop playback and exit player
m.top.control = "stop"
session.video.Delete()
end if
end if

Expand Down Expand Up @@ -785,6 +791,7 @@ function onKeyEvent(key as string, press as boolean) as boolean
if key = "OK" and m.nextEpisodeButton.hasfocus() and not m.top.trickPlayBar.visible
m.top.control = "stop"
m.top.state = "finished"
session.video.Delete()
hideNextEpisodeButton()
return true
else
Expand Down Expand Up @@ -859,6 +866,7 @@ function onKeyEvent(key as string, press as boolean) as boolean

if key = "back"
m.top.control = "stop"
session.video.Delete()
end if

return false
Expand Down
33 changes: 28 additions & 5 deletions source/api/Items.bs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "pkg:/source/api/sdk.bs"
import "pkg:/source/utils/misc.bs"

function ItemGetPlaybackInfo(id as string, startTimeTicks = 0 as longinteger)
params = {
Expand All @@ -13,9 +14,6 @@ function ItemGetPlaybackInfo(id as string, startTimeTicks = 0 as longinteger)
end function

function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger)
body = {
"DeviceProfile": getDeviceProfile()
}
params = {
"UserId": m.global.session.user.id,
"StartTimeTicks": startTimeTicks,
Expand All @@ -25,6 +23,7 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
"MaxStaticBitrate": "140000000",
"SubtitleStreamIndex": subtitleTrackIndex
}
deviceProfile = getDeviceProfile()

' Note: Jellyfin v10.9+ now remuxs LiveTV and does not allow DirectPlay anymore.
' Because of this, we need to tell the server "EnableDirectPlay = false" so that we receive the
Expand All @@ -38,11 +37,35 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
params.EnableDirectPlay = false
end if

if audioTrackIndex > -1 then params.AudioStreamIndex = audioTrackIndex
if audioTrackIndex > -1
params.AudioStreamIndex = audioTrackIndex

' force the server to transcode AAC profiles we don't support to MP3 instead of the usual AAC
' TODO: Remove this after server adds support for transcoding AAC from one profile to another
selectedAudioStream = m.global.session.video.json.MediaStreams[audioTrackIndex]

if LCase(selectedAudioStream.Codec) = "aac"
if LCase(selectedAudioStream.Profile) = "main" or LCase(selectedAudioStream.Profile) = "he-aac"
for each rule in deviceProfile.TranscodingProfiles
if rule.Container = "ts" or rule.Container = "mp4"
if rule.AudioCodec = "aac"
rule.AudioCodec = "mp3"
else if rule.AudioCodec.Left(4) = "aac,"
rule.AudioCodec = mid(rule.AudioCodec, 5)

if rule.AudioCodec.Left(3) <> "mp3"
rule.AudioCodec = "mp3," + rule.AudioCodec
end if
end if
end if
end for
end if
end if
end if

req = APIRequest(Substitute("Items/{0}/PlaybackInfo", id), params)
req.SetRequest("POST")
return postJson(req, FormatJson(body))
return postJson(req, FormatJson({ "DeviceProfile": deviceProfile }))
end function

' Search across all libraries
Expand Down
20 changes: 19 additions & 1 deletion source/utils/session.bs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ namespace session
Policy: {},
settings: {},
lastRunVersion: invalid
},
video: {
json: {}
}
}
})
Expand All @@ -30,7 +33,7 @@ namespace session
' Update one value from the global session array (m.global.session)
sub Update(key as string, value = {} as object)
' validate parameters
if key = "" or (key <> "user" and key <> "server") or value = invalid
if key = "" or (key <> "user" and key <> "server" and key <> "video") or value = invalid
print "Error in session.Update(): Invalid parameters provided"
return
end if
Expand Down Expand Up @@ -429,4 +432,19 @@ namespace session
end sub
end namespace
end namespace

namespace video
' Return the global video session array to it's default state
sub Delete()
session.Update("video", { json: {} })
end sub

' Update the global video session array (m.global.session.video)
sub Update(videoMetaData as object)
if videoMetaData = invalid then return

session.video.Delete()
session.Update("video", videoMetaData)
end sub
end namespace
end namespace

0 comments on commit a5baa30

Please sign in to comment.