Posts From Category: roku

How to use PUT or DELETE with a roUrlTransfer object in Brightscript

In any other languages using alternatives to POST and GET is a fairly simple operation. In Brightscript however using PUT and DELETE operations isn’t particularly well documented in the SDK docs.

To add PUT or DELETE we need to set the request type on our roUrlTransfer object. In a standard GET request you’d have something like this:

function httpGetRequest(url as String) as Object
 request = createObject("roUrlTransfer")
 request.setURL(url)
 response = request.getToString()
 return response
end function

But to use a DELETE or PUT request you need to set the request type as well as using the asyncPostFromString or postFromString call. So to use a PUT use something like:

function httpPutRequest(url as String, body as String) as Void
 request = createObject("roUrlTransfer")
 request.setURL(url)
 request.setRequest("PUT")
 request.postFromString(body)
end function

Or similarly a DELETE:

function httpDeleteRequest(url as String, body as String) as Void
 request = createObject("roUrlTransfer")
 request.setURL(url)
 request.setRequest("DELETE")
 request.postFromString(body)
end function

Read More

Mood

Exiting out of a Brightscript SceneGraph application

To exit a a SceneGraph application you have to complete executions of your main method. A nice easy way to do this is to observe a field on your scene and then fire a roSGNodeEvent via the port (Once you’ve read this you can download a full working app that demonstrates the below here. It’s pretty sweet).

You’ve probably got something like the following in your main app brs file.

screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
scene = screen.CreateScene("mainScene")
screen.show()
scene.setFocus(true)

while(true)
  msg = wait(0, m.port)
  msgType = type(msg)

  if msgType = "roSGScreenEvent" then
    if msg.isScreenClosed() then
      return
    end if
  end if
end while

This would exit out if you clicked back on the RCU when the scene is focused as msg.isScreenClosed() would be true - but what if we wanted to close the app on another event? It’s actually pretty simple to do. The main challenge is exiting out of the while loop. A handy way is to add an observer to the scene and pass the port as the handler.

You could modify this main screen to look something like:

screen = CreateObject("roSGScreen")
m.port = CreateObject("roMessagePort")
screen.setMessagePort(m.port)
scene = screen.CreateScene("mainScene")
screen.show()
scene.observeField("exitApp", m.port)
scene.setFocus(true)

while(true)
  msg = wait(0, m.port)
  msgType = type(msg)

  if msgType = "roSGScreenEvent" then
    if msg.isScreenClosed() then
      return
    else if msgType = "roSGNodeEvent" then
      field = msg.getField()
      if field = "exitApp" then
        return
      end if
    end if
  end if
end while

By adding the observer scene.observeField("exitApp", m.port) on the scene a roSGNodeEvent msg will fire on m.port when we change the exitApp interface field. It’s a nice succinct way of handling this.

Set up your MainScene.xml so it has an observable interface boolean field called exitApp or similar:

<?xml version="1.0" encoding="utf-8" ?>

<component name="MainScene" extends="OverhangPanelSetScene" >
    <interface>
        <field id="exitApp" type="boolean" value="false" />
    </interface>

    <children>

    </children>
    <script type="text/brightscript" uri="pkg://components/MainScene.brs" />
</component>

Then you need to setup your MainScene.brs to alter the exitApp variable on an OK click:

function init() as Void
    print "ExitApp"
end function

function onKeyEvent(key as String, press as Boolean) as Boolean
    if key = "OK" then
        m.top.exitApp = true
    end if
end function

Download the source for this here.

Read More

Mood

How to calculate how much texture memory an image will use on a Roku box

Ever found your Roku app running sluggish or even crashing? If you’re building an image heavy application you may be bumping up against your texture memory limits. Since Roku introduced SceneGraph there have been massive improvements in memory handling and a visible reduction in crashes over apps that use SDK1 but have you ever wondered how to calculate how much texture memory an image will take? (Probably not you say? Well I’ll tell you how anyways).

It’s actually fairly simple and comes down to the dimensions of the image rather than any kind of compression technique.

To figure out how much texture memory an image will use in kilobytes just use the following formula (where numberOfChannels is always 4 - RGB and alpha):

(width * height * numberOfChannels) / 1024

To get megabytes just divide by 1024 again.

So if you had an image of dimensions 1280 x 720 you can calculate that this will take up:

(1280 * 720 * 4) / 1024 = 3600 kBs (Approx 3.5 mBs)

Read More

Mood

Using HTTPS on a Roku device

I was once developing a Roku application and switched from a staging environment to (what was supposed to be) an identical production environment and everything stopped working. It turned out that the only difference with the API was one was HTTP and one was HTTPS. I know, cool story, bear with me.

Generally for a HTTP request you have something like this sat in a task node (to make it asynchronous):

function httpGetRequest(url as String) as Object
	request = createObject("roUrlTransfer")
	request.setURL(url)
	response = request.getToString()
	return response
end function

This is simplified version of what you actually would have as Roku isn’t the best at handling anything other than POST/GET requests - you’d need to handle these yourself (I’ll cover this in another post).

To enable HTTPS you have to set the certificates file and then initialise it. The certificate file is either the .pem file on your web server or the common one listed below (if you don’t know try it with the file listed below, it is included on all Roku boxes). Add the following to the code we wrote above:

if left(url, 5) = "https" then
	request.setCertificatesFile("common:/certs/ca-bundle.crt")
	request.initClientCertificates()
end if

The complete request would look something like this:

function httpGetRequest(url as String) as Object
	request = createObject("roUrlTransfer")
	if left(url, 5) = "https" then
		request.setCertificatesFile("common:/certs/ca-bundle.crt")
		request.initClientCertificates()
	end if
	request.setURL(url)
	response = request.getToString()
	return response
end function

Read More