Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
360tv
Streaming Star

So I need two little changes made to my VideoPlayer example

Hi. I've been poking around on these forums trying to find clues to get some things done to the Videoplayer example in the SDK. Two things, mainly.

1) I've managed to merge the "register" and the "videoplayer" examples. It launches, my categories come up, I pick one, the registration screen works, logs in my database just fine. I can go to my content catigory, but when I want to pick another catigory, it makes me register again. Same if I exit and restart the channel.

2) My ratings buttons that I've managed to add don't work. What I want is when a rating is elected, I want to post it to a database thru a HTTP GET with values in parameters, just like my registration is done. When I try to acomplish this, here is the result

(Don't laugh at my coding)

Unexpected event type:  15
showHomeScreen | msg = | index = 0
Screen closed
Button pressed: 2 0
ButtonPressed
ButtonPressed
m.ratingpost =http://www.site.net/roku/xml/ratepost.asp
ratingpost =devid=16C1AV051975&rating=80
Current Function:
026: Function showDetailScreen(screen As Object, showList As Object, showIndex as Integer) As Integer
027:
028: if validateParam(screen, "roSpringboardScreen", "showDetailScreen") = false return -1
029: if validateParam(showList, "roArray", "showDetailScreen") = false return -1
030:
031: refreshShowDetail(screen, showList, showIndex)
032:
033: 'remote key id's for left/right navigation
034: remoteKeyLeft = 4
035: remoteKeyRight = 5
036:
037: while true
038: msg = wait(0, screen.GetMessagePort())
039:
040: if type(msg) = "roSpringboardScreenEvent" then
041: if msg.isScreenClosed()
042: print "Screen closed"
043: exit while
044: else if msg.isRemoteKeyPressed()
045: print "Remote key pressed"
046: if msg.GetIndex() = remoteKeyLeft then
047: showIndex = getPrevShow(showList, showIndex)
048: if showIndex <> -1
049: refreshShowDetail(screen, showList, showIndex)
050: end if
051: else if msg.GetIndex() = remoteKeyRight
052: showIndex = getNextShow(showList, showIndex)
053: if showIndex <> -1
054: refreshShowDetail(screen, showList, showIndex)
055: end if
056: endif
057: else if msg.isButtonPressed()
058: print "ButtonPressed"
059: print "ButtonPressed"
060: if msg.GetIndex() = 1
061: PlayStart = RegRead(showList[showIndex].ContentId)
062: if PlayStart <> invalid then
063: showList[showIndex].PlayStart = PlayStart.ToInt()
064: endif
065: showVideoScreen(showList[showIndex])
066: refreshShowDetail(screen,showList,showIndex)
067: endif
068: if msg.GetIndex() = 2
069: showList[showIndex].PlayStart = 0
070: showVideoScreen(showList[showIndex])
071: refreshShowDetail(screen,showList,showIndex)
072: endif
073: if msg.GetIndex() = 3
074: m.rating = msg.GetData()
075: sn = GetDeviceESN()
076: rating = msg.GetData().ToStr()
077: m.ratingpost = "http://www.360tv.net/roku/xml/ratepost.asp"
078: ratingpost = "devid=" + sn + "&rating=" + rating
079: http = NewHttp(m.ratingpost)
080: http.AddParam("partner", "roku")
081: http.AddParam("deviceID", sn)
082:
083:
084: print "m.ratingpost =" m.ratingpost
085: print "ratingpost =" ratingpost
086: m.ratingpost.PostFromString(ratingpost)
087: endif
088: print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
089: end if
090: else
091: print "Unexpected message class: "; type(msg)
092: end if
093: end while
094:
095: return showIndex
096:
097: End Function
Member function not found in BrightScript Component or interface. (runtime error &hf4) in ...g:/source/appDetailScreen.brs(86)

086: m.ratingpost.PostFromString(ratingpost)
Backtrace:
Function showdetailscreen(screen As <uninitialized>, showlist As <uninitialized>, showindex As Integer) As Integer
file/line: /tmp/plugin/MFAAAAf7jGw7...g:/source/appDetailScreen.brs(86)
Function displayshowdetailscreen(category As <uninitialized>, showindex As Integer) As Integer
file/line: /tmp/plugin/MFAAAAf7jGw7/pkg:/source/appPosterScreen.brs(93)
Function showposterscreen(screen As <uninitialized>, category As <uninitialized>) As Integer
file/line: /tmp/plugin/MFAAAAf7jGw7/pkg:/source/appPosterScreen.brs(69)
Function displaycategoryposterscreen(category As <uninitialized>) As
file/line: /tmp/plugin/MFAAAAf7jGw7/pkg:/source/appHomeScreen.brs(83)
Function showhomescreen(screen As ) As Integer
file/line: /tmp/plugin/MFAAAAf7jGw7/pkg:/source/appHomeScreen.brs(59)
Function main() As
file/line: /tmp/plugin/MFAAAAf7jGw7/pkg:/source/appMain.brs(20)

Local Variables:
screen &h0010 bsc:roSpringboardScreen, refcnt=2
showlist &h0010 bsc:roArray, refcnt=2
showindex &h0002 Integer val:0
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=7
remotekeyleft &h0002 Integer val:4
remotekeyright &h0002 Integer val:5
msg &h0010 bsc:roSpringboardScreenEvent, refcnt=1
playstart &h0000 <uninitialized> val:Uninitialized
sn &h8010 bsc:roString (2.1 was String), refcnt=1
rating &h8010 bsc:roString (2.1 was String), refcnt=1
ratingpost &h8010 bsc:roString (2.1 was String), refcnt=1
http &h0010 bsc:roAssociativeArray, refcnt=1
BrightScript Debugger> Note: GC - Found 75 orphaned objects (objects in a circular ref loop).



The code in my appDetainScreen.brs is as follows

'**********************************************************
'** Video Player Example Application - Detail Screen
'** November 2009
'** Copyright (c) 2009 Roku Inc. All Rights Reserved.
'**********************************************************

Function preShowDetailScreen(breadA=invalid, breadB=invalid) As Object
port=CreateObject("roMessagePort")
screen = CreateObject("roSpringboardScreen")
screen.SetDescriptionStyle("episode")
screen.SetMessagePort(port)
if breadA<>invalid and breadB<>invalid then
screen.SetBreadcrumbText(breadA, breadB)
end if

return screen
End Function

'***************************************************************
'** The show detail screen (springboard) is where the user sees
'** the details for a show and is allowed to select a show to
'** begin playback. This is the main event loop for that screen
'** and where we spend our time waiting until the user presses a
'** button and then we decide how best to handle the event.
'***************************************************************
Function showDetailScreen(screen As Object, showList As Object, showIndex as Integer) As Integer

if validateParam(screen, "roSpringboardScreen", "showDetailScreen") = false return -1
if validateParam(showList, "roArray", "showDetailScreen") = false return -1

refreshShowDetail(screen, showList, showIndex)

'remote key id's for left/right navigation
remoteKeyLeft = 4
remoteKeyRight = 5

while true
msg = wait(0, screen.GetMessagePort())

if type(msg) = "roSpringboardScreenEvent" then
if msg.isScreenClosed()
print "Screen closed"
exit while
else if msg.isRemoteKeyPressed()
print "Remote key pressed"
if msg.GetIndex() = remoteKeyLeft then
showIndex = getPrevShow(showList, showIndex)
if showIndex <> -1
refreshShowDetail(screen, showList, showIndex)
end if
else if msg.GetIndex() = remoteKeyRight
showIndex = getNextShow(showList, showIndex)
if showIndex <> -1
refreshShowDetail(screen, showList, showIndex)
end if
endif
else if msg.isButtonPressed()
print "ButtonPressed"
print "ButtonPressed"
if msg.GetIndex() = 1
PlayStart = RegRead(showList[showIndex].ContentId)
if PlayStart <> invalid then
showList[showIndex].PlayStart = PlayStart.ToInt()
endif
showVideoScreen(showList[showIndex])
refreshShowDetail(screen,showList,showIndex)
endif
if msg.GetIndex() = 2
showList[showIndex].PlayStart = 0
showVideoScreen(showList[showIndex])
refreshShowDetail(screen,showList,showIndex)
endif
if msg.GetIndex() = 3
m.rating = msg.GetData()
sn = GetDeviceESN()
rating = msg.GetData().ToStr()
m.ratingpost = "http://www.360tv.net/roku/xml/ratepost.asp"
ratingpost = "devid=" + sn + "&rating=" + rating
http = NewHttp(m.ratingpost)
http.AddParam("partner", "roku")
http.AddParam("deviceID", sn)


print "m.ratingpost =" m.ratingpost
print "ratingpost =" ratingpost
m.ratingpost.PostFromString(ratingpost)
endif
print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
end if
else
print "Unexpected message class: "; type(msg)
end if
end while

return showIndex

End Function

'**************************************************************
'** Refresh the contents of the show detail screen. This may be
'** required on initial entry to the screen or as the user moves
'** left/right on the springboard. When the user is on the
'** springboard, we generally let them press left/right arrow keys
'** to navigate to the previous/next show in a circular manner.
'** When leaving the screen, the should be positioned on the
'** corresponding item in the poster screen matching the current show
'**************************************************************
Function refreshShowDetail(screen As Object, showList As Object, showIndex as Integer) As Integer

if validateParam(screen, "roSpringboardScreen", "refreshShowDetail") = false return -1
if validateParam(showList, "roArray", "refreshShowDetail") = false return -1

show = showList[showIndex]

'Uncomment this statement to dump the details for each show
'PrintAA(show)


screen.ClearButtons()
if regread(show.contentid) <> invalid and regread(show.contentid).toint() >=30 then
screen.AddButton(1, "Resume playing")
screen.AddButton(2, "Play from beginning")
screen.AddRatingButton(3, 50, 75 )
screen.SetStaticRatingEnabled(false)
else
screen.addbutton(2,"Play")
screen.AddRatingButton(3, 50, 75 )

end if
screen.SetContent(show)
screen.Show()

End Function

'********************************************************
'** Get the next item in the list and handle the wrap
'** around case to implement a circular list for left/right
'** navigation on the springboard screen
'********************************************************
Function getNextShow(showList As Object, showIndex As Integer) As Integer
if validateParam(showList, "roArray", "getNextShow") = false return -1

nextIndex = showIndex + 1
if nextIndex >= showList.Count() or nextIndex < 0 then
nextIndex = 0
end if

show = showList[nextIndex]
if validateParam(show, "roAssociativeArray", "getNextShow") = false return -1

return nextIndex
End Function


'********************************************************
'** Get the previous item in the list and handle the wrap
'** around case to implement a circular list for left/right
'** navigation on the springboard screen
'********************************************************
Function getPrevShow(showList As Object, showIndex As Integer) As Integer
if validateParam(showList, "roArray", "getPrevShow") = false return -1

prevIndex = showIndex - 1
if prevIndex < 0 or prevIndex >= showList.Count() then
if showList.Count() > 0 then
prevIndex = showList.Count() - 1
else
return -1
end if
end if

show = showList[prevIndex]
if validateParam(show, "roAssociativeArray", "getPrevShow") = false return -1

return prevIndex
End Function


Any advice other than "read the documentation" (because I've tried) would be appreciated.
0 Kudos
9 REPLIES 9
renojim
Community Streaming Expert

Re: So I need two little changes made to my VideoPlayer exam

You want http.PostFromString, not m.ratingpost.PostFromString.
-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
360tv
Streaming Star

Re: So I need two little changes made to my VideoPlayer exam

Thanks for the reply!

the error I was getting before was
Member function not found in BrightScript Component or interface. (runtime error &hf4) in ...g:/source/appDetailScreen.brs(86)

086: m.ratingpost.PostFromString(ratingpost)


Now I'm getting
Member function not found in BrightScript Component or interface. (runtime error &hf4) in ...g:/source/appDetailScreen.brs(86)

086: http.PostFromString(ratingpost)


Am I implementing http.PostFromString incorectly?
0 Kudos
belltown
Roku Guru

Re: So I need two little changes made to my VideoPlayer exam

Try:

http.PostFromStringWithTimeout(ratingpost, 30)


where 30 would be the timeout value in seconds (or zero to wait forever).
0 Kudos
renojim
Community Streaming Expert

Re: So I need two little changes made to my VideoPlayer exam

Sorry, I don't use any of the sample/example code. It looks like you'd need to use http.http.PostFromString, but belltown's answer is probably the better way to go.

-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
360tv
Streaming Star

Re: So I need two little changes made to my VideoPlayer exam

http.PostFromStringWithTimeout worked. I'm not sure why specifiing a timeout keeps it from crashing, but I'll deal with it.

As for my other issue with the registration, anyone have any idea why it's forcing registration every time I enter my channel?

regscreen.brs
' *********************************************************
' ** Roku Registration Demonstration App
' ** Support routines
' ** May 2009
' ** Copyright (c) 2009 Roku Inc. All Rights Reserved.
' *********************************************************

'******************************************************
'Perform the registration flow
'
'Returns:
' 0 - We're registered. Proceed
' 1 - We're not registered. The user canceled the process.
' 2 - We're not registered. There was an error
'******************************************************

Function doRegistration() As Integer

'xml responses are static, but there are a few flavors available for testing
'Generic case: getRegResult (always returns success)
'Failure case: getRegResult_failure (always returns failure)
'Success case: getRegResult_success (always returns success)

m.UrlBase = "http://www.360tv.net/roku"
m.UrlGetRegCode = m.UrlBase + "/getRegCode.asp"
m.UrlGetRegResult = m.UrlBase + "/getRegResult.asp"
m.UrlWebSite = "www.360tv.net/roku"

m.RegToken = loadRegistrationToken()
if isLinked() then
print "device already linked, skipping registration process"
'return 0
endif

regscreen = displayRegistrationScreen()

'main loop get a new registration code, display it and check to see if its been linked
while true

duration = 0

sn = GetDeviceESN()
regCode = getRegistrationCode(sn)

'if we've failed to get the registration code, bail out, otherwise we'll
'get rid of the retreiving... text and replace it with the real code
if regCode = "" then return 2
regscreen.SetRegistrationCode(regCode)
print "Enter registration code " + regCode + " at " + m.UrlWebSite + " for " + sn

'make an http request to see if the device has been registered on the backend
while true
sleep(5000) ' to simulate going to computer and typing in regcode

status = checkRegistrationStatus(sn, regCode)
if status < 3 return status

getNewCode = false
retryInterval = getRetryInterval()
retryDuration = getRetryDuration()
print "retry duration "; itostr(duration); " at "; itostr(retryInterval);
print " sec intervals for "; itostr(retryDuration); " secs max"

'wait for the retry interval to expire or the user to press a button
'indicating they either want to quit or fetch a new registration code
while true
print "Wait for " + itostr(retryInterval)
msg = wait(retryInterval * 1000, regscreen.GetMessagePort())
duration = duration + retryInterval
if msg = invalid exit while

if type(msg) = "roCodeRegistrationScreenEvent"
if msg.isScreenClosed()
print "Screen closed"
return 1
elseif msg.isButtonPressed()
print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
if msg.GetIndex() = 0
regscreen.SetRegistrationCode("retrieving code...")
getNewCode = true
exit while
endif
if msg.GetIndex() = 1 return 1
endif
endif
end while

if duration > retryDuration exit while
if getNewCode exit while

print "poll prelink again..."
end while
end while

End Function


'********************************************************************
'** display the registration screen in its initial state with the
'** text "retreiving..." shown. We'll get the code and replace it
'** in the next step after we have something onscreen for teh user
'********************************************************************
Function displayRegistrationScreen() As Object

regsite = "go to " + m.UrlWebsite
regscreen = CreateObject("roCodeRegistrationScreen")
regscreen.SetMessagePort(CreateObject("roMessagePort"))

regscreen.SetTitle("")
regscreen.AddParagraph("Please link your Roku player to your account by visiting")
regscreen.AddFocalText(" ", "spacing-dense")
regscreen.AddFocalText("From your computer,", "spacing-dense")
regscreen.AddFocalText(regsite, "spacing-dense")
regscreen.AddFocalText("and enter this code to activate:", "spacing-dense")
regscreen.SetRegistrationCode("retrieving code...")
regscreen.AddParagraph("This screen will automatically update as soon as your activation completes")
regscreen.AddButton(0, "New code please")
regscreen.AddButton(1, "exit.")
regscreen.Show()

return regscreen

End Function


'********************************************************************
'** Fetch the prelink code from the registration service. return
'** valid registration code on success or an empty string on failure
'********************************************************************
Function getRegistrationCode(sn As String) As String

if sn = "" then return ""

http = NewHttp(m.UrlGetRegCode)
http.AddParam("partner", "roku")
http.AddParam("deviceID", sn)
http.AddParam("deviceTypeName", "roku")

rsp = http.Http.GetToString()
xml = CreateObject("roXMLElement")
print "GOT: " + rsp
print "Reason: " + http.Http.GetFailureReason()

if not xml.Parse(rsp) then
print "Can't parse getRegistrationCode response"
ShowConnectionFailed()
return ""
endif

if xml.GetName() <> "result"
Dbg("Bad register response: ", xml.GetName())
ShowConnectionFailed()
return ""
endif

if islist(xml.GetBody()) = false then
Dbg("No registration information available")
ShowConnectionFailed()
return ""
endif

'default values for retry logic
retryInterval = 30 'seconds
retryDuration = 900 'seconds (aka 15 minutes)
regCode = ""

'handle validation of response fields
for each e in xml.GetBody()
if e.GetName() = "regCode" then
regCode = e.GetBody() 'enter this code at website
elseif e.GetName() = "retryInterval" then
retryInterval = strtoi(e.GetBody())
elseif e.GetName() = "retryDuration" then
retryDuration = strtoi(e.GetBody())
endif
next

if regCode = "" then
Dbg("Parse yields empty registration code")
ShowConnectionFailed()
endif

m.retryDuration = retryDuration
m.retryInterval = retryInterval
m.regCode = regCode

return regCode

End Function


'******************************************************************
'** Check the status of the registration to see if we've linked
'** Returns:
'** 0 - We're registered. Proceed.
'** 1 - Reserved. Used by calling function.
'** 2 - We're not registered. There was an error, abort.
'** 3 - We're not registered. Keep trying.
'******************************************************************
Function checkRegistrationStatus(sn As String, regCode As String) As Integer

http = NewHttp(m.UrlGetRegResult)
http.AddParam("partner", "roku")
http.AddParam("deviceID", sn)
http.AddParam("regCode", regCode)

print "checking registration status"

while true
rsp = http.Http.GetToString()
xml = CreateObject("roXMLElement")
if not xml.Parse(rsp) then
print "Can't parse check registration status response"
ShowConnectionFailed()
return 2
endif

if xml.GetName() <> "result" then
print "unexpected check registration status response: ", xml.GetName()
ShowConnectionFailed()
return 2
endif

if islist(xml.GetBody()) = true then
for each e in xml.GetBody()
if e.GetName() = "regToken" then
token = e.GetBody()

if token <> "" and token <> invalid then
print "obtained registration token: " + validstr(token)
saveRegistrationToken(token) 'commit it
m.RegistrationToken = token
showCongratulationsScreen()
return 0
else
return 3
endif
elseif e.GetName() = "customerId" then
customerId = strtoi(e.GetBody())
elseif e.GetName() = "creationTime" then
creationTime = strtoi(e.GetBody())
endif
next
endif
end while

print "result: " + validstr(regToken) + " for " + validstr(customerId) + " at " + validstr(creationTime)

return 3

End Function


'***************************************************************
' The retryInterval is used to control how often we retry and
' check for registration success. its generally sent by the
' service and if this hasn't been done, we just return defaults
'***************************************************************
Function getRetryInterval() As Integer
if m.retryInterval < 1 then m.retryInterval = 30
return m.retryInterval
End Function


'**************************************************************
' The retryDuration is used to control how long we attempt to
' retry. this value is generally obtained from the service
' if this hasn't yet been done, we just return the defaults
'**************************************************************
Function getRetryDuration() As Integer
if m.retryDuration < 1 then m.retryDuration = 900
return m.retryDuration
End Function


'******************************************************
'Load/Save RegistrationToken to registry
'******************************************************

Function loadRegistrationToken() As dynamic
m.RegToken = RegRead("RegToken", "Authentication")
if m.RegToken = invalid then m.RegToken = ""
return m.RegToken
End Function

Sub saveRegistrationToken(token As String)
RegWrite("RegToken", token, "Authentication")
End Sub

Sub deleteRegistrationToken()
RegDelete("RegToken", "Authentication")
m.RegToken = ""
End Sub

Function isLinked() As Dynamic
if Len(m.RegToken) > 0 then return true
return false
End Function

'******************************************************
'Show congratulations screen
'******************************************************
Sub showCongratulationsScreen()
port = CreateObject("roMessagePort")
screen = CreateObject("roParagraphScreen")
screen.SetMessagePort(port)

screen.AddHeaderText("Congratulations!")
screen.AddParagraph("You have successfully linked your Roku player to your account")
screen.AddParagraph("Select 'start' to begin.")
screen.AddButton(1, "start")
screen.Show()

while true
msg = wait(0, screen.GetMessagePort())

if type(msg) = "roParagraphScreenEvent"
if msg.isScreenClosed()
print "Screen closed"
exit while
else if msg.isButtonPressed()
print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
exit while
else
print "Unknown event: "; msg.GetType(); " msg: "; msg.GetMessage()
exit while
endif
endif
end while
End Sub

0 Kudos
RokuChris
Roku Employee
Roku Employee

Re: So I need two little changes made to my VideoPlayer exam

"360tv" wrote:
http.PostFromStringWithTimeout worked. I'm not sure why specifiing a timeout keeps it from crashing, but I'll deal with it.


Adding the timeout is not really what kept it from crashing. The original problem is that PostFromString is a function on roURLTransfer, but the variable you were trying to invoke that function on was not a roURLTransfer. Your http variable is a roAssociativeArray. That roAssociativeArray has no attribute named PostFromString, so your code crashed.

Your http variable does have an attribute called PostFromStringWithTimeout which is a reference to a function called http_post_from_string_with_timeout, which is why things worked after the change.

The other suggestion, using http.http.PostFromString would also work because your http variable has an attribute named http which is a roURLTransfer and calling PostFromString on a roURLTransfer object is valid.
0 Kudos
360tv
Streaming Star

Re: So I need two little changes made to my VideoPlayer exam

After reading that slowly and a few times over, I think that made sense. Thank you.
0 Kudos
360tv
Streaming Star

Re: So I need two little changes made to my VideoPlayer exam

Any ideas about my registration repeating problem?
0 Kudos
360tv
Streaming Star

Re: So I need two little changes made to my VideoPlayer exam

All Fixed.
0 Kudos
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.