Merge pull request #112 from thomabx/playstate

Reports playback status to the server
This commit is contained in:
Nick Bisby 2020-02-17 16:16:11 -06:00 committed by GitHub
commit dcc067f11a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 32 deletions

View File

@ -2,6 +2,10 @@
<component name="JFVideo" extends="Video"> <component name="JFVideo" extends="Video">
<interface> <interface>
<field id="backPressed" type="boolean" alwaysNotify="true" /> <field id="backPressed" type="boolean" alwaysNotify="true" />
<field id="PlaySessionId" type="string" />
</interface> </interface>
<script type="text/brightscript" uri="JFVideo.brs" /> <script type="text/brightscript" uri="JFVideo.brs" />
<children>
<timer id="playbackTimer" repeat="true" duration="30" />
</children>
</component> </component>

View File

@ -39,6 +39,9 @@ sub Main()
print "CLOSING SCREEN" print "CLOSING SCREEN"
return return
else if isNodeEvent(msg, "backPressed") else if isNodeEvent(msg, "backPressed")
if msg.getRoSGNode().focusedChild <> invalid and msg.getRoSGNode().focusedChild.isSubtype("JFVideo")
stopPlayback()
end if
' Pop a group off the stack and expose what's below ' Pop a group off the stack and expose what's below
n = m.scene.getChildCount() - 1 n = m.scene.getChildCount() - 1
if n = 1 if n = 1
@ -156,6 +159,7 @@ sub Main()
m.scene.appendChild(group) m.scene.appendChild(group)
group.setFocus(true) group.setFocus(true)
group.control = "play" group.control = "play"
ReportPlayback(group, "start")
m.overhang.visible = false m.overhang.visible = false
else if isNodeEvent(msg, "search_value") else if isNodeEvent(msg, "search_value")
query = msg.getRoSGNode().search_value query = msg.getRoSGNode().search_value
@ -208,6 +212,7 @@ sub Main()
m.scene.appendChild(group) m.scene.appendChild(group)
group.setFocus(true) group.setFocus(true)
group.control = "play" group.control = "play"
ReportPlayback(group, "start")
m.overhang.visible = false m.overhang.visible = false
else if btn.id = "watched-button" else if btn.id = "watched-button"
movie = group.itemContent movie = group.itemContent
@ -262,6 +267,15 @@ sub Main()
wipe_groups() wipe_groups()
goto app_start goto app_start
end if end if
else if isNodeEvent(msg, "fire")
ReportPlayback(group, "update")
else if isNodeEvent(msg, "state")
node = msg.getRoSGNode()
if node.state = "finished" then
node.backPressed = "true"
else if node.state = "playing" or node.state = "paused" then
ReportPlayback(group, "update")
end if
else else
print type(msg) print type(msg)
print msg print msg

View File

@ -344,9 +344,12 @@ end function
function CreateVideoPlayerGroup(video_id) function CreateVideoPlayerGroup(video_id)
' Video is Playing ' Video is Playing
video = VideoPlayer(video_id) video = VideoPlayer(video_id)
timer = video.findNode("playbackTimer")
video.observeField("backPressed", m.port) video.observeField("backPressed", m.port)
video.observeField("state", m.port) video.observeField("state", m.port)
timer.control = "start"
timer.observeField("fire", m.port)
return video return video
end function end function

View File

