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:
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