HMS

Home Media Server for Roku Players
git clone https://www.brianlane.com/git/HMS
Log | Files | Refs | README | LICENSE

commit 645c03cf6d44f471d1c8863bdc173b0fc8d3c166
parent 5804294d12d72ce9b911436846cf5daac47e1c2f
Author: Brian C. Lane <bcl@brianlane.com>
Date:   Thu, 17 Nov 2022 19:43:22 -0800

Add using keystore to save playback position

Diffstat:
AHMS/components/KeystoreTask.brs | 35+++++++++++++++++++++++++++++++++++
AHMS/components/KeystoreTask.xml | 16++++++++++++++++
MHMS/components/MainScene.brs | 57+++++++++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/HMS/components/KeystoreTask.brs b/HMS/components/KeystoreTask.brs @@ -0,0 +1,35 @@ +'******************************************************************** +'** Home Media Server Application - KeystoreTask +'** Copyright (c) 2022 Brian C. Lane All Rights Reserved. +'******************************************************************** +sub Init() + print "KeystoreTask->Init()" + + m.top.functionName = "ExecuteCommand" +end sub + +' ExecuteCommand is executed when m.keystoreTask.control = "run" from MainScene +' This needs to be reset along with UNObserveField("done") to prevent accidental re-triggering +sub ExecuteCommand() + print "KeystoreTask->ExecuteCommand()" + print "Server url = "; m.top.serverurl + print "command = "; m.top.command + print "key = "; m.top.key + print "value = "; m.top.value + + if not m.top.has_keystore + m.top.done = true + return + end if + + if m.top.command = "get" + m.top.value = getKeyValue(m.top.serverurl, m.top.key) + print "new value = "; m.top.value + else if m.top.command = "set" + setKeyValue(m.top.serverurl, m.top.key, m.top.value) + end if + + m.top.done = true +end sub + + diff --git a/HMS/components/KeystoreTask.xml b/HMS/components/KeystoreTask.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" ?> +<component name="KeystoreTask" extends="Task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd"> + <script type="text/brightscript" uri="pkg:/source/generalUtils.brs" /> + <script type="text/brightscript" uri="pkg:/source/urlUtils.brs" /> + <script type="text/brightscript" uri="pkg:/source/keystore.brs" /> + <script type="text/brightscript" uri="KeystoreTask.brs" /> + + <interface> + <field id="serverurl" type="uri" /> + <field id="has_keystore" type="bool" /> + <field id="command" type="string" /> + <field id="key" type="string" /> + <field id="value" type="string" /> + <field id="done" type="bool" /> + </interface> +</component> diff --git a/HMS/components/MainScene.brs b/HMS/components/MainScene.brs @@ -6,6 +6,7 @@ sub Init() print "MainScene->Init()" m.top.ObserveField("serverurl", "RunContentTask") m.details = m.top.FindNode("details") + m.keystoreTask = CreateObject("roSGNode", "KeystoreTask") StartClock() @@ -62,6 +63,33 @@ sub RunContentTask() m.contentTask.control = "run" end sub +sub GetKeystoreValue(key as string, callback as string) + m.keystoreTask.serverurl = m.top.serverurl + m.keystoreTask.key = key + m.keystoreTask.value = "" + m.keystoreTask.command = "get" + if callback <> "" + m.keystoreTask.ObserveField("done", callback) + end if + m.keystoreTask.control = "run" +end sub + +sub SetKeystoreValue(key as string, value as string, callback as string) + m.keystoreTask.serverurl = m.top.serverurl + m.keystoreTask.key = key + m.keystoreTask.value = value + m.keystoreTask.command = "set" + if callback <> "" + m.keystoreTask.ObserveField("done", callback) + end if + m.keystoreTask.control = "run" +end sub + +sub ResetKeystoreTask() + m.keystoreTask.UNObserveField("done") + m.keystoreTask.done = false +end sub + sub OnCategoriesLoaded() print "MainScene->OnCategoriesLoaded()" print m.contentTask.categories @@ -167,9 +195,21 @@ sub StartVideoPlayer(index as integer) content.Title = item.ShortDescriptionLine1 ' TODO fix the category metadata content.Url = item.StreamURLS[0] + m.video.content = content + GetKeystoreValue(content.Title, "StartPlayback") +end sub + + +' Called by GetKeystoreValue +sub StartPlayback() + ResetKeystoreTask() + + ' Was there a result? + if m.keystoreTask.value <> "" + m.video.seek = m.keystoreTask.value.ToInt() + end if ' Play the selected video - m.video.content = content m.video.visible = true m.video.SetFocus(true) m.video.control = "play" @@ -197,8 +237,9 @@ end sub sub OnValidateChanged() print "MainScene->OnValidateChanged" - print m.validateTask.serverurl - print m.validateTask.valid + print "server url = "; m.validateTask.serverurl + print "valid? "; m.validateTask.valid + print "keystore? "; m.validateTask.keystore if not m.validateTask.valid then ' Still invalid, run it again RunSetupServerDialog(m.validateTask.serverurl) @@ -207,7 +248,7 @@ sub OnValidateChanged() m.top.serverurl = m.validateTask.serverurl ' And save it for next time RegWrite("ServerURL", m.validateTask.serverurl) - m.top.keystore = m.validateTask.keystore + m.keystoreTask.has_keystore = m.validateTask.keystore end if end sub @@ -231,7 +272,7 @@ sub SetupVideoPlayer() m.video = m.top.FindNode("player") m.Video.observeField("state", "OnVideoStateChange") m.Video.observeField("position", "OnVideoPositionChange") - m.Video.notificationInterval = 1 + m.Video.notificationInterval = 5 ' map of events that should be handled on state change m.statesToHandle = { finished: "" @@ -259,7 +300,11 @@ end sub sub OnVideoPositionChange() print "MainScene->OnVideoPositionChange()" - ' TODO save position to keystore at intervals + if m.video.positionInfo = invalid + return + end if + print "position = "; m.video.positionInfo.video + SetKeystoreValue(m.video.content.Title, m.video.positionInfo.video.ToStr(), "ResetKeystoreTask") end sub function onKeyEvent(key as String, press as Boolean) as Boolean