Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Starting from Roku SDK video player example
- Loading branch information
1 parent
fb48592
commit 8304361
Showing
54 changed files
with
2,508 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
######################################################################### | ||
# Simple makefile for packaging Roku Video Player example | ||
# | ||
# Makefile Usage: | ||
# > make | ||
# > make install | ||
# > make remove | ||
# | ||
# Important Notes: | ||
# To use the "install" and "remove" targets to install your | ||
# application directly from the shell, you must do the following: | ||
# | ||
# 1) Make sure that you have the curl command line executable in your path | ||
# 2) Set the variable ROKU_DEV_TARGET in your environment to the IP | ||
# address of your Roku box. (e.g. export ROKU_DEV_TARGET=192.168.1.1. | ||
# Set in your this variable in your shell startup (e.g. .bashrc) | ||
########################################################################## | ||
APPNAME = videoplayer | ||
VERSION = 1.0 | ||
|
||
ZIP_EXCLUDE= -x xml/* -x artwork/* -x \*.pkg -x storeassets\* -x keys\* -x \*/.\* | ||
|
||
include ../app.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
The videoplayer example demonstrates a hierarchical, | ||
category based video playback application. The | ||
application allows the playback of a selection | ||
of TED Talks videos which are organized by category. | ||
|
||
The application uses a category based XML feed | ||
to drive the application. The XML describes all | ||
of the categories used, artwork required and | ||
videos to be played. The hierarchy of categories | ||
is described in the file categories.xml. | ||
The actual XML request/response uses our servers, | ||
but the XML is all included for reference. | ||
|
||
Each category branch node, ultimately terminates at a | ||
leaf node that lists details for all of the videos | ||
included in that category. The XML for the leaf | ||
nodes is also included and named in the format | ||
<category>.xml. | ||
|
||
It is possible to easily use this as a template | ||
for a production application by implementing the | ||
appropriate web service API's to provide the | ||
category and content XML feeds. You must also | ||
provide the artwork and brand specific assets | ||
appropriate for your application. | ||
|
||
Contents of the application directories are: | ||
|
||
images - Artwork that is embedded as part of | ||
the application. In general, this | ||
should be kept to a minimum to conserve | ||
space on flash, and is usually just the | ||
main menu icons, plus the logo and | ||
overhang used for branding. | ||
source - The complete BrightScript source code | ||
for the application | ||
xml - Examples of the XML returned by the | ||
server for reference | ||
artwork - Examples of the artwork returned by the | ||
server for reference. | ||
manifest - This file describes the application | ||
package and is used on the main menu | ||
prior to the start of execution for the | ||
application. | ||
Makefile - Optional method of building the application | ||
using "make". This has been provided for | ||
convenience and tested on OSX and linux. | ||
|
||
|
||
Note: The xml and artwork directories are NOT part of the application | ||
package, but can be saved as an archive using the "make archive" | ||
target. The makefile also can push the development app directly | ||
to the device if "make" and "curl" are available. See the comments | ||
in the Makefile for more information. | ||
|
||
************************************************** | ||
|
||
This example uses videos streamed directly from the TED Talks | ||
website (www.ted.com). Please visit the TED website to see the | ||
full lineup of talks made available by TED. | ||
|
||
Please see the following for license details: | ||
http://creativecommons.org/licenses/by-nc-nd/3.0/ | ||
|
||
|
||
|
||
|
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
title=TED Talks | ||
subtitle=Video player example using category based XML feeds | ||
mm_icon_focus_hd=pkg:/images/MainMenu_Icon_CenterFocus_HD.png | ||
mm_icon_side_hd=pkg:/images/MainMenu_Icon_Side_HD.png | ||
mm_icon_focus_sd=pkg:/images/MainMenu_Icon_CenterFocus_SD.png | ||
mm_icon_side_sd=pkg:/images/MainMenu_Icon_Side_SD.png | ||
major_version=1 | ||
minor_version=0 | ||
build_version=00001 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
'********************************************************** | ||
'** 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("video") | ||
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]) | ||
endif | ||
if msg.GetIndex() = 2 | ||
showList[showIndex].PlayStart = 0 | ||
showVideoScreen(showList[showIndex]) | ||
endif | ||
if msg.GetIndex() = 3 | ||
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() | ||
screen.AddButton(1, "resume playing") | ||
screen.AddButton(2, "play from beginning") | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
'***************************************************************** | ||
'** Video Player Example Application -- Home Screen | ||
'** November 2009 | ||
'** Copyright (c) 2009 Roku Inc. All Rights Reserved. | ||
'***************************************************************** | ||
|
||
'****************************************************** | ||
'** Perform any startup/initialization stuff prior to | ||
'** initially showing the screen. | ||
'****************************************************** | ||
Function preShowHomeScreen(breadA=invalid, breadB=invalid) As Object | ||
|
||
if validateParam(breadA, "roString", "preShowHomeScreen", true) = false return -1 | ||
if validateParam(breadA, "roString", "preShowHomeScreen", true) = false return -1 | ||
|
||
port=CreateObject("roMessagePort") | ||
screen = CreateObject("roPosterScreen") | ||
screen.SetMessagePort(port) | ||
if breadA<>invalid and breadB<>invalid then | ||
screen.SetBreadcrumbText(breadA, breadB) | ||
end if | ||
|
||
screen.SetListStyle("flat-category") | ||
screen.setAdDisplayMode("scale-to-fit") | ||
return screen | ||
|
||
End Function | ||
|
||
|
||
'****************************************************** | ||
'** Display the home screen and wait for events from | ||
'** the screen. The screen will show retreiving while | ||
'** we fetch and parse the feeds for the game posters | ||
'****************************************************** | ||
Function showHomeScreen(screen) As Integer | ||
|
||
if validateParam(screen, "roPosterScreen", "showHomeScreen") = false return -1 | ||
|
||
initCategoryList() | ||
screen.SetContentList(m.Categories.Kids) | ||
screen.SetFocusedListItem(3) | ||
screen.Show() | ||
|
||
while true | ||
msg = wait(0, screen.GetMessagePort()) | ||
if type(msg) = "roPosterScreenEvent" then | ||
print "showHomeScreen | msg = "; msg.GetMessage() " | index = "; msg.GetIndex() | ||
if msg.isListFocused() then | ||
print "list focused | index = "; msg.GetIndex(); " | category = "; m.curCategory | ||
else if msg.isListItemSelected() then | ||
print "list item selected | index = "; msg.GetIndex() | ||
kid = m.Categories.Kids[msg.GetIndex()] | ||
if kid.type = "special_category" then | ||
displaySpecialCategoryScreen() | ||
else | ||
displayCategoryPosterScreen(kid) | ||
end if | ||
else if msg.isScreenClosed() then | ||
return -1 | ||
end if | ||
end If | ||
end while | ||
|
||
return 0 | ||
|
||
End Function | ||
|
||
|
||
'********************************************************** | ||
'** When a poster on the home screen is selected, we call | ||
'** this function passing an associative array with the | ||
'** data for the selected show. This data should be | ||
'** sufficient for the show detail (springboard) to display | ||
'********************************************************** | ||
Function displayCategoryPosterScreen(category As Object) As Dynamic | ||
|
||
if validateParam(category, "roAssociativeArray", "displayCategoryPosterScreen") = false return -1 | ||
screen = preShowPosterScreen(category.Title, "") | ||
showPosterScreen(screen, category) | ||
|
||
return 0 | ||
End Function | ||
|
||
'********************************************************** | ||
'** Special categories can be used to have categories that | ||
'** don't correspond to the content hierarchy, but are | ||
'** managed from the server by data from the feed. In these | ||
'** cases we might show a different type of screen other | ||
'** than a poster screen of content. For example, a special | ||
'** category could be search, music, options or similar. | ||
'********************************************************** | ||
Function displaySpecialCategoryScreen() As Dynamic | ||
|
||
' do nothing, this is intended to just show how | ||
' you might add a special category ionto the feed | ||
|
||
return 0 | ||
End Function | ||
|
||
'************************************************************ | ||
'** initialize the category tree. We fetch a category list | ||
'** from the server, parse it into a hierarchy of nodes and | ||
'** then use this to build the home screen and pass to child | ||
'** screen in the heirarchy. Each node terminates at a list | ||
'** of content for the sub-category describing individual videos | ||
'************************************************************ | ||
Function initCategoryList() As Void | ||
|
||
conn = InitCategoryFeedConnection() | ||
|
||
m.Categories = conn.LoadCategoryFeed(conn) | ||
m.CategoryNames = conn.GetCategoryNames(m.Categories) | ||
|
||
End Function |
Oops, something went wrong.