Thru-You Video App

From DevWiki

Revision as of 08:22, 14 June 2010 by Rafael (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Building Your First Application

Thru-You

one of my favorite sites these days is http://thru-you.com, and i thought it would make for a great boxee app. ThruYOU was built by kutiman. he took videos from YouTube sampled and mixed them together to create some really cool music.

following are the steps i have taken in order to build the ThruYou app on boxee:

(once you install the ThruYou app on boxee you will be able to find the source code in the app folder ~/Library/Application Support/BOXEE/UserData/apps/thru-you)

first thing i did was go on YouTube and look for the playlist of the music videos. then i skimmed through the YouTube API and found how to get a standard RSS out of a playlist http://gdata.youtube.com/feeds/api/playlists/88C4BAB8ACE6684C?v=2&alt=rss (usually the YouTube API returns ATOM which boxee currently does not support).

once i had the RSS for the playlist i started building the boxee application.

i created a new folder for the application in the applications folder path (~/Library/Application Support/BOXEE/UserData/apps/) and named it thru-you. then i created the application descriptor file at the folder root. the important parts of the descriptor file are the unique application id, thru-you in this case, the type of the application which is set to skin, the start window id which i set to 14000 and the supported boxee platforms and versions.

this is the final descriptor file:

<app>
	<id>thru-you</id>
	<name>THRU YOU</name>
	<version>1.0</version>
	<description>THRU YOU | Kutiman mixes YouTube</description>
	<thumb>http://dir.boxee.tv/apps/thru-you/thumb.png</thumb>
	<repository>http://dir.boxee.tv/apps</repository>
	<media>video</media>
	<copyright>Boxee</copyright>
	<email>support@boxee.tv</email>
	<type>skin</type>
	<startWindow>14000</startWindow>
	<platform>all</platform>
	<minversion>0.9.12</minversion>
 </app>

next step was to add a skin folder to the application. in the boxee application API the skin files, which are xml flies, hold both the UI and the logic itself through python code. the skin folder has two parts the xml files folder path at ~/Library/Application Support/BOXEE/UserData/apps/thru-you/skin/Boxee Skin NG/720p which holds the skin xml files and the media folder path at ~/Library/Application Support/BOXEE/UserData/apps/thru-you/skin/Boxee Skin NG/media which holds the skin graphical assets.

i wanted the boxee app to have a similar look and feel to the site itself, so i made screenshots of the opening screen and of the main screen. i GIMPed them a little (i’m using GIMP as an image editor… not for the faint of heart), mainly removing the track names from the right side of the screen, then i placed the PNGs in the media folder.

i created the skin file in the 720p folder and called it main.xml. i added a window header:

<window type="window" id="14000">
	<defaultcontrol always="true">100</defaultcontrol>
	<controls>

added a white background as an image control:

<control type="image">
	<posx>0</posx>
	<posy>0</posy>
	<width>1280</width>
	<height>720</height>
	<texture>white.png</texture>
 </control>

(in general boxee has two basic textures white.png and black.png which can always be used and manipulated for color and transparency using the colordiffuse property)

i wanted to have a splash screen and then main screen like in the site itself, so i created the splash screen as a big button with the graphics and the main screen as a hidden group control with an image holding the background. as you can see the id for the button is set to 100 which is also the window default control id, so when opened the focus will be on it. in the button’s onclick event i added python code to hide the button and show the group holding the main screen and move the focus to it.

<control type="button" id="100">
	<posx>382</posx>
	<posy>154</posy>
	<width>515</width>
	<height>412</height>
	<label>-</label>
	<texturenofocus>start.png</texturenofocus>
	<texturefocus>start.png</texturefocus>
	<onclick lang="python"><![CDATA[
 mc.GetWindow(14000).GetControl(100).SetVisible(False)
 mc.GetWindow(14000).GetControl(110).SetVisible(True)
 mc.GetWindow(14000).GetControl(110).SetFocus()
 ]]></onclick>
 </control>
 <control type="group" id="110">
	<visible>false</visible>
	<control type="image">
		<posx>156</posx>
		<posy>0</posy>
		<width>968</width>
		<height>720</height>
		<texture>main.png</texture>
	</control>
 </control>

the main part of the application is the container, it will fetch the playlist from youtube and play the videos themselves. i added a vertical list container and in it i added an image and a label control for the regular and the focused state. in the label control i formatted the text to uppercase and in the focused state i added a scroll property to scroll the text if its longer then the line. i set the content property to url and added the url for the youtube playlist RSS. in the onclick event i added python code which gets the focused item in the list and sends it to the player, i could have just left it empty and the list would have done that automatically, but i wanted to give an example of how you can manipulate items when they are clicked. this can later be used to create a playlist from the items in the list and start playing from the selected item. in addition you might have noticed that i placed the labels in the focused state, that’s because i wanted to add another button to the screen and when the other button will be focused i would like the list to look as it has no focus (by default the item stays focused). i did that by using the visible property and setting the condition to the list focused state.

<control type="list" id="111">
	<posx>786</posx>
	<posy>222</posy>
	<width>337</width>
	<height>224</height>
	<onleft>-</onleft>
	<onright>-</onright>
	<onup>-</onup>
	<ondown>112</ondown>
	<scrolltime>200</scrolltime>
	<pagecontrol>-</pagecontrol>
	<orientation>vertical</orientation>
	<itemlayout width="337" height="28">
		<control type="image">
			<posx>0</posx>
			<posy>0</posy>
			<width>337</width>
			<height>28</height>
			<texture>white.png</texture>
			<colordiffuse>FFD33B37</colordiffuse>
		</control>
		<control type="label">
			<posx>0</posx>
			<posy>0</posy>
			<width>337</width>
			<height>28</height>
			<font>font28b</font>
			<align>left</align>
			<aligny>center</aligny>
			<label>[UPPERCASE]$INFO[ListItem.Label][/UPPERCASE]</label>
			<textcolor>white</textcolor>
			<selectedcolor>FFFDF041</selectedcolor>
		</control>
	</itemlayout>
	<focusedlayout width="337" height="28">
		<control type="image">
			<posx>0</posx>
			<posy>0</posy>
			<width>337</width>
			<height>28</height>
			<texture>white.png</texture>
			<colordiffuse>FFD33B37</colordiffuse>
		</control>
		<control type="label">
			<visible>!Control.HasFocus(111)</visible>
			<posx>0</posx>
			<posy>0</posy>
			<width>337</width>
			<height>28</height>
			<font>font28b</font>
			<align>left</align>
			<aligny>center</aligny>
			<label>[UPPERCASE]$INFO[ListItem.Label][/UPPERCASE]</label>
			<textcolor>white</textcolor>
			<selectedcolor>FFFDF041</selectedcolor>
		</control>
		<control type="label">
			<visible>Control.HasFocus(111)</visible>
			<posx>0</posx>
			<posy>0</posy>
			<width>337</width>
			<height>28</height>
			<font>font28b</font>
			<align>left</align>
			<aligny>center</aligny>
			<label>[UPPERCASE]$INFO[ListItem.Label][/UPPERCASE]</label>
			<textcolor>FFFDF041</textcolor>
			<selectedcolor>FFFDF041</selectedcolor>
			<scroll>true</scroll>
			<scrollspeed>30</scrollspeed>
		</control>
	</focusedlayout>
	<content type="url" url="rss://gdata.youtube.com/feeds/api/playlists/88C4BAB8ACE6684C?v=2&alt=rss">
		<onclick lang="python"><![CDATA[
 n = mc.GetWindow(14000).GetList(111).GetFocusedItem()
 items = mc.GetWindow(14000).GetList(111).GetItems()
 if mc.GetPlayer().IsPlaying():
 mc.GetPlayer().Stop()
 mc.GetPlayer().Play( items[n] )
 ]]></onclick>
	</content>
 </control>

as i played with the application i noticed that all the items in the playlist RSS have a prefix “Kutiman-Thru-you - 01 -” which i didn’t want to display. so i added an onload event to the window to change that. in the python code i take the list items after they are loaded from the RSS and by iterating through them i remove the prefix and change it to look like the original site.

<onload lang="python"><![CDATA[
 items = mc.GetWindow(14000).GetList(111).GetItems()
 for item in items:
    label = item.GetLabel()
    label = label[label.find("- 0") + 2:len(label)]
    label = label.replace(" - ", ". ")
    item.SetLabel(label)
 ]]></onload>

i spoke with kutiman, the creator of the site, and he asked me to include the specific credits to all contributing videos, so i added a button and a text control for the credits. the button looks like an item from the list and it toggles the visibility of the text control through python code. the text controls hold the credits text and is set to slowly scroll down.

<control type="button" id="112">
	<colordiffuse>FFD33B37</colordiffuse>
	<onleft>-</onleft>
	<onright>-</onright>
	<onup>111</onup>
	<ondown>-</ondown>
	<posx>786</posx>
	<posy>474</posy>
	<width>200</width>
	<height>28</height>
	<label>CREDITS</label>
	<font>font28b</font>
	<textcolor>white</textcolor>
	<focusedcolor>FFFDF041</focusedcolor>
	<texturenofocus>white.png</texturenofocus>
	<texturefocus>white.png</texturefocus>
	<onclick lang="python"><![CDATA[
 if mc.GetWindow(14000).GetControl(113).IsVisible():
    mc.GetWindow(14000).GetControl(113).SetVisible(False)
 else:
    mc.GetWindow(14000).GetControl(113).SetVisible(True)
 ]]></onclick>
 </control>
 <control type="textbox" id="113">
	<visible>false</visible>
	<posx>180</posx>
	<posy>150</posy>
	<width>600</width>
	<height>380</height>
	<font>font21sq</font>
	<textcolor>white</textcolor>
	<label>01. Mother of All Funk Chords[CR]tU8gmozj8xY Theremin[CR][CR]6FX_84iWPLU drums[CR] [CR]gl-CxMiW-1Y bass also at :   playbassnow.com[CR][CR]fvw2UuofYyQ Funk Guitar[CR][CR]h7IFYh8TrIs gts-solo...</label>
	<pagecontrol>60</pagecontrol>
	<autoscroll delay="3000" time="1000" repeat="10000">true</autoscroll>
 </control>

last thing i wanted to add to the application is a video window so even when going back to the application you will be able to see the video playing in the background. that is easily done by adding a videowindow control in the black area on the screen.

<control type="videowindow">
	<posx>156</posx>
	<posy>60</posy>
	<width>600</width>
	<height>558</height>
 </control>

that's it, the application is ready. i hope that was not too painful. i will add more samples and tutorials to show how you can create more complicated and rich applications. feel free to poke around the applications folder and look at the code, there are lots of good examples there.

Personal tools