Smart TV platforms


RokuOS: from Roku
Tech: linux – native layer: Application Framework – BrightScript for apps
Used by: TCL Hisense Haier Hitachi Insignia Westinghouse

FireTV: from Amazon.
Tech: Android based, see Android TV

tvOS: from Apple

Android TV: from Google
Tech: Linux – [libraries + ART Android Run Time] – Application Framework – apps
Used by: Sharp Hisense Philips Sony Toshiba

Tizen OS: from Samsung, used by Samsung
Tech: Linux – HTML5-based, free, also for wearables

Panasonic: my Home Screen Firefox OS
LG: webOS
Viera Cast and Viera Connect
TiVo: apps are HTML 5 based and live in Opera TV store
Vizio TV: TV has Chromecast built-in
Reference https://www.kodifiretvstick.com/smart-tvs-that-run-android/

Roku SDK: legacy vs SceneGraph


How video is played, legacy vs SceneGraph, or SDK1 vs SDK2
Screen creation:
SDK1: CreateObject(“roScreen”, true)
SDK2: CreateObject(“roSGScreen”) followed by CreateScene
Video object creation:
SDK1: CreateObject(“roVideoPlayer”)
SDK2: CreateObject(“roSGNode”, “Video”) followed by reparent to scene
Start video playing:
SDK1: video.Play()
SDK2: video.control = “play”
Event loop:
Nothing more than an empty dead loop, like while(true) end while, just to prevent main from exiting

Source code: http://riowing.net/p/sdk1vs2.zip

Brightscript library called directly by firmware


It is obvious that main/runUserInterface in a channel, instead of library, is called by firmware.
How to make a function in library, instead of channel, that gets called without involving main/runUserInterface?
Here is a sample library to show how FW call BRS as it does with GrandCentral library.
Firmware loads roku_grandcentral_lib.zip, and calls launchContent.
On Brightscript side:
manifest file:
required: os_markup=1 sg_component_libs_provided=Roku_GrandCentral
sg_component_libs_provided so that FW knows it is a library instead of channel
optional: major_version, hidden=1
.xml file:
required: <field id=”scene” type=”node”/>
optional: base class of ContentLauncher, extends=”Node”, is not required
.brs:
required: the function being caalled by FW: launchContent
optional: init()
Folder structure and file name of xml and brs dont make difference.

On FW side:called in LaunchController.cpp

The way we know the function did get called:
check port 8085, and look for log message “Function launchContent is called by FW.”

BrightScript m variable


BrightScript is the language to program Roku streaming player.
The m keyword can be confusing.
code snippet from source/main.brs tagged with MvsThis, which stands for m vs this.

Function MvsThisCreate() as Object
	print "MvsThisCreate entered"
	obj = CreateObject("roAssociativeArray")
	obj.svc = "MvsThisSvc"
	obj.MvsThisFunc = MvsThisFunc
	obj.MvsThisFunc2 = MvsThisFunc2
	return obj
End Function

Function MvsThisFunc() as Void
	print "MvsThisFunc entered"
	print "MvsThisFunc m.svc="m.svc
	print "MvsThisFunc m.MvsThisFunc2="m.MvsThisFunc2
	print "MvsThisFunc MvsThisFunc2="MvsThisFunc2
	m.MvsThisFunc2("m.MvsThisFunc2")
	MvsThisFunc2("MvsThisFunc2")
End Function

Function MvsThisFunc2(str as String) as Void
	print "MvsThisFunc2 called by: "str
End Function

Function MvsThisTest() as Void
	print "MvsThisTest start"
	MvsThis = MvsThisCreate()
	MvsThis.MvsThisFunc()
	print "MvsThisTest done"
End Function

When we run MvsThisTest(), we get these output:

	MvsThisTest start
	MvsThisCreate entered
	MvsThisFunc entered
	MvsThisFunc m.svc=MvsThisSvc
	MvsThisFunc m.MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc2 called by: m.MvsThisFunc2
	MvsThisFunc2 called by: MvsThisFunc2

As shown above, m is for accessing data in roAssociativeArray from roAssociativeArray’s function fields.
Calling m.MvsThisFunc2( and MvsThisFunc2(, without the m. are the same thing when the object is roAssociativeArray.
Calling m.MvsThisFunc2() doesn’t work if the object is SceneGraph node, e.g. loaded as xml file.