@ -1,7 +1,8 @@
function VideoPlayer(id) function VideoPlayer(id)
' Get video controls and UI ' Get video controls and UI
video = CreateObject("roSGNode", "JFVideo") video = CreateObject("roSGNode", "JFVideo")
video.content = VideoContent(id) video.id = id
video = VideoContent(video)
jellyfin_blue = "#00a4dcFF" jellyfin_blue = "#00a4dcFF"
@ -11,38 +12,45 @@ function VideoPlayer(id)
return video return video
end function end function
function VideoContent(id) as object function VideoContent(video) as object
' Get video stream ' Get video stream
content = createObject("RoSGNode", "ContentNode") video.content = createObject("RoSGNode", "ContentNode")
meta = ItemMetaData(id) meta = ItemMetaData(video.id)
content.title = meta.Name video.content.title = meta.Name
container = getContainerType(meta) container = getContainerType(meta)
video.PlaySessionId = ItemGetSession(video.id)
if directPlaySupported(meta) then if directPlaySupported(meta) then
content.url = buildURL(Substitute("Videos/{0}/stream", id), { video.content.url = buildURL(Substitute("Videos/{0}/stream", video.id), {
"PlaySessionId": video.PlaySessionId
Static: "true", Static: "true",
Container: container Container: container
}) })
content.streamformat = container video.content.streamformat = container
content.switchingStrategy = "" video.content.switchingStrategy = ""
else else
content.url = buildURL(Substitute("Videos/{0}/master.m3u8", id), { video.content.url = buildURL(Substitute("Videos/{0}/master.m3u8", video.id), {
PlaySessionId: ItemGetSession(id) "PlaySessionId": video.PlaySessionId
VideoCodec: "h264", "VideoCodec": "h264",
AudioCodec: "aac", "AudioCodec": "aac",
MediaSourceId: id, "MediaSourceId": video.id,
"SegmentContainer": "ts",
"MinSegments": 1,
"BreakOnNonKeyFrames": "True",
"h264-profile": "high,main,baseline,constrainedbaseline",
"RequireAvc": "false",
}) })
end if end if
content = authorize_request(content) video.content = authorize_request(video.content)
' todo - audioFormat is read only ' todo - audioFormat is read only
content.audioFormat = getAudioFormat(meta) video.content.audioFormat = getAudioFormat(meta)
if server_is_https() then if server_is_https() then
content.setCertificatesFile("common:/certs/ca-bundle.crt") video.content.setCertificatesFile("common:/certs/ca-bundle.crt")
end if end if
return content return video
end function end function
function directPlaySupported(meta as object) as boolean function directPlaySupported(meta as object) as boolean
@ -84,3 +92,21 @@ function getAudioInfo(meta as object) as object
end for end for
return results return results
end function end function
function ReportPlayback(video, state = "update" as string)
params = {
"PlaySessionId": video.PlaySessionId,
"PositionTicks": str(int(video.position))+"0000000",
"IsPaused": (video.state = "paused"),
}
PlaystateUpdate(video.id, state, params)
end function
function StopPlayback()
video = m.scene.focusedchild
video.findNode("playbackTimer").control = "stop"
video.control = "stop"
video.visible = "false"
if video.status = "finished" then MarkItemWatched(video.id)
ReportPlayback(video,"stop")
end function

View File

@ -1,18 +1,13 @@
function PlaystateStart(id, params) function PlaystateUpdate(id, state as string, params = {})
if state = "start" then
url = "Sessions/Playing"
else if state = "stop" then
url = "Sessions/Playing/Stopped"
else if state = "update"
url = "Sessions/Playing/Progress"
end if
params = PlaystateDefaults(id, params) params = PlaystateDefaults(id, params)
resp = APIRequest("Sessions/Playing") resp = APIRequest(url)
return postJson(resp, params)
end function
function PlaystateUpdate(id, params)
params = PlaystateDefaults(id, params)
resp = APIRequest("Sessions/Playing/Progress")
return postJson(resp, params)
end function
function PlaystateStop(id, params={})
params = PlaystateDefaults(id, params)
resp = APIRequest("Sessions/Playing/Stopped")
return postJson(resp, params) return postJson(resp, params)
end function end function
@ -29,7 +24,7 @@ function PlaystateDefaults(id="" as string, params={} as object)
'"SubtitleStreamIndex": 0, '"SubtitleStreamIndex": 0,
"IsPaused": false, "IsPaused": false,
'"IsMuted": false, '"IsMuted": false,
'"PositionTicks": 0, "PositionTicks": 0,
'"PlaybackStartTimeTicks": 0, '"PlaybackStartTimeTicks": 0,
'"VolumeLevel": 100, '"VolumeLevel": 100,
'"Brightness": 100, '"Brightness": 100,