2023-10-03 16:11:25 +00:00
import "pkg:/source/utils/config.bs"
import "pkg:/source/utils/misc.bs"
import "pkg:/source/utils/deviceCapabilities.bs"
import "pkg:/source/api/baserequest.bs"
2023-05-05 17:45:53 +00:00
import "pkg:/source/api/sdk.bs"
2023-05-03 21:21:04 +00:00
2023-02-25 16:43:36 +00:00
sub init()
m.top.functionName = "getPlaybackInfoTask"
end sub
2023-05-07 01:26:02 +00:00
function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger)
currentView = m.global.sceneManager.callFunc("getActiveScene")
currentItem = m.global.queueManager.callFunc("getCurrentItem")
2023-02-25 16:43:36 +00:00
body = {
"DeviceProfile": getDeviceProfile()
}
params = {
2023-06-01 12:43:27 +00:00
"UserId": m.global.session.user.id,
2023-05-07 01:26:02 +00:00
"StartTimeTicks": currentItem.startingPoint,
2023-02-25 16:43:36 +00:00
"IsPlayback": true,
"AutoOpenLiveStream": true,
"MaxStreamingBitrate": "140000000",
"MaxStaticBitrate": "140000000",
2023-05-07 01:26:02 +00:00
"SubtitleStreamIndex": currentView.selectedSubtitle,
"MediaSourceId": currentItem.id,
"AudioStreamIndex": currentItem.selectedAudioStreamIndex
2023-02-25 16:43:36 +00:00
}
req = APIRequest(Substitute("Items/{0}/PlaybackInfo", id), params)
req.SetRequest("POST")
return postJson(req, FormatJson(body))
end function
' Returns an array of playback info to be displayed during playback.
' In the future, with a custom playback info view, we can return an associated array.
sub getPlaybackInfoTask()
2023-10-27 14:51:09 +00:00
sessions = api.sessions.Get({ "deviceId": m.global.device.serverDeviceName })
2023-02-25 16:43:36 +00:00
m.playbackInfo = ItemPostPlaybackInfo(m.top.videoID)
if isValid(sessions) and sessions.Count() > 0
m.top.data = { playbackInfo: GetTranscodingStats(sessions[0]) }
else
m.top.data = { playbackInfo: [tr("Unable to get playback information")] }
end if
end sub
2023-06-01 12:43:27 +00:00
function GetTranscodingStats(deviceSession)
2023-02-25 16:43:36 +00:00
sessionStats = { data: [] }
2023-06-01 12:43:27 +00:00
if isValid(deviceSession.TranscodingInfo) and deviceSession.TranscodingInfo.Count() > 0
transcodingReasons = deviceSession.TranscodingInfo.TranscodeReasons
videoCodec = deviceSession.TranscodingInfo.VideoCodec
audioCodec = deviceSession.TranscodingInfo.AudioCodec
totalBitrate = deviceSession.TranscodingInfo.Bitrate
audioChannels = deviceSession.TranscodingInfo.AudioChannels
2023-02-25 16:43:36 +00:00
if isValid(transcodingReasons) and transcodingReasons.Count() > 0
sessionStats.data.push("<header>" + tr("Transcoding Information") + "</header>")
for each item in transcodingReasons
sessionStats.data.push("<b>• " + tr("Reason") + ":</b> " + item)
end for
end if
if isValid(videoCodec)
data = "<b>• " + tr("Video Codec") + ":</b> " + videoCodec
2023-06-01 12:43:27 +00:00
if deviceSession.TranscodingInfo.IsVideoDirect
2023-02-25 16:43:36 +00:00
data = data + " (" + tr("direct") + ")"
end if
sessionStats.data.push(data)
end if
if isValid(audioCodec)
data = "<b>• " + tr("Audio Codec") + ":</b> " + audioCodec
2023-06-01 12:43:27 +00:00
if deviceSession.TranscodingInfo.IsAudioDirect
2023-02-25 16:43:36 +00:00
data = data + " (" + tr("direct") + ")"
end if
sessionStats.data.push(data)
end if
if isValid(totalBitrate)
data = "<b>• " + tr("Total Bitrate") + ":</b> " + getDisplayBitrate(totalBitrate)
sessionStats.data.push(data)
end if
if isValid(audioChannels)
data = "<b>• " + tr("Audio Channels") + ":</b> " + Str(audioChannels)
sessionStats.data.push(data)
end if
2023-06-28 18:33:14 +00:00
else
sessionStats.data.push("<header>" + tr("Direct playing") + "</header>")
2023-06-30 02:47:54 +00:00
sessionStats.data.push("<b>" + tr("The source file is entirely compatible with this client and the session is receiving the file without modifications.") + "</b>")
2023-02-25 16:43:36 +00:00
end if
if havePlaybackInfo()
stream = m.playbackInfo.mediaSources[0].MediaStreams[0]
sessionStats.data.push("<header>" + tr("Stream Information") + "</header>")
if isValid(stream.Container)
data = "<b>• " + tr("Container") + ":</b> " + stream.Container
sessionStats.data.push(data)
end if
if isValid(stream.Size)
data = "<b>• " + tr("Size") + ":</b> " + stream.Size
sessionStats.data.push(data)
end if
if isValid(stream.BitRate)
data = "<b>• " + tr("Bit Rate") + ":</b> " + getDisplayBitrate(stream.BitRate)
sessionStats.data.push(data)
end if
if isValid(stream.Codec)
data = "<b>• " + tr("Codec") + ":</b> " + stream.Codec
sessionStats.data.push(data)
end if
if isValid(stream.CodecTag)
data = "<b>• " + tr("Codec Tag") + ":</b> " + stream.CodecTag
sessionStats.data.push(data)
end if
if isValid(stream.VideoRangeType)
data = "<b>• " + tr("Video range type") + ":</b> " + stream.VideoRangeType
sessionStats.data.push(data)
end if
if isValid(stream.PixelFormat)
data = "<b>• " + tr("Pixel format") + ":</b> " + stream.PixelFormat
sessionStats.data.push(data)
end if
if isValid(stream.Width) and isValid(stream.Height)
data = "<b>• " + tr("WxH") + ":</b> " + Str(stream.Width) + " x " + Str(stream.Height)
sessionStats.data.push(data)
end if
if isValid(stream.Level)
data = "<b>• " + tr("Level") + ":</b> " + Str(stream.Level)
sessionStats.data.push(data)
end if
end if
return sessionStats
end function
function havePlaybackInfo()
if not isValid(m.playbackInfo)
return false
end if
if not isValid(m.playbackInfo.mediaSources)
return false
end if
if m.playbackInfo.mediaSources.Count() <= 0
return false
end if
if not isValid(m.playbackInfo.mediaSources[0].MediaStreams)
return false
end if
if m.playbackInfo.mediaSources[0].MediaStreams.Count() <= 0
return false
end if
return true
end function
function getDisplayBitrate(bitrate)
if bitrate > 1000000
return Str(Fix(bitrate / 1000000)) + " Mbps"
else
return Str(Fix(bitrate / 1000)) + " Kbps"
end if
end function