<?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom"><title>Dev.Opera</title><link href="https://dev.opera.com/"/><link type="application/atom+xml" rel="self" href="https://dev.opera.com/feed/"/><updated>2017-02-07T17:38:22+00:00</updated><id>https://dev.opera.com/</id><author><name>Dev.Opera editors</name><email></email></author><entry><id>https://dev.opera.com/tv/tv-snap-mrss-requirements/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/tv-snap-mrss-requirements/"/><title>Opera TV Snap Data Format Requirements</title><published>2016-06-09T00:00:00+00:00</published><updated>2016-06-09T00:00:00+00:00</updated><author><name>Oskar Furga</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="table-of-contents">Table of Contents</h2>

<ul>
  <li><a href="#introduction">Introduction</a>
    <ul>
      <li><a href="#basics">Basics</a></li>
    </ul>
  </li>
  <li><a href="#mrss">Opera MRSS</a>
    <ul>
      <li><a href="#feed">Feed example</a></li>
      <li><a href="#metadata">Opera metadata</a></li>
      <li><a href="#item">Item example</a></li>
      <li><a href="#visualization">Visualization</a></li>
    </ul>
  </li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>Opera TV Snap is an industry-first, end-to-end solution that allows content publishers to create and submit a Smart TV app to the Opera TV Store quickly and easily, for free. See the <a href="http://www.opera.com/tvsnap/">Opera TV Snap page</a> for more details.</p>

<h3 id="basics">Basics</h3>

<p>Specifications you should be aware of before preparing a video feed for the TV Snap Template:</p>

<ul>
  <li><a href="http://rssboard.org/rss-specification/">RSS specification</a>.</li>
  <li><a href="http://rssboard.org/media-rss/">MRSS specification</a>.</li>
  <li><a href="http://rssboard.org/rss-validator/">RSS feed validator</a>.</li>
  <li><a href="http://rssboard.org/rss-validator/">RFC822</a> for date and time.</li>
  <li><a href="https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/">HTML5 Audio and Video Support in Opera TV Store Applications</a></li>
  <li>16:9 thumbnail ratio is a must. 256 × 144 px is minimal and recommended for the best user experience. If the image is greater, it will be scaled down to 256 px.</li>
</ul>

<h2 id="mrss">Opera MRSS</h2>

<p>TV Snap 3.0 Template uses Opera Media RSS Specification (OMRSS).</p>

<ul>
  <li>Feed must point to the MRSS compliant data.</li>
  <li>MRSS may contain more tags than TV Snap Template supports, but they will be ignored.</li>
  <li>We are still trying to provide backward compatibility with RSS, but OMRSS format is recommended and contains many improvements. Feed without <code>media</code> namespace will be parsed, but support for this format might be removed in the future.</li>
</ul>

<h3 id="feed">Feed example</h3>

<p>Required tags are:</p>

<ul>
  <li><code>&lt;rss&gt;</code> as a top level tag.</li>
  <li>One <code>&lt;channel&gt;</code> as a child of <code>&lt;rss&gt;</code>.</li>
  <li><code>&lt;channel&gt;</code> must contain <code>&lt;title&gt;</code> and at least one <code>&lt;item&gt;</code>.</li>
  <li>Each <code>&lt;item&gt;</code> must be a child of <code>&lt;channel&gt;</code>.</li>
</ul>

<p>Optional tags:</p>

<ul>
  <li><code>&lt;link rel="next"&gt;</code> with proper <code>href</code> should point to the next page of results.</li>
  <li><code>&lt;opera:metadata&gt;</code> as a child of <code>&lt;channel&gt;</code>
    <ul>
      <li>It is used as a wrapper to define nested categories.</li>
      <li>You can indefinitely nest categories inside another one.</li>
    </ul>
  </li>
</ul>

<p>Example feed: <a href="http://apps.tvstore.opera.com/broadcastspec/opera_mrss_for_broadcasters.xml">Opera MRSS</a></p>

<p>Feed structure:</p>

<pre><code>&lt;rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:opera="http://apps.tvstore.opera.com/broadcastspec/" version="2.0"&gt;
	&lt;channel&gt;
		&lt;title&gt;Channel Title&lt;/title&gt;
		&lt;description&gt;Description of channel content&lt;/description&gt;
		&lt;opera:metadata&gt;
			&lt;!-- categoryData items - see next section --&gt;
		&lt;/opera:metadata&gt;
		&lt;item&gt;&lt;!-- See example in next section --&gt;&lt;/item&gt;
		&lt;item&gt;&lt;!-- … --&gt;&lt;/item&gt;
		&lt;!-- More items --&gt;
		&lt;link rel="next" href="[next results page]"/&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</code></pre>

<h3 id="metadata">Opera metadata</h3>

<p>Inside <code>&lt;opera:metadata&gt;</code> you can put <code>&lt;opera:categoryData&gt;</code> to define categories and collections (nested categories).</p>

<p><strong>Important</strong>: If you use metadata to define categories then in <code>&lt;media:category&gt;</code> you should use <code>path</code> instead of real category name (it will be taken from <code>categoryData</code>’s <code>label</code>)</p>

<p>Required attributes of <code>categoryData</code>:
- <code>path</code> argument defines category nesting. For each nested category you should define exactly one <code>categoryData</code> with correct <code>path</code>.
- <code>label</code> is name of category</p>

<p>Optional attributes of <code>categoryData</code>:
- <code>description</code> is description of category.
- <code>order</code> argument is optional. If it’s not passed then order will be based on MRSS feed order.
- <code>background</code> attribute replaces application’s background whenever user visits the category. This image should be in jpg format, 1280x720.
- <code>thumbnail</code>, <code>thumbnailwidth</code> &amp; <code>thumbnailheight</code> are used to display category thumbnail.</p>

<p>Example:</p>

<pre><code>&lt;opera:metadata&gt;
	&lt;!-- 1st category level. --&gt;
	&lt;opera:categoryData order="1" path="videos" label="Clips" description="Section with cool clips."/&gt;
	&lt;!-- 2nd category level. --&gt;
	&lt;opera:categoryData order="1" path="videos/fail" label="Fail Compilations" description="Fail compilations" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
	&lt;opera:categoryData order="2" path="videos/cats" label="Cute Cats" description="All the cute cats in one place" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
	&lt;!-- 3rd category level. --&gt;
	&lt;opera:categoryData order="1" path="videos/cats/black" label="Black Cats" description="Only black cats" /&gt;
	&lt;opera:categoryData order="2" path="videos/cats/white" label="White Cats" description="Only white cats" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
&lt;/opera:metadata&gt;
</code></pre>

<h3 id="item">Item example</h3>

<p>Required tags are:</p>

<ul>
  <li><code>&lt;media:title&gt;</code></li>
  <li><code>&lt;media:content&gt;</code> with correct <code>url</code> &amp; <code>type</code>.
    <ul>
      <li>You might also use <code>&lt;media:group&gt;</code> to group multiple media elements (like video in different formats)</li>
      <li>Content might also contain <code>duration</code> &amp; <code>bitrate</code> attributes.</li>
      <li>Duration should be set as a number of seconds.</li>
      <li>For widest device support and best user experience use mp4 video type with bitrate up to 4000 kbit (see our <a href="https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/">Audio &amp; Video Support</a>).</li>
    </ul>
  </li>
  <li><code>&lt;media:thumbnail&gt;</code> with correct <code>url</code> pointing to an image.
    <ul>
      <li>256 × 144 px format is recommended (see <a href="#basics">Basics</a> for more info)</li>
      <li>If there is more than one thumbnail then best will be selected based on <code>width</code> attribute (if present).</li>
    </ul>
  </li>
  <li>At least one <code>&lt;media:category&gt;</code> is needed but item can belong to many categories. It should contain path to the actual category defined in <code>&lt;opera:metadata&gt;</code> tag if one is present or just a simple name of the category.</li>
</ul>

<p>Optional tags:</p>

<ul>
  <li><code>&lt;pubDate&gt;</code> used to sort movies from newest to oldest
    <ul>
      <li>if not set then order will be set based on feed appearence</li>
    </ul>
  </li>
  <li><code>&lt;media:description&gt;</code> if exist it will be displayed as description for the video.</li>
  <li><code>&lt;media:restriction&gt;</code> used to define country restrictions</li>
  <li><code>&lt;media:keywords&gt;</code> for movie keywords (used in search)</li>
  <li><code>&lt;media:credit&gt;</code> for move credits</li>
  <li><code>&lt;media:subTitle&gt;</code> providing subtitles in VTT format</li>
  <li><code>&lt;opera:orderInCategory&gt;</code> is used to set order of item in category. If item is in many categories then it can have order set to each category separately. It has two required attributes:
    <ul>
      <li><code>path</code> with value the same as defined in category</li>
      <li><code>value</code> as a number (ascending)</li>
    </ul>
  </li>
  <li>Any other MRSS tag (see <a href="http://rssboard.org/media-rss/">MRSS specification</a>)</li>
</ul>

<p>Item structure:</p>

<pre><code>&lt;item&gt;
	&lt;pubDate&gt;Mon, 21 Mar 2016 11:00:01 GMT&lt;/pubDate&gt;
	&lt;media:title&gt;
		Sam Smoothy Follows His Fathers
		Footsteps In The Andes | Lost…
	&lt;/title&gt;
	&lt;media:description&gt;
		Many years ago, Sam Smoothy’s father
		climbed in the Andes mountains…
	&lt;/description&gt;
	&lt;media:category&gt;Skiing&lt;/category&gt;
	&lt;media:category&gt;Winter/Events&lt;/category&gt;
	&lt;opera:orderInCategory path="Winter/Events" value="12"/&gt;
	&lt;media:content url="video.mp4" type="video/mp4"
		bitrate="2200" duration="772"/&gt;
	&lt;media:thumbnail url="thumb.jpg" width="256" height="144"/&gt;
&lt;/item&gt;
</code></pre>

<h3 id="visualization">Visualization</h3>

<p>Below is example application look with defined categories. <em>Latest</em> and <em>Popular Videos</em> categories are generated automatically. Background and thumbnail of this app (right top corner) is provided through the <a href="https://publish.tvstore.opera.com/metadata/new/mrss">submission panel</a> and is not a part of Opera MRSS format.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-snap-mrss-requirements/example-1.jpg" alt="Main page view" />
	<figcaption elem="caption">Main page view</figcaption>
</figure>

<p>Example of TV Snap player.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-snap-mrss-requirements/example-2.jpg" alt="View with collections" />
	<figcaption elem="caption">View with collections</figcaption>
</figure>
]]></content></entry><entry><id>https://dev.opera.com/tv/tv-store-icons-thumbnails-and-screenshots/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/tv-store-icons-thumbnails-and-screenshots/"/><title>Creating TV Store Icons, Thumbnails and Screenshots</title><published>2013-04-30T00:00:00+00:00</published><updated>2013-04-30T00:00:00+00:00</updated><author><name>Chris Mills</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>First impressions are very important for a successful product. It is therefore vital to take your time on graphics that represent your app, and polish them before you publish your work. This short guide provides some tips on making your application’s icon and other graphics the best they can be.</p>

<p>There are three types of graphic that represent applications in the TV Store: Icons, thumbnails, and screenshots. Let’s look at each of these in turn.</p>

<h2 id="icons">Icons</h2>

<p>Icons are the simplest and smallest graphical representation of an app.</p>

<h3 id="size-and-format">Size and format</h3>

<p>In the TV Store we require submission of a 512px × 512px, 24bit PNG file, but in the current UI we display only a 96px × 96px scaled version. Bear in mind that you are designing an icon for a size roughly around 3cm × 3cm in the real world. The large size requirement is for further scaling capabilities, if needed in the future.</p>

<h3 id="style">Style</h3>

<p>We don’t expect compliance with any specific style guidelines in your app icons, but we do expect you to think carefully about your icon’s content. It is recommended that you keep your icons consistent with the style of your apps. For example, a photorealistic, serious design will not be a good representation of a cartoony kids app.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/1.png" alt="A set of clock icons with a check and cross showing that a flat, clear clock icon is a better look than a tilted, stylised icon" />
	<figcaption elem="caption">A set of clock icons with a check and cross showing that a flat, clear clock icon is a better look than a tilted, stylised icon</figcaption>
</figure>

<p>Well designed icons in general are simple, recognisable and intuitive. Also remember that they should be legible on small TVs as well as larger ones. Think about the content of your icon. You only really have space to focus on one concept in an icon, and it will generally be one of three things:</p>

<ol>
  <li><strong>A pictogram:</strong> A picture of something from real life, such as a video camera, tree, dog or flag.</li>
  <li><strong>An ideogram:</strong> An idea of something, such as trust, information, learning, or speed.</li>
  <li><strong>An arbitrary invention:</strong> These don’t commonly exist in real life, but sometimes you’ll want a more abstract invention to represent your app. For example, your app might be represented by some kind of abstract shape or strange invention.</li>
</ol>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/2.jpg" alt="Three icons: A die representing a pictogram, a heart with waves going through it representing an ideogram — pulse or heartbeat, and an abstract design with letters inside it representing an abstract icon" />
	<figcaption elem="caption">Three icons: A die representing a pictogram, a heart with waves going through it representing an ideogram — pulse or heartbeat, and an abstract design with letters inside it representing an abstract icon</figcaption>
</figure>

<p>Next, use established, recognised conventions where possible. Think of well-known icons for “information”, “play” and “shopping cart”, for example. Using such conventions will immediately make your icon more intuitive and recognisable. <a href="http://thenounproject.com/">The Noun project</a> is a great place for researching icon styles and conventions.</p>

<p>Another general tip is to just make your TV app icons fun! Most apps on TV are pure entertainment, so formal, system icons may look out of place.</p>

<h3 id="less-is-more">Less is more</h3>

<p>An icon needs to be simple so it will work at small sizes — don’t employ too many complex shapes in your icon, and stay away from using too much text. Anything more than a simple, short word will reduce clarity below an acceptable level.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/3.jpg" alt="Two copies of a thermometer icon. The one on the right is cluttered with text, and clearly less effective than the simple uncluttered version on the left" />
	<figcaption elem="caption">Two copies of a thermometer icon. The one on the right is cluttered with text, and clearly less effective than the simple uncluttered version on the left</figcaption>
</figure>

<h3 id="effects">Effects</h3>

<p>Moving on from “Less is more”, think carefully about graphics effects you use in your icons. Drop shadows, heavy bevels, glows and halos will not replace drawing skills, metaphors, and great ideas, and may reduce clarity.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/4.jpg" alt="Four similar music-related icons. The first one is simple and flat, and more effective than the other three, which have drop shadows, glow effects and distortion" />
	<figcaption elem="caption">Four similar music-related icons. The first one is simple and flat, and more effective than the other three, which have drop shadows, glow effects and distortion</figcaption>
</figure>

<p>If you decide to use shadows, highlights and reflections in your icons, be consistent with the direction of light, otherwise the icon will look terrible. Unnecessary perspective for a two dimensional icon can also spoil the effect.</p>

<h3 id="background">Background</h3>

<p>Make sure there is a good degree of contrast between your icon and the background it appears on. All icons in store are presented on top of dark placeholders — if you use PNG icons with alpha channels, or dark icons, your icon could become almost invisible. If you are planning on designing a dark icon, you should consider mounting it on top of your own custom background color.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/5.jpg" alt="Four icons. Two are light coloured so look good on the TV store default dark background, and two are dark, so don’t look good on the dark background" />
	<figcaption elem="caption">Four icons. Two are light coloured so look good on the TV store default dark background, and two are dark, so don’t look good on the dark background</figcaption>
</figure>

<h2 id="thumbnails">Thumbnails</h2>

<p>Your thumbnails are where you can give your creativity free rein, creating beautiful app cover art. By default, an app’s thumbnail is used as the graphic representation of an icon in the app store, and the launch shortcut in the “My Apps” section.</p>

<h3 id="technical-details">Technical details</h3>

<p>The required size and format for thumbnail graphics is 480px × 270px, in JPG format.</p>

<h3 id="style-1">Style</h3>

<p>As with your icons, we don’t expect any particular style to be used for your thumbnails, however it should be pleasant to the eye, and consistent with the style of your app and the TV store.</p>

<p>You have a lot more space to play with when designing a thumbnail, but again make them fun, make sure they are a good representation of your apps that will draw users in, and be careful not to make them too cluttered.</p>

<h3 id="background-1">Background</h3>

<p>Thumbnails are displayed on pre-designed placeholders, so there’s no need to shape your thumbnails in any way. Any additional effects applied to thumbnails — such as bevels or shadows — are not allowed.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/6.jpg" alt="Two thumbnail icons, one simple flat icon, and one with a drop shadow and bevel. The simple icon looks better" />
	<figcaption elem="caption">Two thumbnail icons, one simple flat icon, and one with a drop shadow and bevel. The simple icon looks better</figcaption>
</figure>

<h3 id="less-is-more-1">Less is more</h3>

<p>By reducing the amount of extraneous content, you can emphasise more important elements of your composition. Less is more in many cases.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/7.jpg" alt="A die, with dice written in the background and a loud gradient. Just the die would be more effective" />
	<figcaption elem="caption">A die, with dice written in the background and a loud gradient. Just the die would be more effective</figcaption>
</figure>

<h3 id="crop">Crop</h3>

<p>When deciding what to show in a thumbnail, you should consider focusing just on the most important details or features. If your thumbnail is a screenshot of your app’s main UI, consider cropping it down to just show the most important bit, rather than the whole lot.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/8.jpg" alt="Two representations of the same interface. One is zoomed out, and one is cropped to show just the most important feature of the interface" />
	<figcaption elem="caption">Two representations of the same interface. One is zoomed out, and one is cropped to show just the most important feature of the interface</figcaption>
</figure>

<h3 id="text">Text</h3>

<p>If you decide to include text on your thumbnail, limit it to a title, or a single sentence. Including too much text will look messy and lose clarity.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/9.jpg" alt="Two icons for a backgammon game: One has just the game title, while the other contains far more text and looks cluttered" />
	<figcaption elem="caption">Two icons for a backgammon game: One has just the game title, while the other contains far more text and looks cluttered</figcaption>
</figure>

<h3 id="colour">Colour</h3>

<p>There is no better way to give your artwork life than a tasty colour palette. Look around you and get inspiration from a wide variety of sources, online and in nature. There are also a lot of tools around that can help you choose a stunning colour set, for example colorlovers.com.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/10.jpg" alt="A colour palette" />
	<figcaption elem="caption">A colour palette</figcaption>
</figure>

<h3 id="contrast">Contrast</h3>

<p>Contrast between foreground and background colours is important in your thumbnails, however in a larger graphic contrast can also be controlled by size, position, form, light and shadow.</p>

<figure elem="media">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/11.jpg" alt="Two side by side images showing an example of good and bad colour contrast between background and foreground" />
	<figcaption elem="caption">Two side by side images showing an example of good and bad colour contrast between background and foreground</figcaption>
</figure>

<h3 id="white-space">White space</h3>

<p>It is also important to consider the space in between your graphic elements. Not having enough whitespace can make everything seem messy and cluttered, and reduce the impact your thumbnails have.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/12.jpg" alt="A pixel grid with the word “blocks” spelled out by some of the pictures, plus a pair of 3D glasses" />
	<figcaption elem="caption">A pixel grid with the word “blocks” spelled out by some of the pictures, plus a pair of 3D glasses</figcaption>
</figure>

<h3 id="extending-the-thumbnail">Extending the thumbnail</h3>

<p>You may notice from time to time that people around you don’t recognise even perfectly known and famous brands. Extending your thumbnail with some content may help improving people’s understanding of what the app is about. Check out examples below. Can you tell what the apps on the left side are about? The ones on the right are better at communicating what the user can expect from the app in question.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-store-icons-thumbnails-and-screenshots/13.jpg" alt="Examples of well designed thumbnails, and their extended versions" />
	<figcaption elem="caption">Examples of well designed thumbnails, and their extended versions</figcaption>
</figure>

<h2 id="screenshots">Screenshots</h2>

<p>It is important to include screenshots in your app’s app store page to show users what functionality the app has, and entice them to install it. When you include more than one the app store creates a nice fading gallery in the app description page.</p>

<h3 id="size">Size</h3>

<p>Screenshots of your application are required to be 1280px × 720px, in JPG format. These need to be exactly this size, as rescaling and cropping is not applied.</p>

<h2 id="further-resources">Further resources</h2>

<p>You should also consider getting inspiration for your app graphics from other sources. Have a look at other apps, other app stores, and web sites such as the following:</p>

<h3 id="inspiration">Inspiration</h3>

<ul>
  <li><a href="http://thenounproject.com/">thenounproject.com</a></li>
  <li><a href="http://www.dribbble.com/">dribbble.com</a></li>
  <li><a href="http://www.iconfinder.net/">iconfinder.net</a></li>
  <li><a href="http://www.behance.net/">behance.net</a></li>
</ul>

<h3 id="tutorials">Tutorials</h3>

<ul>
  <li><a href="http://psd.tutsplus.com/">psd.tutsplus.com</a></li>
  <li><a href="http://vector.tutsplus.com/">vector.tutsplus.com</a></li>
  <li><a href="http://www.smashingmagazine.com/">smashingmagazine.com</a></li>
</ul>
]]></content></entry><entry><id>https://dev.opera.com/tv/opera-tv-emulator/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/opera-tv-emulator/"/><title>Opera TV Emulator User Guide</title><published>2013-01-23T00:00:00+00:00</published><updated>2013-01-23T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>This guide has been updated to cover the Opera TV Emulator 3.4. For previous versions of the emulator, please refer to the documentation contained inside the emulator’s <code>.zip</code> package.</p>

<h2 id="about-the-opera-tv-emulator">About the Opera TV Emulator</h2>

<p>The Opera TV Emulator allows web developer to test HTML5 and CE-HTML content for TVs and other appliances running the <a href="https://www.opera.com/business/devices/">Opera Devices SDK</a>, as well as HTML-based applications for the <a href="https://www.opera.com/business/tv/store/">Opera TV Store</a>. It comes packaged as an <a href="https://www.virtualbox.org/">Oracle VirtualBox</a> image and can be run on Windows, Mac and Linux.</p>

<ul>
  <li><a href="#install">Installation</a></li>
  <li><a href="#start-page">The Opera TV Emulator start page</a></li>
  <li><a href="#h264-codec">Installing the H.264 codec</a></li>
  <li><a href="#navigation">Navigation</a>
    <ul>
      <li><a href="#keyboard">Keyboard</a></li>
      <li><a href="#web-remote">Web-based remote</a></li>
    </ul>
  </li>
  <li><a href="#local">Accessing local files</a>
    <ul>
      <li><a href="#local-server">Running a local server</a></li>
      <li><a href="#shared-folders">Shared folders</a></li>
    </ul>
  </li>
  <li><a href="#debugging">Debugging with Opera Dragonfly</a></li>
  <li><a href="#settings">Settings</a></li>
  <li><a href="#closing">Closing the emulator</a></li>
  <li><a href="#support">Support</a></li>
</ul>

<h2 id="install">Installation</h2>

<p>The Opera TV Emulator is provided as a preconfigured <a href="https://www.virtualbox.org/">Oracle VirtualBox</a> machine and disk image. This ensures a test environment for web developers that is as close to a real device as possible. To use the emulator:</p>

<ol>
  <li>Install the <a href="http://www.virtualbox.org/wiki/Downloads">Oracle VirtualBox</a> application.</li>
  <li>Download the <a href="https://www.opera.com/business/tv/emulator/">Opera TV Emulator</a> package.</li>
  <li>Extract the package to an appropriate folder on your development machine.</li>
  <li>Open the <code>.vbox</code> file from the package. This will automatically add the virtual machine to the Oracle VirtualBox Manager and start the emulator.</li>
</ol>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/virtualbox-vbox-vdi-files.png" alt="The Opera TV Emulator .vbox and .vdi files from the extracted package" />
	<figcaption elem="caption">The Opera TV Emulator .vbox and .vdi files from the extracted package</figcaption>
</figure>

<p>You can also install the emulator from within the VirtualBox Manager itself: in the <strong>Machine</strong> menu, choose <strong>Add</strong> and open the <code>.vbox</code> file.</p>

<p>Some Linux distributions already ship with an open source version of VirtualBox. The Opera TV Emulator package was specifically developed for the <a href="https://www.virtualbox.org/">Oracle VirtualBox</a> binary version, and may not work reliably with any other version.</p>

<h2 id="start-page">The Opera TV Emulator start page</h2>

<p>The Opera TV Emulator is, in essence, a self-contained generic web browser, equivalent to what you would find on devices running the <a href="https://www.opera.com/business/devices/">Opera Devices SDK</a>. In addition, the emulator contains specific functionality that is only present in <a href="https://www.opera.com/business/tv/store/">Opera TV Store</a> client application.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/tv-emulator-start-page.png" alt="The Opera TV Emulator start page" />
	<figcaption elem="caption">The Opera TV Emulator start page</figcaption>
</figure>

<p>The emulator’s start page — itself just a web page — provides a direct link to the <a href="http://demo.tvstore.opera.com">Opera TV Store demo server</a> at <code>http://demo.tvstore.opera.com</code>. This demo store can be used to test Opera TV Store applications. See our article on <a href="https://dev.opera.com/articles/view/testing-your-app-inside-the-opera-tv-store/">Testing your app inside the Opera TV Store</a> for further information.</p>

<h2 id="h264-codec">Installing the H.264 codec</h2>

<p>For legal reasons, the Opera TV Emulator does not come with any H.264 codec preinstalled. As this codec is widely used for TV applications, you will need to install it the first time you run the emulator.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/codec-install.png" alt="The H.264 codec installation prompt on the Opera TV Emulator start page" />
	<figcaption elem="caption">The H.264 codec installation prompt on the Opera TV Emulator start page</figcaption>
</figure>

<p>To do this, simply choose the Install option on the start page. This will download the necessary codec, install it, and restart Opera.</p>

<p>For information about the specific multimedia formats that can be used, please refer to the article on <a href="https://dev.opera.com/articles/view/html5-audio-video-support-in-opera-tv-store-applications/">HTML5 audio/video support in Opera TV Store applications</a>.</p>

<h2 id="navigation">Navigation</h2>

<p>Although the Opera TV Emulator can be used with a mouse, this will not provide the same user experience as the real TV browser and Opera TV Store client. Instead of using on-screen mouse pointers, users navigate by using directional keys on their remote controls to select different focusable page elements (buttons, links, etc). For a more accurate emulation, there are two alternative control mechanisms that simulate a real device’s remote control interface:</p>

<h3 id="keyboard">Keyboard</h3>

<p>The emulator uses the following keyboard controls:</p>

<ul>
  <li>F1 shows/hides the browser navigation bar</li>
  <li>←↑→↓ cursor keys move the focus</li>
  <li>0-9 number keys</li>
  <li>Enter activates the currently focused element</li>
  <li>Backspace maps to the Return/Back key</li>
  <li>F5 reload the current page</li>
  <li>F10 restart the browser</li>
  <li>ESC close current tab, open a fresh <code>about:blank</code> tab</li>
</ul>

<h3 id="web-remote">Web-based remote</h3>

<p>In addition to basic keyboard controls, the Opera TV Emulator also provides a more comprehensive web-based remote control that also simulates the colored keys (red, green, yellow, blue) and a set of media controls (play/pause, stop, rewind, fast-forward).</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/web-based-remote.png" alt="The Opera TV Emulator’s web-based remote control on localhost:5555" />
	<figcaption elem="caption">The Opera TV Emulator’s web-based remote control on localhost:5555</figcaption>
</figure>

<p>When the emulator is running, the Oracle VirtualBox machine is configured to expose a local server on the host machine on port <code>5555</code>. To access the web-based remote, simply launch your regular browser on the development machine and point it to <code>http://localhost:5555</code>.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/port-forwarding.png" alt="VirtualBox’s settings for Port Forwarding" />
	<figcaption elem="caption">VirtualBox’s settings for Port Forwarding</figcaption>
</figure>

<p>In order to use the web-based remote control, please ensure that no other application is currently running on your development machine using port <code>5555</code>. If this is not possible, you can change the port number used by the VirtualBox machine by going to the Network section in the machine’s settings and modifying the Port Forwarding host port.</p>

<h2 id="local">Accessing local files</h2>

<p>The Opera TV Emulator runs as a completely separate Linux-based system on your development machine. To access files hosted on your development machine for testing, there are two options:</p>

<h3 id="local-server">Running a local server</h3>

<p>If you have a server (such as the <a href="http://projects.apache.org/projects/http_server.html">Apache HTTP Server</a>) running on your development machine, note that it is not possible to access it from within the emulator by just using the standard <code>http://localhost</code> address, as <code>localhost</code> in this context refers to the emulator’s environment itself.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/local-server.png" alt="Running WAMP as a local server on the machine: in a browser on the host environment, the server can simply be accessed from http://localhost. In the Opera TV Emulator, the IP address of the host machine itself has to be used" />
	<figcaption elem="caption">Running WAMP as a local server on the machine: in a browser on the host environment, the server can simply be accessed from <code>http://localhost</code>. In the Opera TV Emulator, the IP address of the host machine itself has to be used</figcaption>
</figure>

<p>Instead, you should use the IP address of your development machine — the emulator will then establish a connection to your server from within the virtual machine.</p>

<h3 id="shared-folders">Shared folders</h3>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/shared-folder.png" alt="VirtualBox’s setup for Shared Folders" />
	<figcaption elem="caption">VirtualBox’s setup for Shared Folders</figcaption>
</figure>

<p>Particularly for static files that do not require any server-side functionality, another option is to add a local folder on your development machine as a shared folder inside the emulator’s Linux environment. This can be done from the Oracle VirtualBox Manager:</p>

<ol>
  <li>Make sure the Opera TV Emulator is not currently running</li>
  <li>Go to the emulator’s Settings… (either by right-clicking on the emulator or from the Machine menu)</li>
  <li>In the Shared Folders section, add your local folder, making sure the Auto-mount option is checked</li>
</ol>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/shared-folder-2.png" alt="The Opera TV Emulator, showing the shared folder being displayed from the relevant file://localhost/mydata location" />
	<figcaption elem="caption">The Opera TV Emulator, showing the shared folder being displayed from the relevant file://localhost/mydata location</figcaption>
</figure>

<p>Your shared folder will be available under <code>file://localhost/mydata/sf_[name of your folder]</code> the next time you start the emulator.</p>

<h2 id="debugging">Debugging with Opera Dragonfly</h2>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/remote-debug-setup.png" alt="A standard debugging setup: Opera TV Emulator, a browser showing the web-based remote control, and an undocked Opera Dragonfly window set to remotely debug the emulator" />
	<figcaption elem="caption">A standard debugging setup: Opera TV Emulator, a browser showing the web-based remote control, and an undocked Opera Dragonfly window set to remotely debug the emulator</figcaption>
</figure>

<p><a href="https://www.opera.com/dragonfly/">Opera Dragonfly</a> is a comprehensive set of web developer tools integrated with the Opera desktop browser. Using the remote debugging functionality of Opera Dragonfly, it is possible to debug web pages and applications running in the Opera TV Emulator:</p>

<ol>
  <li>Set Opera Dragonfly to listen for incoming remote debugging connections.</li>
  <li>Press the Connect to Dragonfly button on the emulator’s web-based remote control.</li>
</ol>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/tv-emulator-remote-dragonfly.png" alt="The web remote control’s “Connect to Dragonfly” button" />
	<figcaption elem="caption">The web remote control’s “Connect to Dragonfly” button</figcaption>
</figure>

<p>Note that using the Connect to Dragonfly button is the only way to establish a remote debugging connection. Entering <code>opera:debug</code> in the Opera TV Emulator’s address bar will not work.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/debugging-context.png" alt="Opera Dragonfly’s Debugging Context button" />
	<figcaption elem="caption">Opera Dragonfly’s Debugging Context button</figcaption>
</figure>

<p>When the connection is established, make sure that the debugging context is set to the web page / application that you want to debug, rather than the Opera TV Emulator’s status page or navigation bar.</p>

<p>For more information, please refer to the <a href="https://www.opera.com/dragonfly/documentation/">Opera Dragonfly documentation</a>.</p>

<h2 id="settings">Settings</h2>

<p>The Opera TV Emulator offers a few customisation options that can be configured via the Settings button on the web remote control.</p>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/web-remote-settings.png" alt="The web-based remote control, showing the settings popup dialog" />
	<figcaption elem="caption">The web-based remote control, showing the settings popup dialog</figcaption>
</figure>

<h3 id="general">General</h3>

<ul>
  <li><strong>TV Emulator version:</strong> Some emulator packages can contain a series of different Opera Devices SDK versions. You can switch between them with this dropdown.</li>
  <li><strong>Enable TV Store profile:</strong> the Opera TV Store features a few customisations (such as custom <code>VK_</code> key constants in the global JavaScript namespace) not present in the standard Opera Devices SDK. If you are developing/testing Opera TV Store applications, this option should be checked.</li>
  <li><strong>Default URL:</strong> The URL that will be loaded when the emulator is launched.</li>
  <li><strong>Screen resolution:</strong> The screen resolution of the Opera TV Emulator.</li>
</ul>

<h3 id="debug">Debug</h3>

<ul>
  <li><strong>Opera Dragonfly listening IP/port:</strong> For the purposes of Opera Dragonfly debugging, it is possible to set a different IP and port from the default. Generally, you should not need to change these.</li>
</ul>

<h3 id="memory">Memory</h3>

<ul>
  <li><strong>Alloc limit/Heap limit:</strong> These are advanced options that let you control the memory available for the TV Emulator. These options may be useful when you want to emulate a device with limited memory.</li>
</ul>

<h3 id="browsing-data">Browsing Data</h3>

<ul>
  <li><strong>Clear cache / Clear history:</strong> these buttons clear the cache or history immediately, without having to save or apply the settings.</li>
</ul>

<h3 id="proxy">Proxy</h3>

<ul>
  <li><strong>HTTP/HTTPS proxy:</strong> Define the address of any proxies required to make HTTP/HTTPS connections from your development machine.</li>
</ul>

<h3 id="other">Other</h3>

<ul>
  <li><strong>Allow file and cross-domain XMLHttpRequests:</strong> For security reasons, most browsers block XMLHttpRequests to external domains and local files by default. However, for testing purposes (for instance, if your application is not yet deployed to its production server) you can set the emulator to allow these requests.</li>
  <li><strong>Performance adjustment:</strong> You can throttle the performance of the emulator to more closely simulate low-power devices.</li>
  <li><strong>HTTP Accept Language:</strong> If your application does content negotiation based on language headers, this option lets you define the default HTTP Accept Language header that is sent with each request.</li>
</ul>

<p>To immediately apply changes, choose Apply — this will store the settings and restart the emulator. Using Save will store the new settings, but these will only take effect the next time the emulator is restarted.</p>

<h2 id="closing">Closing the emulator</h2>

<figure block="figure">
	<img elem="media" src="/tv/opera-tv-emulator/shutdown.png" alt="VirtualBox’s “Close Virtual Machine” dialog, with the “Send the shutdown signal” option checked" />
	<figcaption elem="caption">VirtualBox’s “Close Virtual Machine” dialog, with the “Send the shutdown signal” option checked</figcaption>
</figure>

<p>When closing the emulator, please choose the Send the shutdown signal option. This will ensure that the Linux environment in the emulator is properly powered down.</p>

<h2 id="support">Support</h2>

<p>Opera Software does not provide any official support for the Opera TV Emulator. However, a number of communication channels are available:</p>

<ul>
  <li>Join our developer community forums on <a href="http://forums.opera.com/categories/en-opera-tv-store">dev.opera.com/forums</a>, where you’ll find a dedicated section on TV content development.</li>
  <li>Get notified of updates to the Opera TV Emulator on the <a href="https://list.opera.com/mailman/listinfo/tv-emulator-external">tv-emulator-external@list.opera.com mailing list</a>.</li>
</ul>

]]></content></entry><entry><id>https://dev.opera.com/tv/opera-tv-store-app-templates/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/opera-tv-store-app-templates/"/><title>Opera TV Store App Templates</title><published>2013-01-07T00:00:00+00:00</published><updated>2013-01-07T00:00:00+00:00</updated><author><name>Daniel Davis</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>The templates presented in this article are available for free to developers developing for the Opera TV Store, but they are not maintained or supported by Opera any more. Instead, we strongly suggest that content creators use the Opera TV Snap tool, which generates template-based applications automatically. Opera Snap also contains built-in support for monetization and is constantly developed and maintained by Opera. See <a href="http://opera.com/tvsnap">opera.com/tvsnap</a> for more details.</p>

<h2 id="introduction">Introduction</h2>

<p>Since the launch of the Opera TV Store, we’ve seen a variety of apps published by creators and enjoyed by users. The fact that our TV apps are built using web standards means that web developers can use their existing skills to create content for the TV platform. Developing for TV can still feel unfamiliar, however, so to make it easier we’ve created a couple of templates for common app types that content creators can freely use.</p>

<p>On any platform, news and entertainment are among the most popular types of content so the templates we’re providing are for video player and RSS reader apps. Both of them are intended to be easy to customise so you can quickly publish your own branded apps without having to worry about development time and costs.</p>

<h2 id="video-player-template">Video player template</h2>

<figure block="figure" id="figure-1">
	<img elem="media" src="/tv/opera-tv-store-app-templates/video-app-template.jpg" alt="Screenshot showing the video player TV app in use" />
	<figcaption elem="caption">Figure 1: The video player TV template in use</figcaption>
</figure>

<h3 id="overview">Overview</h3>

<p>The video app template is more than just a simple player — it allows you to separate videos into channels based on a theme or subject. There is also a built-in bookmarking feature where users can move videos they particularly like into a list of their favorites. When watching videos, users can also choose to play videos continuously and even shuffle the order in which they are played. To customize the template, there are three main areas that can be easily edited — data (which can be via the XML file or your existing API), images and colors.</p>

<h3 id="customization">Customization</h3>

<p>The first thing you will want to do is add your chosen videos and channels. This is done in the <code>video.xml</code> file, which looks like this:</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;rss&gt;
	&lt;channel&gt;
	&lt;item&gt;
		&lt;title&gt;Opera Labs: Mobile Extensions&lt;/title&gt;
		&lt;description&gt;We’re excited to share with you a Labs release of our mobile browser with support for extensions.&lt;/description&gt;
		&lt;category&gt;Opera Labs&lt;/category&gt;
		&lt;duration&gt;00:01:24&lt;/duration&gt;
		&lt;content url="http://apps.tvstore.opera.com/videos/Opera_Labs_Mobile_Extensions.mp4" fileSize="24434480" type="video/mp4" /&gt;
		&lt;thumbnail url="http://apps.tvstore.opera.com/videos/Opera_Labs_Mobile_Extensions.jpg" width="250" height="140" /&gt;
	&lt;/item&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</code></pre>

<p>This file is read by the function <code>getData()</code>, in the file <code>videotemplate.js</code>, so if you prefer to use your own API or RSS feed for the source of the videos you just need to change the file address in that function. You would also need to change the parsing rules in the <code>prepareData()</code> function in the same file to suit.</p>

<p>For visual customization, all images are contained in the <code>images</code> directory and named with logical filenames such as <code>logo.png</code>. This allows you to easily replace them with your own logo and color scheme. In addition the styles for the app’s design are in the <code>style.css</code> file in the <code>css</code> directory. Font and color definitions have been placed at the top of this file to make it easier to customize.</p>

<h2 id="rss-reader-template">RSS reader template</h2>

<figure block="figure" id="figure-2">
	<img elem="media" src="/tv/opera-tv-store-app-templates/rss-app-template.jpg" alt="Screenshot showing the RSS reader TV app in use" />
	<figcaption elem="caption">Figure 2: The RSS reader TV template in use</figcaption>
</figure>

<h3 id="overview-1">Overview</h3>

<p>The RSS reader app template allows you to conveniently provide news or other regularly updated content in a single app. Like the video app template, it is easily controlled with the direction keys of a TV remote control and includes a slideshow feature that can automatically display individual news items or articles one by one. Customization can consist of simple color changes, or more advanced alterations such as editing the dynamically-generated HTML.</p>

<h3 id="customization-1">Customization</h3>

<p>The most important step is to specify the feeds you’d like to use. This is done by editing the <code>DEF_FEEDS</code> array in the <code>js/config.js</code> file. You can add as many as you like — including feeds that are hosted on an external domain — however to workaround browser security measures a proxy feed server needs to be used. There are instructions for setting this up in the tutorial, linked to with the downloadable package below. A list of feeds may look something like this:</p>

<pre><code>var DEF_FEEDS = [{
	url: 'data/data.xml';
},
{
	url: 'http://my.opera.com/chooseopera/xml/rss/blog/',
	proxy: true
}];
</code></pre>

<p>Also in the <code>js/config.js</code> file are options to change the title of your app and the address of the proxy server, if necessary:</p>

<pre><code>/**
 * Application main title
 */
var APP_TITLE = 'All feeds';

/**
 * Proxy URL
 */
var PROXY_URL = '/xhrproxy/?_proxy_url=';
</code></pre>

<p>Visual styles for the app can be changed by editing the <code>css/common.css</code> file, and if you’d like to edit the HTML that each feed item uses, that is contained in the <code>js/Item.js</code> file in the <code>TMPL</code> and <code>TMPL_CONTENT</code> arrays.</p>

<h2 id="downloading-the-templates">Downloading the templates!</h2>

<p>The app templates are available for download here (ZIP files):</p>

<ul>
  <li><a href="http://apps.tvstore.opera.com/templates/videotemplate.zip">Video player app template</a></li>
  <li><a href="http://apps.tvstore.opera.com/templates/rssreader.zip">RSS reader app template</a></li>
</ul>

<p>The ZIPs both include more detailed tutorials on how to add your own data and customize the templates to suit your taste or brand guidelines. They have been designed so that you don’t need to edit functionality or layout to create an easy-to-use, good-looking app, however because both templates are provided under a <a href="http://creativecommons.org/licenses/by/3.0/">free, open source license</a>, there’s nothing to stop you customizing the code at a deeper level if you wish. We look forward to seeing the apps you create from these templates in the Opera TV Store!</p>

<p>The templates are licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported</a> license. Please include the following notice in any distribution: Copyright © 2012 Opera Software ASA. Used by Permission.</p>

<h2 id="updating-the-templates">Updating the templates</h2>

<p>We are constantly looking to improve our app templates, by fixing bugs and adding new features. Because of this, they are designed to be easily upgradeable to updated versions containing new styling and script logic — as long as application developers do not modify files other than the <code>custom.css</code> and <code>config.js</code> files. Whenever a new version of an app template is available (check the links above) just download and unpack it, then copy your app’s existing custom <code>config.js</code> and <code>custom.css</code> files into the updated package, overwriting the default ones there.</p>

<p>If your app has more significant customizations, bear in mind that upgrading to a new version might be much more difficult. Also please note that these instructions mainly relate to the video app template (and possible others that we may release in the future) — the RSS app template is unlikely to require updates, and such an update would be much more complicated.</p>
]]></content></entry><entry><id>https://dev.opera.com/tv/functional-keys-in-opera-tv-browsers/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/functional-keys-in-opera-tv-browsers/"/><title>Functional Key Handling in Opera Device SDK Based TV Browsers</title><published>2012-09-05T00:00:00+00:00</published><updated>2012-09-05T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<div class="note">
This article offers advice for generic browsers based on the Opera Device SDK. For specific information about the Opera TV Store – which introduces further functionality, as well as additional requirements to authors – please refer to this separate article: [Functional key handling in Opera TV Store applications](/tv/functional-key-handling-in-opera-tv-store-applications/).
</div>

<ul>
  <li><a href="#spatial-functional">Spatial navigation and functional buttons</a></li>
  <li><a href="#handling-keydown">Handling <code>keydown</code> events</a></li>
  <li><a href="#repeat">Repeating key events</a></li>
  <li><a href="#prevent-default">Preventing default spatial navigation</a></li>
</ul>

<h2 id="spatial-functional">Spatial navigation and functional buttons</h2>

<p>Browsers based on the Opera Device SDK are generally designed to use the standard four-way directional keys on a remote control for spatial navigation. Opera's spatial navigation works in a similar way to traditional <kbd>TAB</kbd> based keyboard access in most browsers, allowing users to move between focusable elements (links, form controls, image map areas). In addition, spatial navigation also employs heuristics that make arbitrary elements with attached <code>click</code> and <code>mouseover</code> JavaScript events focusable as well. Lastly, as the name implies, spatial navigation in Opera allows the user to move between those elements based on their spatial relationship on screen, rather than in source order (as with <kbd>TAB</kbd> navigation).</p>
<p>In most cases, websites can simply rely on Opera's spatial navigation to handle site navigation. There are simple mechanisms to further [tweak spatial navigation for TV browsing](/tv/tweaking-spatial-navigation-for-tv-browsing/) using CSS3.</p>
<p>However, for maximum control, web authors may also choose to handle the navigation of their site (or specific aspects of their site, such as individual image carousel elements for instance) themselves by intercepting key presses from the remote control. This makes it possible to not only react to the basic directional buttons (<kbd>UP</kbd>, <kbd>RIGHT</kbd>, <kbd>DOWN</kbd>, <kbd>LEFT</kbd>), but to further bind functionality to the various shortcut and functional keys (such as <kbd>BACK</kbd>, <kbd>INFO</kbd>, <kbd>OPTIONS</kbd> or the <kbd>RED</kbd> button).</p>

<h2 id="handling-keydown">Handling <code>keydown</code> events</h2>

<div class="note">
<p>In previous versions of the Opera Device SDK, authors were encouraged to handle <code>keypress</code> events. However, starting with the Opera Device SDK 3.4, Opera is aligned with the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model.</p>
<p>The most notable change here is that the <code>keypress</code> event is now only fired for <em>keys which produce a character value</em>. From the list of functional buttons above, this means that only the number keys <kbd>0</kbd>-<kbd>9</kbd> and the <kbd>ENTER</kbd> (Confirm/Select/Ok) buttons can be detected via <code>keypress</code>.</p>
<p>Additionally, this specification deprecates the <code>keypress</code> event, meaning that future versions of the specification – and, as a result, future versions of conformant browsers – should not fire this event anymore. For compatibility with existing content, it is unlikely that browsers will drop legacy support for this event, but we would still recommend using <code>keydown</code> instead of <code>keypress</code> going forward.</p>
</div>

<p>In the past, websites often handled key events by simply adding an <code>onkeydown</code> attribute to an element in HTML and running some inline JavaScript.</p>

<pre><code>&lt;ELEMENT onkeydown="handler()"&gt;</code></pre>

<p>However, we would recommend the much cleaner and flexible method of adding handler purely in JavaScript – either by attaching the handler function directly to the <code>onkeydown</code> property of the element or using <code>addEventListener</code>. This automatically passes on the event object associated with the call, avoiding any ugly <code>window.event</code> hacks:</p>

<pre><code>object.onkeydown = handler;
object.addEventListener("keydown", handler, useCapture);</code></pre>

<p>Before the standardisation effort of <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a>, key handler functions would simply compare the <code>event.keyCode</code> value to hardcoded values corresponding to specific keys. For instance, to detect if the <kbd>UP</kbd> arrow was pressed, the handler script would have been something like:</p>

<pre><code>function handler(event){
	…
	if (event.keyCode == 38){
		// UP (generally keyCode 38) was pressed … do something useful
	}
	…
}</code></pre>

<p>The potential problem with this approach has always been that the specific numerical values of <code>event.keyCode</code> were never standardised – the same functional or navigation key, on different devices, may generate different key codes. For this reason, DOM Level 3 introduces a new, more abstracted method of identifying keys in the form of the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list">DOM Level 3 Events Key values list</a> and the new <code>event.key</code> (as well as <code>event.char</code>, which is however only applicable to keys which produce a character value).</p>

<p>Starting with the Opera Device SDK 3.4, the recommended method of identifying navigation and functional keys is therefore:</p>

<pre><code>function handler(event){
	…
	if (event.key == 'Up'){
		// 'Up' was pressed … do something useful
	}
	…
}</code></pre>

<p class="note">Although the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model normatively uses <code>event.key</code> and <code>event.char</code>, it still retains information on <a href="http://www.w3.org/TR/DOM-Level-3-Events/#legacy-key-attributes">legacy key attributes</a> such as <code>event.keyCode</code>. For compatibility with existing content, it is likely that <code>event.keyCode</code> will continue to be available for the time being.</p>

<p>To ensure backwards compatibility with previous Opera Device SDK versions, it may be necessary to combine the old and new way of comparing key events into a single expression:</p>

<pre><code>function handler(event){
	…
	if ((event.key == 'Up') || (event.keyCode == 38)) {
		// 'Up'/key 38 was pressed … do something useful
	}
	…
}</code></pre>

<p>Depending on the application, it is advisable not to include a large number of separate event handlers to various elements in the page, but to instead take advantage of event capture / bubbling and use an event delegation mechanism, hooking the <code>keydown</code> handler on a top-level element (for instance, the <code>body</code>) or object (<code>window</code> or similar):</p>

<pre><code>window.addEventListener("keydown", handler, useCapture);</code></pre>

<p>In your <code>handler</code> function, you may need to determine the element where the event originated. A reference to this can be easily obtained from the <code>event.target</code>:</p>

<pre><code>function handler(event){
	…
	var target = event.target;
	…
}</code></pre>

<h2 id="repeat">Repeating key events</h2>

<p>What happens when a user keeps a functional button on their remote control pressed is dependant on their specific device. Some devices will only send a single <code>keydown</code> event until the button is released. Others may send a series of <code>keydown</code> (and <code>keypress</code>, if it's a key that produces a <em>character value</em>) and <code>keyup</code> events (as if the button was manually being pressed and released multiple times). Lastly, platforms that do support proper key repeats will send a continuous stream of <code>keydown</code> (and <code>keypress</code>, if it's a key that produces a <em>character value</em>) events, and only fire <code>keyup</code> once the user releases the button.</p>

<p>In general, since it cannot be guaranteed that a device has full key repeat support, we'd recommend not making an application reliant on this behaviour.</p>

<p>If your applications does need to handle repeating / long-press button events, the switch to the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model in the Opera Device SDK 3.4 may require some additional work in order to ensure backwards- and forwards-compatibility.</p>

<p>Previously, repeating keys (on supporting platforms) used to fire:</p>
<ul>
<li><code>keydown</code> &gt; [multiple <code>keypress</code>] &gt; <code>keyup</code></li>
</ul>

<p>Starting with the Opera Device SDK 3.4, in accordance with the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model, the browser will instead fire:</p>

<ul>
<li>[multiple <code>keydown</code> and <code>keypress</code>] &gt; <code>keyup</code> (for keys that produce a <em>character value</em>)</li>
<li>[multiple <code>keydown</code>] &gt; <code>keyup</code> (for all other keys)</li>
</ul>

<p>If for previous versions of the Opera Device SDK your code listened to repeating <code>keypress</code> events, the best way to remain compatible is to register your handlers for <strong>both</strong> <code>keydown</code> and <code>keypress</code>. To avoid having functionality being triggered twice (for the first button press in the old SDK, and for repeating <em>character value</em> keys in the new SDK), you can take advantage of the <code>event.repeat</code> property introduced in <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> to filter out unwanted duplicate events:</p>

<pre><code>
// example using event delegation
window.addEventListener("keydown", handler, useCapture);
window.addEventListener("keypress", handler, useCapture);

function handler(event){
	if ((event.type=='keydown' &amp;&amp; !('repeat' in event)) ||
		(event.type=='keypress' &amp;&amp; ('repeat' in event))) return;
	…
}
</code></pre>

<p>Alternatively, if you're binding event handlers via JavaScript already, you can use the new <code>window.KeyboardEvent</code> interface as an indicator for DOM 3 support, and only bind your event handler to either <code>keydown</code> or <code>keypress</code>.</p>

<pre><code>
// example using event delegation
if (window.KeyboardEvent){
	window.addEventListener('keydown', handler, useCapture);
} else {
	window.addEventListener('keypress', handler, useCapture);
}

function handler(event){
	// no need to de-dupe events
	…
}
</code></pre>

<h2 id="prevent-default">Preventing default spatial navigation</h2>

<p>When handling key events directly, you will probably want to stop the Opera Device SDK from carrying out its normal spatial navigation and element activation behaviours. This can simply be suppressed in the <code>handler</code> function:</p>

<pre><code>function handler(event){
	…
	event.preventDefault();
	…
}</code></pre>
]]></content></entry><entry><id>https://dev.opera.com/tv/testing-your-app-inside-opera-tv-store/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/testing-your-app-inside-opera-tv-store/"/><title>Testing Your App Inside the Opera TV Store</title><published>2012-08-20T00:00:00+00:00</published><updated>2012-08-20T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that this article refers to an older version of the Opera TV Store that (Opera TV Store 1.x), and may not be valid for Opera TV 2.0 or newer versions.

<h2>Introduction</h2>

<p>Before submitting an application to the Opera TV Store, developers need to ensure that it works as expected, to avoid a lengthy review process and potential delays.</p>

<p>Although the Opera TV Store uses the same core engine that is also found in the generic Opera Device SDK – used by many TV and set-top-box manufacturers as the basis for their own TV browser implementations – and in the Opera browser on desktop and mobile devices, there are still notable differences. The Opera TV Store provides additional functionality (such as its functional key handling) and specific restrictions. For this reason, it is advisable to test your applications inside the actual Opera TV Store environment itself.</p>

<p class="note">Note that you can access a <a href="http://forums.opera.com/discussion/1832897/opera-tv-store-retail-device-list">list of TVs that the Opera TV store is already available on</a>, to find a suitable device for testing TV store apps.</p>

<p>Normally, the Opera TV Store does not provide end users with any browser-like interface elements – it only shows the user's chosen applications and the catalogue of already approved and published applications. However, as a developer you can set up your particular TV, set-top-box or <a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a> to be "paired" with your <a href="https://publish.tvstore.opera.com">Opera TV Store Submission portal</a> account. This gives you access to a simple URL entry application, making it possible to view and test any arbitrary web address, and the ability to launch any apps already saved in your account, even before they've been submitted for final review.</p>

<p>To pair a device, you will need a device ID FOR DEVELOPERS. This can be found by opening the Opera TV Store on the device and viewing the About information (found under the MENU button at the top of the interface) under the My Apps tab. If you are using the <a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a>, simply navigate to Opera's demonstration store at <code>https://demo.tvstore.opera.com</code>.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/opera-tv-store-emulator-my-apps-menu.jpg" alt="The Opera TV Store's 'My Apps' screen, showing the dropdown menu containing the 'About' option" />
</p>

<p>The About screen details the version number of the Opera TV Store, as well as a 64-character Device ID.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/tv-store-device-id-2.jpg" alt="The Opera TV Store's 'About' screen, showing the version number and the Device ID, plus an ID FOr DEVELOPERS button to generate a pairing ID" />
</p>


<p>Press the ID FOR DEVELOPERS button at the bottom right to generate a unique ID for pairing.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/tv-store-device-id-3.jpg" alt="The Opera TV Store's 'About' screen, showing the version number and the Device ID, plus a generated pairing ID" />
</p>

<p>Using your regular desktop browser, log in to your <a href="https://publish.tvstore.opera.com">Opera TV Store Submission portal</a> account and go to your <a href="https://publish.tvstore.opera.com/paired_devices/">Paired devices</a> page. Enter a friendly <cite>Custom name</cite> and the Pairing ID (labelled <cite>Device ID on the form</cite>), and your device will now be paired with your account.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/tv-store-submission-portal.jpg" alt="The 'Paired devices' page in the Opera TV Store Submission portal" />
</p>

<p>After that you should be prompted on your TV to accept pairing.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/accept-pair-request-dialog.jpg" alt="A pairing request, appearing on the Opera TV browser" />
</p>

<p>Once you accept the pairing request, your account and device will be associated. You will see your device listed on the <a href="https://publish.tvstore.opera.com/paired_devices/">Paired devices</a> page, with its full 64-character DEVICE ID.</p>

<p>Please note that you should not leave the About page while pairing your device. Also note that the ID FOR DEVELOPERS will be valid only for 15 minutes. If you fail to enter the ID in the <a href="https://publish.tvstore.opera.com/paired_devices/">Paired devices</a> page in that time, you will have to generate a new one by pressing the ID FOR DEVELOPERS button again.</p>

<p>After a device has been paired, you will see a new Develop category under the Opera TV Store tab. This category contains all your saved, submitted and reviewed applications. This allows you to test exactly how an application that is still in development will look and behave in the store.</p>

<div class="note">
<p>If you are using the Opera TV Emulator, you can simply use your mouse to select the <cite>Device ID</cite> shown on screen, copy it to your clipboard, and paste it into the relevant form field in your desktop browsed.</p>

<p>If you're on a Mac, remember that the Opera TV Emulator is running Linux at its core, so you'll need to use <kbd>CTRL</kbd>+<kbd>C</kbd>, rather than <kbd>⌘/CMD</kbd>+<kbd>C</kbd>, to copy the text to the clipboard.</p>
</div>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/opera-tv-store-develop-category.jpg" alt="The 'Develop' category in the Opera TV Store, showing the 'URL Loader' app as well as 'My test app', which the developer has saved (but not submitted) in their Opera TV Store Submission portal page" width="665" height="392" />
</p>

<p>From here, you can launch the <cite>URL Loader</cite> – a simple utility to point the Opera TV Store client to any arbitrary web address where your in-development app is located. Additionally, if you already saved or submitted  applications in the <cite>My Apps</cite> section of the <a href="https://publish.tvstore.opera.com">Opera TV Store Submission portal</a>, these will also be shown in this category, ready to be tested.</p>

<p>
<img src="/tv/testing-your-app-inside-opera-tv-store/opera-tv-store-test-app-info.jpg" alt="The information screen for 'My test app', showing the screenshot, description, support information – just as it would be shown if my app had already been submitted and approved" width="665" height="374" />
</p>

<p>The advantage of saving an application and starting it from the <cite>Develop</cite> category, rather than simply loading its address via the <cite>URL Loader</cite>, is that it allows you to check how the icon, screenshot and description will look within the context of the Opera TV Store. Additionally, when a saved app is launched, a valid <code>UID</code> will be passed along as a <code>GET</code> parameter, just as with fully published applications.</p>

<p class="note">The <code>UID</code> is both device and application specific (it's an encrypted combination of the <cite>Device ID</cite> and the identifier that's been assigned to the app in the Opera TV Store's systems), meaning that it can be used to identify return visits to an application from the same device, but it can't be used to track users across different devices, or across different applications on the same device.</p>
</p>
]]></content></entry><entry><id>https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/"/><title>HTML5 Audio and Video Support in Opera TV Store Applications</title><published>2012-02-10T00:00:00+00:00</published><updated>2012-02-10T00:00:00+00:00</updated><author><name>Jakub Gladykowski, Patrick H. Lauke, Tomasz Stawarz</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>Update history:</p>

<ul>
  <li>Article updated on 30 March 2012 to suggest explicit <code>&lt;source&gt;</code> workaround.</li>
  <li>Article updated on 18 April 2012 to include MPEG-1/MPEG-2 Audio Layer 3 audio codec for video and clarification on limitation of single <code>&lt;audio&gt;</code> or <code>&lt;video&gt;</code> element playback on some of the current devices.</li>
  <li>Article updated on 13 August 2014 to include information about supported Adaptive Bitrate Streaming and DRM formats.</li>
  <li>Article updated on 7 October 2014 to cover subtitles support</li>
  <li>Article update on 5 November 2014 with information about Shoutcast and fixed example player codes</li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>The Opera TV Store browser comes with built-in support for the HTML5 <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code> elements, allowing developers to include multimedia content in their applications without any need for plugin-based solutions.</p>

<p>At its simplest, this means that multimedia elements can be included in a TV Store application by simply using markup such as:</p>

<pre><code>&lt;video src="/path/to/video.mp4"&gt;&lt;/video&gt;
&lt;audio src="/path/to/audio.mp3"&gt;&lt;/audio&gt;
</code></pre>

<p>For more on the basics of HTML5 <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code>, read <a href="http://dev.opera.com/articles/view/introduction-html5-video/">Introduction to HTML5 video</a>.</p>

<p>Due to limitations in how multimedia content is handled on certain current devices, there are situations in which the type of audio/video content being used is not automatically inferred by file extensions or MIME types. For this reason, we suggest to use the more explicit, though slightly more wordy, variant:</p>

<pre><code>&lt;video&gt;
	&lt;source src="/path/to/video.mp4" type="video/mp4"&gt;
&lt;/video&gt;
&lt;audio&gt;
	&lt;source src="/path/to/audio.mp3" type="audio/mp3"&gt;
&lt;/audio&gt;
</code></pre>

<p>In contrast to the desktop version of Opera — where multimedia decoding and playback is handled directly by the browser) — the specifics of which codecs are supported on devices can vary considerably, as this depends on the underlying platform and integration work carried out by device manufacturers, as well as the specific version of the Opera TV Store that may be running on the device.</p>

<p>Additionally, due to the way some of the current devices have integrated audio and video support on their platform via an external media playback framework, it may not be possible to guarantee simultaneous playback of more than a single <code>&lt;audio&gt;</code> or <code>&lt;video&gt;</code> element.</p>

<p>Whenever you switch to the next audio/video source with JavaScript, make sure to destroy the current audio/video element, and create a new one. Without this, some devices may have problems playing the new audio/video source, especially if the format is different than the one previously played.</p>

<p>Shoutcast format is not officially supported. It may work with subset of devices with the Opera TV Store depending on platform capabilities. We recommend to not use it in order to increase the reach.</p>

<p>We recommend using bitrates from 2Mbps (lowest to get minimum video quality) to 4Mbps (highest limited by the network bandwidth users usually have) in your videos.</p>

<h2 id="audio-and-video-codecs">Audio and video codecs</h2>

<p>At the time of publication, the following container formats and codecs are supported for Opera TV Store applications:</p>

<figure block="figure">
<table>
<tr>
	<th width="50%">Audio or video codec</th>
	<th>Supported in the Opera TV Store</th>
	<th>Supported in the Opera TV Emulator</th>
</tr>
<tr>
	<th>H.264</th>
	<td>Yes</td>
	<td>Yes</td>
</tr>
<tr>
	<th>MP3</th>
	<td>Yes</td>
	<td>Yes</td>
</tr>
<tr>
	<th>AAC-LC</th>
	<td>Yes</td>
	<td>Yes</td>
</tr>
<tr>
	<th>HE-AAC</th>
	<td>Yes</td>
	<td>Yes</td>
</tr>
</table>
</figure>

<h3 id="using-mpeg-4-avc-h264-video">Using MPEG-4 AVC (H.264) video</h3>
<ul>
  <li>Main and High Profiles,</li>
  <li>Up to Level 4 (inclusive),</li>
  <li>With audio codecs: MP3, AAC-LC or HE-AAC,</li>
  <li>Container format is MP4,</li>
  <li>Source type set to <code>video/mp4</code>,</li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;video&gt;
	&lt;source src="/path/to/video.mp4" type="video/mp4"&gt;
&lt;/video&gt;
</code></pre>

<h3 id="using-mpeg-1mpeg-2-audio-layer-3-mp3-audio">Using MPEG-1/MPEG-2 Audio Layer 3 (MP3) audio</h3>
<ul>
  <li>Mono or Stereo options,</li>
  <li>32kHz/44.1kHz/48kHz frequencies,</li>
  <li>16kbps-10Mbps bitrate (2Mbps-4Mbps is recommended to be used),</li>
  <li>Container format is MP3,</li>
  <li>Source type set to <code>audio/mp3</code> or <code>audio/mpeg</code>,</li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;audio&gt;
	&lt;source src="/path/to/audio.mp3" type="audio/mp3"&gt;
&lt;/audio&gt;
</code></pre>

<h3 id="using-aac-lc-and-he-aac-audio">Using AAC-LC and HE-AAC audio</h3>
<ul>
  <li>Mono or Stereo options,</li>
  <li>32kHz/44.1kHz/48kHz frequencies,</li>
  <li>16kbps-10Mbps bitrate (2Mbps-4Mbps is recommended to be used),</li>
  <li>Container format is MP4,</li>
  <li>Source type set to <code>audio/mp4</code>,</li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;audio&gt;
	&lt;source src="/path/to/audio.mp4" type="audio/mp4"&gt;
&lt;/audio&gt;
</code></pre>

<h2 id="adaptive-bitrate-streaming-and-drm">Adaptive Bitrate Streaming and DRM</h2>

<p>When dealing with premium multimedia content, you’ll encounter technologies like adaptive bitrate streaming, which allows for smooth video playback by dynamically adjusting the bitrate, and digital rights management (DRM).</p>

<p>Below you can find the list of supported adaptive bitrate streaming formats and their combinations with DRM, together with simple examples how to correctly use such videos into your application. Please note that the actual support may slightly differ, depending on specific video stream parameters, firmware versions and device generations. It is also important to note that not all devices the Opera TV Store runs on support adaptive bitrate streaming and DRM.</p>

<p>Adaptive bitrate streaming formats supported in the Opera TV Store are as follows:</p>

<ul>
  <li>HTTP Live Streaming (HLS) — VOD and Live profiles</li>
  <li>Microsoft Smooth Streaming (MSS) — VOD and Live profiles</li>
  <li>MPEG-DASH — Live profile only (recommended)</li>
</ul>

<figure block="figure">
<table>
<tr>
	<th width="50%">Adaptive Bitrate Format</th>
	<th>Supported in the Opera TV Store</th>
	<th>Supported in the Opera TV Emulator</th>
</tr>
<tr>
	<th>HTTP Live Streaming (HLS) v3. Live and VOD profiles</th>
	<td>Yes</td>
	<td>No</td>
</tr>
<tr>
	<th>Microsoft Smooth Streaming (MSS) v1. Live and VOD profiles</th>
	<td>Yes</td>
	<td>No</td>
</tr>
<tr>
	<th>MPEG-DASH. Live profile only</th>
	<td>Yes</td>
	<td>No</td>
</tr>
</table>
</figure>

<figure block="figure">
<table>
<tr>
	<th width="50%">DRM Format</th>
	<th>Supported in the Opera TV Store</th>
	<th>Supported in the Opera TV Emulator</th>
</tr>
<tr>
	<th>Microsoft PlayReady 1.2</th>
	<td>Yes</td>
	<td>No</td>
</tr>
</table>
</figure>

<p>The DRM format supported in the Opera TV Store is Microsoft PlayReady 1.2 in combination with MSS (recommended) or MPEG-DASH.</p>

<h3 id="using-http-live-streaming-hls">Using HTTP Live Streaming (HLS)</h3>

<ul>
  <li>VOD and Live profiles are supported,</li>
  <li>HLS version 3 specification up to and including Panthos 06,</li>
  <li>With or without AES 128 bit encryption,</li>
  <li>MPEG2TS as a container,</li>
  <li>Source pointing to a m3u8 playlist,</li>
  <li>Source type set to <code>application/vnd.apple.mpegurl</code>,</li>
  <li>At some devices HLS playback may be terminated if HLS stream is broken,</li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;video&gt;
	&lt;source type="application/vnd.apple.mpegurl"
		src="http://example.com/videofile.m3u8"&gt;
&lt;/video&gt;
</code></pre>

<h3 id="using-microsoft-smooth-streaming-mss">Using Microsoft Smooth Streaming (MSS)</h3>

<p>Technical details are as follows:</p>

<ul>
  <li>VOD and Live profiles are supported</li>
  <li>Version 1.0 of the specification</li>
  <li>container format is MP4</li>
  <li>Source pointing to the MSS manifest file</li>
  <li>Source type set to <code>application/vnd.ms-sstr+xml</code></li>
  <li>PlayReady content is supported here:
    <ul>
      <li>PlayReady content can be embedded with <code>ProtectionHeader</code> inside the MSS manifest</li>
      <li>Some devices may not support Security Levels (content with any security level required is played)</li>
      <li>DRM errors are signaled by the <code>MediaError</code> element of the video tag</li>
    </ul>
  </li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;video controls&gt;
	&lt;source type="application/vnd.ms-sstr+xml"
		src="http://example.com/videofile.ssm/Manifest"&gt;
&lt;/video&gt;
</code></pre>

<h3 id="using-mpeg-dash">Using MPEG-DASH</h3>

<p>Technical details are as follows:</p>

<ul>
  <li>Only Live profile is supported. VOD functionality can be still achieved by using Live profile</li>
  <li>container format is MP4</li>
  <li>Source pointing to the MPD manifest</li>
  <li>Source type set to <code>application/dash+xml</code></li>
  <li>PlayReady content will be supported here by future devices
    <ul>
      <li>Such content can be embedded with the <code>ContentProtection</code> element as defined by the reactive licence acquisition method</li>
      <li>Some device may not support Security Levels (content with any security level required is played)</li>
      <li>DRM errors are signaled by the <code>MediaError</code> element of the video tag</li>
    </ul>
  </li>
</ul>

<p>Example player code:</p>

<pre><code>&lt;video controls&gt;
	&lt;source type="application/dash+xml"
		src="http://example.com/videofile.isml/videofile.mpd"&gt;
&lt;/video&gt;
</code></pre>

<h2 id="subtitles">Subtitles</h2>

<figure block="figure">
<table>
<tr>
	<th width="50%">Format</th>
	<th>Supported in the Opera TV Store</th>
	<th>Supported in the Opera TV Emulator</th>
</tr>
<tr>
	<th>Out-of-band WebVTT</th>
	<td>Yes</td>
	<td>Yes</td>
</tr>
</table>
</figure>

<p>Opera TV Store supports out-of-band subtitles through HTML5’s <code>&lt;track&gt;</code> tag and a WebVTT (Web Video Text Tracks) file format. Out-of-band means subtitles are delivered in addition to the media file.</p>

<p>Example player code:</p>

<pre><code>&lt;video&gt;
  		&lt;source type="video/mp4" src="http://example.com/video.mp4"&gt;
  		&lt;track src="http://example.com/subtitles.vtt" srclang="en" label="English"&gt;
&lt;/video&gt;
</code></pre>

<p>WebVTT subtitles can be also used together with all ABR or DRM formats mentioned in this article just by adding the <code>&lt;track&gt;</code> tag.</p>

<p>More information about using the WebVTT format can be found in <a href="http://dev.opera.com/articles/an-introduction-to-webvtt-and-track/">this article</a>.</p>

<p>In-band subtitles (included inside the media container e.g. MP4) are supported at subset of devices only. In addition platforms are fragmented so we recommend using out-of-band subtitles with the WebVTT format only.</p>

<h2 id="testing">Testing</h2>

<p><a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a> supports the above audio and video formats, including subtitles but without adaptive bitrate streaming and DRM. You can test H.264 streaming or audio playback in your application with it. Please note that because of licensing reasons the H.264 codecs are not installed by default. See the <a href="http://dev.opera.com/tv/opera-tv-emulator/#h264-codec">emulator’s user guide</a> for information of how to install these codecs.</p>

<p>Since the <a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a> doesn’t support any adaptive bitrate streaming or DRM formats, the only way to test such streams in your application is to use a retail device. We recommend to use Sony Blue-ray Disc Players 2013 or 2014 models e.g. BDP-S1100 or BDP-S1200. For more info on how to test your app inside the Opera TV Store see <a href="http://dev.opera.com/tv/testing-your-app-inside-opera-tv-store/">our article</a> about it.</p>

]]></content></entry><entry><id>https://dev.opera.com/tv/functional-key-handling-in-opera-tv-store-applications/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/functional-key-handling-in-opera-tv-store-applications/"/><title>Functional Key Handling in Opera TV Store Applications</title><published>2012-02-10T00:00:00+00:00</published><updated>2012-02-10T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>Update history:</p>

<ul>
  <li>8 June 2012: added requirements for Back/Return button handling</li>
  <li>24 August 2012: changes to key handling in line with <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a>, additional information on repeating key events.</li>
  <li>4 September 2012: alternative and refined approach for handling repeating key events, clarification of extra <code>&lt;ELEMENT onkeydown="…"&gt;</code> complications to get event object, inclusion of HTML5 history API trick to circumvent automatic app closure.</li>
</ul>

<ul>
  <li><a href="#spatial-functional">Spatial navigation and functional buttons</a></li>
  <li><a href="#functional-buttons">List of available functional buttons</a></li>
  <li><a href="#handling-keydown">Handling <code>keydown</code> events</a></li>
  <li><a href="#repeat">Repeating key events</a></li>
  <li><a href="#return">Requirements for the <code>Back/Return</code> button</a></li>
  <li><a href="#prevent-default">Preventing default spatial navigation</a></li>
  <li><a href="#determining-support">Determining support for a specific functional key</a></li>
</ul>

<h2 id="spatial-functional">Spatial navigation and functional buttons</h2>

<p>The Opera TV Store is designed to use the standard four-way directional keys on a remote control for spatial navigation. Authors should test that their applications work correctly using the default spatial navigation built into the Opera TV Store browser.</p>

<p>Opera’s spatial navigation works in a similar way to traditional TAB based keyboard access in most browsers, allowing users to move between focusable elements (links, form controls, image map areas). In addition, spatial navigation also employs heuristics that make arbitrary elements with attached <code>click</code> and <code>mouseover</code> JavaScript events focusable as well. Lastly, as the name implies, spatial navigation in Opera allows the user to move between those elements based on their spatial relationship on screen, rather than in source order (as with <code>TAB</code> navigation).</p>

<p>In most cases, authors can simply rely on Opera’s spatial navigation to handle their application’s controls. There are simple mechanisms to further <a href="/tv/tweaking-spatial-navigation-for-tv-browsing/">tweak spatial navigation for TV browsing</a> using CSS3.</p>

<p>For maximum control, authors may also choose to handle the navigation of their application themselves by intercepting key presses from the remote control. This makes it possible to not only react to the basic directional buttons (<code>UP</code>, <code>RIGHT</code>, <code>DOWN</code>, <code>LEFT</code>), but to further bind functionality to the various shortcut and functional keys (such as <code>BACK</code>, <code>INFO</code>, <code>OPTIONS</code> or the RED button). As the exact key codes for remote control keys vary between different devices, the Opera TV Store browser provides built-in <strong>global constants</strong> mapped to the hardware-specific codes used by the current device.</p>

<h2 id="functional-buttons">List of available functional buttons</h2>

<figure block="figure">
<table>
<thead>
<tr>
	<th>
		Hardware key
	</th>
	<th>
		Key code constant
	</th>
	<th>
		Availability in devices
	</th>
</tr>
</thead>
<tbody>
<tr>
	<td>
		↑
	</td>
	<td>
		VK_UP
	</td>
	<td>
		Always present in remote controllers*
	</td>
</tr>
<tr>
	<td>
		→
	</td>
	<td>
		VK_RIGHT
	</td>
	<td>
		Always present in remote controllers*
	</td>
</tr>
<tr>
	<td>
		↓
	</td>
	<td>
		VK_DOWN
	</td>
	<td>
		Always present in remote controllers*
	</td>
</tr>
<tr>
	<td>
		←
	</td>
	<td>
		VK_LEFT
	</td>
	<td>
		Always present in remote controllers*
	</td>
</tr>
<tr>
	<td>
		Confirm/Select/OK
	</td>
	<td>
		VK_ENTER
	</td>
	<td>
		Always present in remote controllers*
	</td>
</tr>
<tr>
	<td>
		Exit
	</td>
	<td>
		N/A
	</td>
	<td>
		Usually present in remote controllers
	</td>
</tr>
<tr>
	<td>
		Back/Return
	</td>
	<td>
		VK_BACK_SPACE
	</td>
	<td>
		Always present in remote controllers
	</td>
</tr>
<tr>
	<td>
		BLUE
	</td>
	<td>
		VK_BLUE
	</td>
	<td>
		Usually present in remote controllers
	</td>
</tr>
<tr>
	<td>
		RED
	</td>
	<td>
		VK_RED
	</td>
	<td>
		Usually present in remote controllers
	</td>
</tr>
<tr>
	<td>
		GREEN
	</td>
	<td>
		VK_GREEN
	</td>
	<td>
		Usually present in remote controllers
	</td>
</tr>
<tr>
	<td>
		YELLOW
	</td>
	<td>
		VK_YELLOW
	</td>
	<td>
		Usually present in remote controllers
	</td>
</tr>
<tr>
	<td>
		Menu
	</td>
	<td>
		VK_MENU
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		0
	</td>
	<td>
		VK_0
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		1
	</td>
	<td>
		VK_1
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		2
	</td>
	<td>
		VK_2
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		3
	</td>
	<td>
		VK_3
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		4
	</td>
	<td>
		VK_4
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		5
	</td>
	<td>
		VK_5
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		6
	</td>
	<td>
		VK_6
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		7
	</td>
	<td>
		VK_7
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		8
	</td>
	<td>
		VK_8
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		9
	</td>
	<td>
		VK_9
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		PLAY
	</td>
	<td>
		VK_PLAY
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		PAUSE
	</td>
	<td>
		VK_PAUSE
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		STOP
	</td>
	<td>
		VK_STOP
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		NEXT
	</td>
	<td>
		VK_TRACK_NEXT
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		PREV
	</td>
	<td>
		VK_TRACK_PREV
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		FF (Fast-Forward)
	</td>
	<td>
		VK_FAST_FWD
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		REWIND
	</td>
	<td>
		VK_REWIND
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		SUBTITLE
	</td>
	<td>
		VK_SUBTITLE
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
<tr>
	<td>
		INFORMATION
	</td>
	<td>
		VK_INFO
	</td>
	<td>
		Not available in some remote controllers
	</td>
</tr>
</tbody>
</table>
</figure>

<p><strong>Note:</strong> <code>CONFIRM</code>, <code>EXIT</code> and directional buttons are mandatory for device manufacturers to implement, so they are always available for the end user via the remote control of any device that the Opera TV Store is integrated with. The <code>EXIT</code> key is handled by the Opera TV Store browser itself, to ensure that each application can be closed. For this reason <code>VK_EXIT</code> will not be sent to the application. Not all keys from the table above are always present in various remote controllers (see Availability column). It is important to take this into account when designing an app. For example, it should be possible to play and pause video, even if the PLAY or PAUSE buttons are not available.</p>

<h2 id="handling-keydown">Handling <code>keydown</code> events</h2>

<p>Previously, authors were encouraged to handle <code>keypress</code> events. However, starting with the Opera Device SDK 3.4, the Opera TV Store is aligned with the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model.</p>

<p>The most notable change here is that the <code>keypress</code> event is now only fired for <em>keys which produce a character value</em>. From the list of functional buttons above, this means that only the number keys <code>0-9</code> and the <code>ENTER</code> (Confirm/Select/Ok) buttons can be detected via <code>keypress</code>.</p>

<p>Additionally, this specification deprecates the <code>keypress</code> event, meaning that future versions of the specification — and, as a result, future versions of conformant browsers — should not fire this event anymore. For compatibility with existing content, it is unlikely that browsers will drop legacy support for this event, but we would still recommend using <code>keydown</code> instead of <code>keypress</code> going forward.</p>

<p>The simplest, but least elegant, way to add key events is to directly add an <code>onkeydown</code> attribute to an element. When that element has focus, the key event code will be fired. Note, though, that this old-school method requires extra work to determine the event (and the related properties, like <code>keyCode</code>) that caused the handler to be called, and doesn’t necessarily work cross-platform.</p>

<pre><code>&lt;ELEMENT onkeydown="handler()"&gt;

function handler() {
	// extra hoop to jump through to get event
	if (!event) { event=window.event; }
	…
}
</code></pre>

<p>A much cleaner and flexible way would be to do this directly via JavaScript, either by attaching the handler function directly to the <code>onkeydown</code> property of the element or using <code>addEventListener</code>. This automatically passes on the event object associated with the call, avoiding any ugly <code>window.event</code> hacks:</p>

<pre><code>object.onkeydown = handler;
object.addEventListener('keydown', handler, useCapture);
</code></pre>

<p>In the <code>handler</code> function, you can then compare the <code>event.keyCode</code> to the set of global constants for functional keys provided in the Opera TV Store.</p>

<pre><code>function handler(event){
	…
	if (VK_RED == event.keyCode){
		/* VK_RED was pressed … do something useful */
	}
	…
}
</code></pre>

<p>Although the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model normatively uses <code>event.key</code> and <code>event.char</code>, it still retains information on <a href="http://www.w3.org/TR/DOM-Level-3-Events/#legacy-key-attributes">legacy key attributes</a> such as <code>event.keyCode</code>. For compatibility with existing content, it is likely that <code>event.keyCode</code> will continue to be available for the time being. As the new event properties are not backwards-compatible, we recommend still using the current <code>event.keyCode</code> property.</p>

<p>Depending on the application, it is advisable not to include a large number of separate event handlers to various elements in the page, but to instead take advantage of event capture / bubbling and use an event delegation mechanism, hooking the <code>keydown</code> handler on a top-level element (for instance, the <code>body</code>) or object (<code>window</code> or similar):</p>

<pre><code>window.addEventListener('keydown', handler, useCapture);
</code></pre>

<p>In your <code>handler</code> function, you may need to determine the element where the event originated. A reference to this can be easily obtained from the <code>event.target</code>:</p>

<pre><code>function handler(event){
	…
	var target = event.target;
	…
}
</code></pre>

<h2 id="repeat">Repeating key events</h2>

<p>What happens when a user keeps a functional button on their remote control pressed is dependant on their specific device. Some devices will only send a single <code>keydown</code> event until the button is released. Others may send a series of <code>keydown</code> (and <code>keypress</code>, if it’s a key that produces a <em>character value</em>) and <code>keyup</code> events (as if the button was manually being pressed and released multiple times). Lastly, platforms that do support proper key repeats will send a continuous stream of <code>keydown</code> (and <code>keypress</code>, if it’s a key that produces a <em>character value</em>) events, and only fire <code>keyup</code> once the user releases the button.</p>

<p>In general, since it cannot be guaranteed that a device has full key repeat support, we’d recommend not making an application reliant on this behaviour.</p>

<p>If your applications does need to handle repeating / long-press button events, the switch to the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model in the Opera Device SDK 3.4 may require some additional work in order to ensure backwards- and forwards-compatibility.</p>

<p>Previously, repeating keys (on supporting platforms) used to fire:</p>

<ul>
  <li><code>keydown</code> &gt; [multiple <code>keypress</code>] &gt; <code>keyup</code></li>
</ul>

<p>New versions of the Opera TV Store, in accordance with the <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> model, will instead fire:</p>

<ul>
  <li>[multiple <code>keydown</code> and <code>keypress</code>] &gt; <code>keyup</code> (for keys that produce a <em>character value</em>)</li>
  <li>[multiple <code>keydown</code>] &gt; <code>keyup</code> (for all other keys)</li>
</ul>

<p>If for previous versions of the TV Store your code listened to repeating <code>keypress</code> events, the best way to remain compatible is to register your handlers for <strong>both</strong> <code>keydown</code> and <code>keypress</code>. To avoid having functionality being triggered twice (for the first button press in the old SDK, and for repeating <em>character value</em> keys in the new SDK), you can take advantage of the <code>event.repeat</code> property introduced in <a href="http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order">DOM Level 3 Events</a> to filter out unwanted duplicate events:</p>

<pre><code>// example using event delegation
window.addEventListener('keydown', handler, useCapture);
window.addEventListener('keypress', handler, useCapture);

function handler(event){
	if ((event.type=='keydown' &amp;&amp; !('repeat' in event)) ||
		(event.type=='keypress' &amp;&amp; ('repeat' in event))) return;
	…
}
</code></pre>

<p>Alternatively, if you’re binding event handlers via JavaScript already, you can use the new <code>window.KeyboardEvent</code> interface as an indicator for DOM 3 support, and only bind your event handler to either <code>keydown</code> or <code>keypress</code>.</p>

<pre><code>// example using event delegation
if (window.KeyboardEvent){
	window.addEventListener('keydown', handler, useCapture);
} else {
	window.addEventListener('keypress', handler, useCapture);
}

function handler(event){
	// no need to de-dupe events
	…
}
</code></pre>

<h2 id="return">Requirements for the <code>Back/Return</code> button</h2>

<p>Most remote controllers have a <code>Back</code> or <code>Return</code> button. In the Opera TV emulator, this is equivalent to pressing the <code>BACKSPACE</code> key. The Opera TV Store requires that the <code>Back/Return</code> button works consistently in each application as follows:</p>

<ul>
  <li>Pressing <code>Back/Return</code> must return the user to the previous page or screen.</li>
  <li>If the user is at the first page of the application, the application should close.</li>
  <li>If the user is at an “Exit app” confirmation dialog, the application should close.</li>
</ul>

<p>In other words, if the user presses <code>Back/Return</code> repeatedly, they will eventually exit the application and return to the TV Store menu.</p>

<p>If your application consists of regular pages loaded one after another, the <code>Back/Return</code> button should work without any extra effort — the correct behaviour is handled automatically by Opera. If your application is using AJAX, overlays or history modifications, however, then Back/Return must be handled by your application. Here are examples of how such behaviour can be coded:</p>

<pre><code>// To close overlays with Back/Return
function handler(event) {
	// assuming there’s a global boolean overlay_opened
	if (overlay_opened &amp;&amp; event.keyCode == VK_BACK_SPACE) {
		event.preventDefault();
		overlay_opened = false;
		closeOverlay();
	}
}

// To close the application with Back/Return
function handler(event) {
	// assuming there’s a global boolean main_page
	if (main_page &amp;&amp; event.keyCode == VK_BACK_SPACE) {
		event.preventDefault();
		main_page = false;
		window.close();
	}
}
</code></pre>

<p>Currently, the Opera TV Store has implemented some additional hardcoded behavior which automatically closes an application if the user presses Back/Return and the browser history is empty, without the possibility to <code>preventDefault()</code> the event. The idea is to avoid faulty applications from inadvertently trapping users.</p>

<p>To circumvent this behavior, a slightly hacky workaround is to user the HTML5 history management API to inject entries into the browser history.</p>

<pre><code>window.history.pushState({}, document.title, '#dummy_url');
</code></pre>

<p>After this, the preceding code snippets to manually handle the Back/Return key using <code>preventDefault()</code> will work as expected.</p>

<h2 id="prevent-default">Preventing default spatial navigation</h2>

<p>When handling key events directly, you will probably want to stop the Opera TV Store browser from carrying out its normal spatial navigation and element activation behaviours. This can simply be suppressed in the <code>handler</code> function:</p>

<pre><code>function handler(event){
	…
	event.preventDefault();
	…
}
</code></pre>

<h2 id="determining-support">Determining support for a specific functional key</h2>

<p>Authors can check if a specific functional key has been defined on the current device using a simple JavaScript check. If a button is supported, the constant will contain the device-specific key code of the button; otherwise, the constant will return a <code>null</code> value. For example, to test for the VK_RED key:</p>

<pre><code>if (VK_RED !== null) {
	/* VK_RED is supported */
	…
}
</code></pre>

<p>Although all devices running the Opera TV Store should have all the global constants listed above defined (though their value may be <code>null</code>, if the device’s default remote control doesn’t have a particular button), it is still advisable to also check for the existence of the constant before using it, to avoid any <code>Unhandled Error: Undefined variable</code> JavaScript errors.</p>

<pre><code>if (('VK_RED' in window)&amp;&amp;(VK_RED !== null)) {
	/* VK_RED is supported */
	…
}
</code></pre>

<p>This precaution should also be taken when checking <code>event.keyCode</code> values against those constants:</p>

<pre><code>function handler(event){
	…
	if (('VK_RED' in window)&amp;&amp;(VK_RED == event.keyCode)){
		/* VK_RED was pressed … do something useful */
	}
	…
}
</code></pre>

<p>The list of <code>VK_*</code> global constants is currently set in a <code>user.js</code> file, which OEMs include as part of their Opera TV Store installation at integration time. Device manufacturers will include the buttons and their respective key codes based on the default remote controls that ship with their devices. With this approach, however, any third-party or alternative remote controls may not match the standard remote’s set of functional buttons — the constants may be defined and present, but the actual remote doesn’t have those physical keys. For this reason, it’s still advisable to use caution and to make applications work with the minimal set of <em>Always available</em> keys.</p>
]]></content></entry><entry><id>https://dev.opera.com/tv/building-applications-for-the-opera-tv-store/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/building-applications-for-the-opera-tv-store/"/><title>Building Applications for the Opera TV Store</title><published>2012-02-10T00:00:00+00:00</published><updated>2012-02-10T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>Update history:</p>

<ol>
  <li>18 April 2012: new section for currently known limitations of the Opera TV Store.</li>
  <li>27 August 2012: explicit note about lack of support for third-party multimedia plugins.</li>
  <li>5 September 2012: removed the requirement for inclusion of the Opera TV Store API.</li>
  <li>20 January 2013: added note about modal dialogs and lack of support for <code>alert()</code>, <code>prompt()</code> and <code>confirm()</code></li>
</ol>

<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#building">Building your application</a></li>
  <li><a href="#requirements">Requirements specific to Opera TV Store applications</a>
    <ul>
      <li><a href="#requirements-resolution">Resolution</a></li>
      <li><a href="#requirements-navigation">Navigation and functional keys</a></li>
      <li><a href="#requirements-modal-dialogs">Modal dialogs</a></li>
      <li><a href="#requirements-plugin-flash">Multimedia plugins / Flash</a></li>
      <li><a href="#requirements-closing">Closing applications</a></li>
      <li><a href="#requirements-limitations">Limitations of current implementations</a></li>
    </ul>
  </li>
  <li><a href="#submitting">Submitting to the Opera TV Store</a></li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>The Opera TV Store is a moderated, hosted catalogue of TV-specific web applications. Developers can submit and share their apps through this portal. It presents end users with a storefront (itself a web-based application) which allows them quick and easy access to the applications.</p>

<figure block="figure">
	<img elem="media" src="/tv/building-applications-for-the-opera-tv-store/sample-views.png" alt="Sample Opera TV Store and an application" />
	<figcaption elem="caption">Sample Opera TV Store and a sample weather application</figcaption>
</figure>

<p>Applications in the Opera TV Store will be presented as static thumbnail images in a dashboard. Users are able to browse the TV Store catalogue and “install” applications, adding them to their dashboard. Selecting an application launches it in full-screen mode.</p>

<figure block="figure">
	<img elem="media" src="/tv/building-applications-for-the-opera-tv-store/architecture.png" alt="Opera TV Store architecture diagram" />
	<figcaption elem="caption">A simple overview of the Opera TV Store architecture</figcaption>
</figure>

<p>The full-screen web applications themselves are not hosted directly on Opera’s servers. The Opera TV Store only acts as a directory, with references to the actual URLs of the applications.</p>

<h2 id="building-your-application">Building your application</h2>

<p>Applications for the Opera TV Store are, in essence, regular web applications, which are rendered by a customised version of <a href="https://www.opera.com/business/devices/">Opera Devices SDK</a> browsing environment on the user’s TV. As such, developers can tap into all the traditional web technologies (HTML5, CSS 3, JavaScript, SVG) supported by the Opera browser. See our documentation on <a href="https://www.opera.com/docs/specs/">web specifications supported by Opera</a> (and in particular our comparison of <a href="https://www.opera.com/docs/specs/productspecs/">support in different Opera product lines</a>) for a thorough breakdown.</p>

<p>Although the Opera Devices SDK is built on the same core rendering engine as our desktop browsers, there are still platform-specific APIs and subtle integration differences that developers need to be aware of. For this reason, it is recommended that developers test their applications on an actual TV running the Opera TV Store and/or with the <a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a>.</p>

<p>Developing web content for TV brings with it its own challenges – from a difference in user interaction to considerations regarding device capabilities and performance optimisation. For an introduction to some of the necessary adaptations and techniques see our documentation on <a href="/tv/creating-web-content-for-tv/">creating web content for TV</a> and other articles in our <a href="/tv/">TV section</a>.</p>

<h2 id="requirements-specific-to-opera-tv-store-applications">Requirements specific to Opera TV Store applications</h2>

<p>Due to the way in which applications will be integrated into, and launched from, the Opera TV Store, developers need to be aware of the following additional requirements:</p>

<h3 id="resolution">Resolution</h3>

<p>All TV Store applications have to support 1280×720 resolution. Other common TV resolutions (1920×1080, 960×540) are currently not supported. Although the TV Store browser itself supports regular scrolling, applications should be designed not to require scrolling, and if needed should provide their own custom mechanisms for displaying long lists of items or content.</p>

<h3 id="navigation-and-functional-keys">Navigation and functional keys</h3>

<p>The Opera TV Store is designed to use the standard four-way directional keys on a remote control for spatial navigation. Authors should test that their applications work correctly using the default spatial navigation built into the Opera TV Store browser. Authors may also choose to handle the navigation of their application themselves by intercepting key presses from the remote control. As the exact key codes for remote control functional keys varies between different devices, the Opera TV Store browser provides built-in constants (tailored to the device currently running the TV Store). See the article on <a href="/tv/functional-key-handling-in-opera-tv-store-applications/">Functional key handling in Opera TV Store applications</a> for further details.</p>

<h3 id="modal-dialogs">Modal dialogs</h3>

<p>As the standard JavaScript methods for <code>alert()</code>, <code>prompt()</code> and <code>confirm()</code> are not supported on all platforms that run the Opera TV Store (since they require platform integration), applications that needs modal dialogs (such as data entry prompts or general alerts/messages) need to provide these using HTML/CSS/JavaScript – which also allows for these modal dialogs to be styled in line with the rest of the application.</p>

<h3 id="multimedia-plugins--flash">Multimedia plugins / Flash</h3>

<p>The Opera TV Store does not provide support for any third-party plugins, such as Adobe Flash. Any multimedia features and functionality needed by an application must be implemented using HTML5 technologies such as <code>&lt;canvas&gt;</code> or the native support for <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code> elements.</p>

<h3 id="closing-applications">Closing applications</h3>

<p>Once an application is launched from the dashboard, it is effectively opened full screen in a new window. The Opera TV Store browser (based on the Opera Devices SDK, responsible for rendering the applications and the TV Store itself) does not present any standard interface elements to the user – it runs as a completely “chromeless” browser, with no address bar or back button. Users will be able to close the application and return to their dashboard via the remote control’s <em>EXIT</em> and/or <em>RETURN</em> key. Developers should nonetheless provide an explicit option or button in their UI to close the application, with a simple call to the <code>window.close()</code> method.</p>

<h3 id="limitations-of-current-implementations">Limitations of current implementations</h3>

<p>There are known limitations in some of the current devices that are shipping with the Opera TV Store, generally due to the way certain features have been integrated on the devices by the manufacturers and which version of the TV Store software has been used.</p>

<ul>
  <li>Missing <a href="/articles/dom-access-control-using-cors/">CORS (Cross-Origin Resource Sharing)</a> support: if your application relies on cross-origin resources (particularly via <code>XMLHttpRequest</code>), you will need to implement some form of proxy on your application’s origin domain to relay the resources from other domains.</li>
  <li>Due to the integration with external media playback frameworks on certain devices, it may not be possible to guarantee simultaneous playback of more than a single <code>audio</code> or <code>video</code> element.</li>
</ul>

<h2 id="submitting-to-the-opera-tv-store">Submitting to the Opera TV Store</h2>

<p>Once your application is ready, it can be submitted to the Opera TV Store. Log in to the <a href="https://publish.tvstore.opera.com/">Opera TV Store – Submission portal</a> and follow the steps required in the submission dialog.</p>

<p>This article summarises the most important guidelines that applications need to follow for inclusion in the Opera TV Store. Further restrictions and requirements are listed in the <strong>acceptance criteria</strong> of the <a href="https://publish.tvstore.opera.com/guidelines/">Opera TV Store application publishing guidelines</a>. Please ensure that your application fulfills those criteria – as well as the best practices and suggestions laid out in our developer articles – before submitting your application.</p>

]]></content></entry><entry><id>https://dev.opera.com/tv/design-considerations-for-opera-tv-store-applications/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/design-considerations-for-opera-tv-store-applications/"/><title>Design Considerations for Opera TV Store Applications</title><published>2012-02-09T00:00:00+00:00</published><updated>2012-02-09T00:00:00+00:00</updated><author><name>Patrick H. Lauke, Yenny Otero</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#checklist">Quick checklist</a></li>
  <li><a href="#context">Potential of the TV context</a></li>
  <li><a href="#simplicity">Simplicity</a></li>
  <li><a href="#distance">User distance</a></li>
  <li><a href="#resolution_overscan">Resolution and overscan</a></li>
  <li><a href="#layout">Layout</a>
    <ul>
      <li><a href="#layout_examples">Examples</a></li>
    </ul>
  </li>
  <li><a href="#navigation">Navigation/Controls</a>
    <ul>
      <li><a href="#back_key">The BACK key</a></li>
      <li><a href="#shortcuts">Shortcuts</a></li>
    </ul>
  </li>
  <li><a href="#input">Text input</a></li>
  <li><a href="#responsiveness">Responsiveness</a></li>
  <li><a href="#privacy">Privacy</a></li>
  <li><a href="#testing">Testing/App submission</a></li>
</ul>

<h2 id="introduction">Introduction</h2>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/tvstore.png" alt="The Opera TV Store" />
	<figcaption elem="caption">The Opera TV Store dashboard</figcaption>
</figure>

<p>The Opera TV Store offers a platform for delivering HTML5-based applications to customers on TV.</p>

<p>Although TV Store applications are, in essence, nothing more than web pages, there are certain design considerations related to the TV context in general, and the Opera TV Store model in particular, that developers need to take into consideration.</p>

<h2 id="quick-checklist">Quick checklist</h2>

<p>This is a summary of our recommendations for an optimised TV Store application experience:</p>

<ul>
  <li>Keep things simple and consistent</li>
  <li>Less is more – TV screen may be big, but are usually viewed from a greater distance.</li>
  <li>For best legibility and usability, use sans-serif fonts at a size of at least 22px and make your selectable elements at least 34px in height.</li>
  <li>Make sure your application works at a size of 1216×684px (leaving a 5% margin on the Opera TV Store’s resolution of 1280×720 to account for <a href="#resolution_overscan">overscan</a>).</li>
  <li>Make everything accessible with the standard remote control keys: <code>UP</code>, <code>RIGHT</code>, <code>DOWN</code>, <code>LEFT</code> and <code>BACK</code> – other keys (specifically, the color keys found on most connected TVs and devices) are optional and should only be used as shortcuts.</li>
  <li>Ensure that the highlight/outline that indicates the currently selected element is clearly visible at all times.</li>
  <li>Avoid the need for the user to enter text.</li>
  <li>Make an application feel more responsive by giving quick feedback to the user actions.</li>
</ul>

<h2 id="potential-of-the-tv-context">Potential of the TV context</h2>

<p>The context of use of a TV is very different from the one for desktop computers or mobile phones. When you make an application for TV you should consider that:</p>

<ul>
  <li>TV is mostly used for entertainment and relaxation. Users prefer to avoid too much interaction or decision making.</li>
  <li>The TV is located far from the user and the only means of interaction is the remote control.</li>
  <li>TV interfaces resemble mobile interfaces because of the simplicity, however, TV interaction has to be modified to work with the remote control (4 key navigation).</li>
  <li>Unlike other devices, TVs are social devices where privacy is very limited.</li>
  <li>The strength of TV is in beautifully displaying big images, videos and sound. Your application should take advantage of these strengths.</li>
</ul>

<h2 id="simplicity">Simplicity</h2>

<p>Keep things simple — people love simple. Complicated interfaces confuse and frustrate people, and this issue can be compounded on TV apps. You want to give people videos? Show them on the first page. If your videos are more than a click or two away, your users will quit your app and turn on the Discovery Channel instead.</p>

<p>If your app can do everything, it cannot do anything. Limit the number of functions your app has to one or two and do those well, rather than being mediocre at lots of things. The user will be happier, and you will have less code to debug. For example, do you need a Twitter box inside your music app? music? Will your users add comments underneath photos, when there are thousands of other photos to see as well? Should you provide drawing tools inside your photo app, or just do that side of things in a separate app perhaps on a different system?</p>

<p>Some more laws of simplicity:</p>

<ul>
  <li>Try not to make an application that has more than 3 levels of depth. If needed, make more menu elements.</li>
  <li>If your application has more than 3 levels of complexity, it is even more important that the menu or the menu items are visible at all times.</li>
  <li>Don’t forget to include an “Exit” item in the menu.</li>
  <li>Keep things consistent across multiple views, like button controls and menus.</li>
  <li>In general, opt for a simple solution. A sophisticated 3D world may sound like a good idea, but will likely run inconsistently across devices, and be less effective than some nice drawings and humorous text.</li>
</ul>

<h2 id="user-distance">User distance</h2>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/10feetUx2.png" alt="10-feet UX" />
	<figcaption elem="caption">10-feet user experience: A user sits 10 feet away from the TV</figcaption>
</figure>

<p>TV interfaces are also known as 10-foot user interfaces because 10 feet (3m) is the approximate distance that users will sit from the TV. For designers, this means that the “big screen” cannot really be considered “big” but that you have to keep the same considerations that you have when making a mobile application:</p>

<ul>
  <li>All application elements and text need to be bigger than those used for computers. We recommend a minimum text size of 22px, though you may be able to go as low as 18px if your design does not accommodate a bigger font. Considering that you need approximately 10px of padding for your buttons, we recommend them to be of a minimum size of 34px height.</li>
  <li>Fonts should be big and clean. We recommend using simple sans-serif fonts.</li>
  <li>More empty space is needed between elements to avoid items blending into each other from a distance and creating clutter.</li>
  <li>There should be enough contrast between the background and the application elements. This is especially important when you use a fullscreen photo as a background.</li>
  <li>When items are selected, the highlight should be visible and clear so that there is never any doubt what is selected.</li>
  <li>Light content on a darker background is usually easier to read/view on a TV.</li>
  <li>Do not be tempted to think that a bigger screen means that you can include more content. Less is more. Only include relevant content, and keep the amount of content on each screen to a minimum.</li>
</ul>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/comparisonTvMobile.png" alt="TV viewer" />
	<figcaption elem="caption">A TV in the distance is not much bigger than a close mobile screen</figcaption>
</figure>

<p>Although TVs are similar in perceived size to a mobile device, it is not enough to take the design of a mobile application and expect it to always work well on a TV:</p>

<ul>
  <li>The mobile screen can be vertical and horizontal; a TV is only horizontal and, in some cases, widescreen.</li>
  <li>By being far away and controlled by a 4-way remote, all interactions made for touchscreen have to be reviewed and designed.</li>
</ul>

<h2 id="resolution-and-overscan">Resolution and overscan</h2>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/overscan.png" alt="TV viewer" />
	<figcaption elem="caption">If you don’t consider the overscan, part of your application will be out of the screen</figcaption>
</figure>

<p>The Opera TV Store runs at a resolution of 1280×720px. However, due to overscan, you should ensure that your application works and displays correctly at a size of 1216×684px.</p>

<p>All of today’s TV sets have a certain amount of overscan, meaning that margins of your application are shown outside the visible area of the TV. While it is possible for users to turn off overscan, it is better to design your application with this invisible margin in mind, as most users are likely unaware of this option. The overscan amount varies between TV sets but it is advisable to assume that a 5% margin might not be visible to the user.</p>

<p>We recommend that you test your applications with overscan both turned on and off.</p>

<h2 id="layout">Layout</h2>

<p>The layout of a TV application should be simple:</p>

<ul>
  <li>The best position for the menu elements is on the top or the left side.</li>
  <li>Keep the layout as simple as possible: menu and container (list, grid, one item, etc).</li>
  <li>Keep all related functionality and information together. For example, if you have information about a game score, keep all those in the same side / corner instead of scattering them around the screen or grouping them with other elements that are not relevant.</li>
  <li>Remember the basics of graphic design and review that your applications follow them: alignment, proximity, balance, consistency, contrast and whitespace.</li>
</ul>

<h3 id="examples">Examples</h3>

<p>To design the layout for your application, we recommend to have a maximum of two groups of items on the screen: the menu and the content. You can also have the menu in its own screen and dedicate your entire screen to the content.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/layout-justContent.png" alt="TV app with only content" />
	<figcaption elem="caption">Example of a TV app where the menu is on a separate screen</figcaption>
</figure>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/layout-horizontal.png" alt="TV app horizontal" />
	<figcaption elem="caption">Example of a TV app with horizontal layout</figcaption>
</figure>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/layout-vertical.png" alt="TV app vertical" />
	<figcaption elem="caption">Example of a TV app with vertical layout</figcaption>
</figure>

<h2 id="navigationcontrols">Navigation/Controls</h2>

<p>TV users are usually limited to a simple four-way spatial navigation (UP, RIGHT, DOWN, LEFT) with a regular remote.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/remote.jpg" alt="TV remote" />
	<figcaption elem="caption">Everything should be accessible with the directional keys, OK and Exit (also labelled BACK on certain remotes)</figcaption>
</figure>

<p>Although all-purpose web browsers on connected TVs may support a combination of spatial navigation and the use of a virtual mouse pointer, only spatial navigation is supported in the Opera TV Store.</p>

<p>You should strive to make navigation as simple as possible. Navigation usually works best with a rectangular/list design, where it is very clear which item is above/below, and to the left and right, of the selected item. Avoid navigation that requires users to jump diagonally to another item.</p>

<p>Avoid mixing vertical and horizontal navigation. It is better to rely solely on either horizontal or vertical columns, rather then mixing the two. Avoid putting content that is critical for user navigation at the top, or at the end, of a list; otherwise, users may be forced to go through the list to select it.</p>

<p>Horizontal navigation is often preferable because of the TV’s landscape orientation and aspect ratio, but this will depends on the application.</p>

<p>Try to avoid elements that need to be enabled or clicked first before being able to interact with them. For example, do not make a list that you need to click first to be able to navigate through it. If you have an element that contains sub-elements (for example, in a list) make it visually obvious that you need to click the item first, before you can select sub-elements.</p>

<p>As a last point, remember that the TV remote already has rather convenient volume/mute controls, so you generally don’t need to code those into your application. It sounds almost too obvious to say, but we’ve seen more than enough examples of superfluous volume controls.</p>

<h3 id="the-back-key">The BACK key</h3>

<p>The BACK key on the remote control works just like it does in a desktop browser. Users will be familiar with this key and expect it to bring them to the previous screen of the application. If needed, you can still provide a visible back button in the application.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/back.png" alt="TV app navigation flow" />
	<figcaption elem="caption">Navigation between screens using the BACK key</figcaption>
</figure>

<p>The ultimate goal of the BACK key is to take you out of the application. If possible, the application should save the current state and quit but, if this is not possible theBACK key should bring forward a dialog asking if the application should continue or quit.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/quitGame.png" alt="TV app menu" />
	<figcaption elem="caption">BACK key pressed when playing a game that cannot be stopped</figcaption>
</figure>

<h3 id="shortcuts">Shortcuts</h3>

<p>We recommend that all functionality is accessible with normal navigation using the directional keys. Color keys should be considered as “nice to have” shortcuts. Most people don’t bother learning shortcuts, and, depending on the particular remote control used, the color keys may not actually be located at a convenient position.</p>

<p>Color-key shortcuts are good to have in situations when you have an action that you are likely to do often but that might require many clicks to get to. This, however, also means that it is not always best to use all of the color keys, as users are more likely to remember one or two of them but not all four. Keeping all four shortcuts might mean the users don’t learn any of them. How many you use will depend on each application.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/shortcuts.png" alt="TV app with shortcut key legend" />
	<figcaption elem="caption">Example of the placement for a shortcut key legend</figcaption>
</figure>

<h2 id="text-input">Text input</h2>

<p>Historically, TVs have required very little interaction other than changing channels or volume settings. Even if remotes are becoming more advanced, they are still relatively primitive and are rarely optimized for text input.</p>

<figure block="figure">
	<img elem="media" src="/tv/design-considerations-for-opera-tv-store-applications/remote2.jpg" alt="TV Remote" />
	<figcaption elem="caption">A remote control uncomfortably close to the TV</figcaption>
</figure>

<p>Some TVs are shipped with external keyboards, but users are most likely to just be using the remote control. We recommend designing your application in such a way that avoids the need for text input as much as possible. Here are a few suggestions:</p>

<ul>
  <li>Provide viewing content suggestions to the user rather than relying on searching.</li>
  <li>Make it possible to navigate to content through logical categories.</li>
  <li>Always include “smart” autocompletion in search/edit fields, if this is possible.</li>
  <li>Let the user choose to stay in a logged-in state in applications that require login. This option could be given as a pre-selected “Keep me logged in” checkbox on the login screen.</li>
</ul>

<h2 id="responsiveness">Responsiveness</h2>

<p>TVs are still running on relatively low-end hardware. TV remotes are also still relatively unresponsive. This makes it extremely important that your applications feel as responsive as possible, to avoid creating an additional bottleneck. Here are a few things to keep in mind:</p>

<ul>
  <li>Make selection highlighting very visible, so the viewer never needs to spend time looking for it.</li>
  <li>Always include some kind of progress indicator if the operation is not instant.</li>
  <li>Make sure animation is not at the expense of performance. If an animation is not smooth, or adds a performance bottleneck, disable it.</li>
  <li>Always give feedback to a user action by changing the state of the affected element, showing a loading indicator, or using sounds.</li>
  <li>Do not force actions on focus that will take time — especially on a limited power device, such actions will make an app feel sluggish and unresponsive. Your awesome app might use different categories or channels to group content, but don’t switch between them on focus — let your users decide to switch by pressing OK.</li>
  <li>Full page reloads can look ugly and feel sluggish, particularly on a 70 inch TV, so if at all possible it is usually better to update content/views using Ajax on a single page, rather than using multiple pages.</li>
</ul>

<p>We highly recommend that you test your application on an actual TV.</p>

<h2 id="privacy">Privacy</h2>

<p>Mobile phones are personal devices that are not commonly shared. Desktop computers can be shared, but the operating system provides interfaces to change the currently active user, and the device is mostly used by one person at a time. TVs are social devices, placed in a common location of the house and too big to cover if you want to hide some information. This has implications for TV application design:</p>

<ul>
  <li>In most cases, users will not want to type their personal information on a TV application, especially if this is sensitive information such as passwords or credit card numbers. For these services, allow users to create their accounts on the desktop version of your website and make it easy to link their accounts to the TV application.</li>
  <li>Allow users to clean their viewing history easily.</li>
  <li>Plan your applications for concurrent use and interaction by multiple people (e.g. multiplayer games, adding items to a shared playlist)</li>
</ul>

<h2 id="testingapp-submission">Testing/App Submission</h2>

<p>Before submitting your app to the app store, and preferably as early on in your development process as possible, give it some proper testing. You should make sure it works across the different target devices your target audience will be likely to use, sure, but you should also do some user testing. Let you neighbour play with it. The waitress/waiter in your favourite coffee place. Your boss. Watch and observe, how they do actions, how they try to accomplish actions and learn from it. Improve your app as a result.</p>

<p>Last but not least, take a few seconds to read our documents about app submissions:</p>

<ul>
  <li><a href="/tv/functional-key-handling-in-opera-tv-store-applications/">Functional key handling in Opera TV store applications</a></li>
  <li><a href="/tv/design-considerations-for-opera-tv-store-applications/">Design considerations for Opera TV store applications</a></li>
  <li><a href="https://publish.tvstore.opera.com/guidelines/#acceptance-criteria">Opera TV store acceptance criteria</a></li>
</ul>

<p>Adhering to these guidelines will make store acceptance of your app a lot easier and quicker.</p>
]]></content></entry><entry><id>https://dev.opera.com/tv/opera-for-devices-out-of-memory-system/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/opera-for-devices-out-of-memory-system/"/><title>Opera for Devices: Out of Memory System</title><published>2011-11-21T00:00:00+00:00</published><updated>2011-11-21T00:00:00+00:00</updated><author><name>DevRel Team</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p><a href="https://www.opera.com/business/devices/">Opera for Devices</a> provides powerful mechanisms to strictly limit the heap usage of Opera. Memory is an expensive commodity on many devices and different programs may compete for the limited resources with unpredictable consequences. With the Out of Memory (OOM) system it is possible to restrict Opera to a limited amount of memory while ensuring good functionality.</p>

<p>Although this topic is more a concern for customer integrating Opera on their devices rather then for content developers, understanding how memory allocation works on limited memory devices is important to be able to optimize your application and understand which kind of behaviour to expect from Opera when running out of memory.</p>

<h2 id="content">Content:</h2>

<ul>
  <li><a href="#understanding">Understanding out of memory situations</a></li>
  <li><a href="#system">The Opera OOM system</a></li>
  <li><a href="#problems">What problems does each mechanism solve?</a></li>
  <li><a href="#employing">Employing the OOM system</a></li>
</ul>

<h2 id="understanding-out-of-memory-situations">Understanding out of memory situations</h2>

<p>Linux is generally not OOM safe, so it is not possible to rely on malloc(), and so on, to fail when memory runs low. A Linux environment is usually set up so that malloc() never, or seldom, returns NULL. Consequently most Linux applications and libraries do not expect this to happen, and do not handle it well. This only works well on a desktop system that rarely runs out of memory.</p>

<p>In the rare event when a Linux system does get low on memory, the kernel has a sophisticated algorithm which selects and kills the process using too much memory — <em>the OOM-killer</em>. The problem is that an application is never told about the low memory condition until it is too late, and the application is killed. To the end user, it will simply appear to crash. On a device with very limited memory, this is undesirable and it is best to avoid this.</p>

<h2 id="the-opera-oom-system">The Opera OOM system</h2>

<p>To combat problems associated with limited memory, we have implemented a system that ensures that Opera behaves well in low memory situations. It provides two mechanisms that effectively limit Opera heap memory usage.</p>

<h3 id="limit-by-heap-size">Limit by heap size</h3>

<p>The first mechanism captures memory allocations in Opera and force-fails them if they would cause the process heap size to grow beyond the set limit.</p>

<h3 id="limit-by-allocation-size">Limit by allocation size</h3>

<p>The second mechanism internally keeps track of the amount of memory that Opera has allocated, and force-fails any allocations that would cause the total to exceed the allowed limit.</p>

<h3 id="internal-oom-handling">Internal OOM handling</h3>

<p>Internal OOM handling is triggered by a force-failed memory allocation, regardless of which mechanism triggered it. Internal OOM handling frees as much memory as possible and, if necessary, stops page loading. This means that Opera should not cause the heap to increase past the set limit and that Opera should be able to keep the amount of memory allocated below the specified limits.</p>

<p>Opera also sends an OOM notification to the implementation layer, alerting it that Opera is low on memory. How this situation is handled can differ between different Opera Powered products, e.g. a dialog suggesting closing of any unused applications could be shown.</p>

<h2 id="what-problems-does-each-mechanism-solve">What problems does each mechanism solve?</h2>

<p>The two different mechanisms in the OOM system work quite differently to solve different problems. It is necessary to take in to account the use case for the device to determine how to best configure the OOM system. Typically, it is a good idea to employ both mechanisms, but it is important to understand the effects of them to tune the behavior.</p>

<p>This topic describes a number of issues and how they are affected by the OOM system.</p>

<h3 id="memory-starvation">Memory starvation</h3>

<p>There may be situations where Opera is effectively starved for memory, and internal OOM handling is unable to raise enough memory to browse normal pages, rendering the browser unusable. This problem arises when the Opera heap limit has been reached, but Opera still does not have enough memory.</p>

<h3 id="what-causes-this-problem">What causes this problem?</h3>

<p>There are other parts of the Opera process that are not affected by the OOM system, such as plug-ins and user interface sections. These share Opera’s heap space but Opera does not control them. In some situations, they may be allocating on the heap, filling it up with memory, growing it far above the size allowed to Opera. The more they allocate, the less may be available to Opera. This may lead to Opera starving, as it will never be allowed to increase the heap.</p>

<p>This problem can be alleviated by listening for Opera’s OOM signals and thoroughly clearing any plug-in or user interface memory that currently does not need to be allocated.</p>

<p>Another cause of memory starvation could be that the heap is suffering from severe fragmentation. If this is the case, large allocations cannot be provided without growing the heap, particularly if the heap limit was not initially generous. In extreme cases, the heap may be so badly fragmented that Opera functionality is crippled.</p>

<p>If memory starvation is a significant problem, the solution may be to increase the heap limit and to consider a stricter employment of an allocation limit.</p>

<h3 id="heap-limiting-and-allocation-limits">Heap-limiting and allocation limits</h3>

<p>One notable aspect of heap-limiting Opera is that it will only stop allocations which <em>grow</em> the heap. If the heap has been increased by some other part of the process, Opera is allowed to use the available memory on the heap. In some situations where the heap has been increased a lot, Opera may allocate huge amounts of memory. This may be either good or bad. On the one hand, it will use memory which is available on the heap, which may otherwise lie unused. On the other hand, this memory may only have been temporarily allocated, and using it may prevent it from being reduced when Linux attempts to shrink the heap. This can lead to quite a vicious circle.</p>

<p>To stop this phenomenon, use an allocation limit to prevent the Opera heap from growing too large, even if it thinks it has plenty of room.</p>

<h3 id="oversized-heap">Oversized heap</h3>

<p>One problem with using an allocation limit is that the heap size may grow very large. The allocation limit does not take in to consideration fragmentation effects. If the heap suffers from heavy fragmentation, it may grow to large sizes as Opera continues to allocate memory regardless.</p>

<p>Also, it may be desirable to keep Opera from growing the heap if other parts of the process have temporarily allocated more memory than usual — even at the expense of Opera functionality.</p>

<p>To reduce the effects of this problem, set a stricter heap limit.</p>

<h3 id="conclusion">Conclusion</h3>

<p>It may not be perfect for every platform, but you will probably want to employ both mechanisms of the OOM system. The allocation limit should be smaller than the heap limit to allow room for user interface and plug-ins to live on the heap. The exact numbers for your platform can only be attained through careful experimentation.</p>

<h2 id="employing-the-oom-system">Employing the OOM system</h2>

<p>It is possible to set environment variables <code>OPERA_HEAP_LIMIT</code> and <code>OPERA_ALLOC_LIMIT</code> in the Linux shell used to launch Opera to control opera OOM limits. These variables are enforced as soon as Opera starts. One example:</p>

<ul>
  <li><code>export OPERA_HEAP_LIMIT=8388608</code> Limit Opera heap size to 8MB</li>
  <li><code>export OPERA_ALLOC_LIMIT=6291456</code> Limits the amount of memory that Opera is allowed to use on the heap to 6MB</li>
</ul>
]]></content></entry><entry><id>https://dev.opera.com/tv/tweaking-spatial-navigation-for-tv-browsing/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/tweaking-spatial-navigation-for-tv-browsing/"/><title>Tweaking Spatial Navigation for TV Browsing</title><published>2011-07-25T00:00:00+00:00</published><updated>2011-07-25T00:00:00+00:00</updated><author><name>Daniel Davis</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>One of the biggest challenges designing content for TVs is navigation. Not only are there several different methods that can be used to navigate a page, but none of them provide the perfect blend of convenience and practicality, at least not yet. At the time of writing, a user could be controlling their TV browsing session with any of the following devices:</p>

<ul>
  <li>A remote control with a D-pad (with keypad)</li>
  <li>A remote control with a touchpad or similar (with full keyboard)</li>
  <li>A gyroscopic mouse</li>
  <li>An infrared pointer</li>
  <li>A touchscreen mobile phone or tablet</li>
</ul>

<p>Currently the most widely used by far is the regular remote control with basic up, down, left, right and select buttons. Using directional controls like this is referred to as spatial navigation and is essential to understand to create a great TV experience. It is also the same navigational method used on mobile phones with keypads and non-touch devices such as Amazon’s Kindle.</p>

<h2 id="testing-spatial-navigation">Testing spatial navigation</h2>

<p>Beyond the browser on TVs and similar web-connected devices, spatial navigation is also available in Opera on its other popular platforms. Developers can easily test spatial navigation on their desktop machines:</p>

<ul>
  <li>In the <a href="https://www.opera.com/browser/">Opera desktop browser</a>, hold down the Shift button and press the arrow keys.</li>
  <li>In the <a href="https://www.opera.com/developer/tools/mobile/">Opera Mobile emulator</a>, select <em>Keypad</em> in the launch settings window.</li>
</ul>

<p>An eye-opening exercise is to browse a few popular sites using only spatial navigation. Although it probably won’t be impossible, it is likely to be frustrating with the cursor seeming to focus on elements at random. Television adds an extra layer of frustration and that’s due to the infrared connection between the remote control and the TV. This causes a noticeable delay of up to half a second or so between pressing a button on the remote control and the cursor moving on the screen. Consequently, any mistake by the user or unexpected movement of the cursor is particularly expensive in terms of time wasted. Fortunately, we can alleviate a lot of this with CSS3.</p>

<h2 id="controlling-navigation-with-css3">Controlling navigation with CSS3</h2>

<p>The <a href="http://www.w3.org/TR/css3-ui/#nav-dir">CSS3 Basic User Interface specification for directional focus navigation</a> is refreshingly simple both to explain and to implement. It’s purpose is to enable you to specify which element should receive focus when a user presses one of the directional buttons. For example, if the user is focused on your copyright notice at the bottom of a page and presses the down arrow key, you could tell the cursor to focus on your logo at the top of the page. The CSS code for that would be something like this:</p>

<pre><code>/* CSS */
#copyright {
	nav-down: #logo;
}
</code></pre>

<p>Note that this can be applied to any CSS selector, but the property’s value must be the <code>ID</code> of an element, i.e. preceded by #. Not surprisingly, other possible property names are <code>nav-up</code>, <code>nav-left</code> and <code>nav-right</code>. As you can see, it’s a very straightforward enhancement to implement and although it won’t be noticed by in a desktop or touchscreen environment, for users relying on D-pad to navigate, it can improve their experience remarkably. Just make sure you fully test it yourself before publishing, to avoid any nasty surprises.</p>

<p>Note: Often you will want to control the look of the spatial navigation highlight, or even suppress it completely. This can be done by manipulating the <code>outline</code> CSS property, so for example you could use <code>outline: 2px solid rgba(0,0,0,0.0);</code> to suppress the highlight.</p>

<h2 id="example">Example</h2>

<p>Here’s an <a href="/tv/tweaking-spatial-navigation-for-tv-browsing/example.html">example of spatial and CSS navigation</a>. It shows two identical groups of photos–try using just the left and right arrows to move from photo to photo. The first group relies on the browser’s spatial navigation algorithm whereas the second group uses CSS navigation, enabling the user to scroll through the photos with ease.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Particularly on devices with a simple set of directional keys, spatial navigation is a far more natural way of navigating a page than a simple “jump to next/previous link” approach — and with a sprinkling of CSS, developers can further tweak the order in which elements receive focus.</p>
]]></content></entry><entry><id>https://dev.opera.com/tv/creating-web-content-for-tv/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/creating-web-content-for-tv/"/><title>Creating Web Content for TV</title><published>2010-09-09T00:00:00+00:00</published><updated>2010-09-09T00:00:00+00:00</updated><author><name>Patrick H. Lauke</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p block="disclaimer"><strong>Please note</strong> that parts of this article refers to older Presto-based versions of the Opera TV products (Opera TV SDK 3.x). These versions are still live in a lot of devices that are active in all markets, but most devices shipped since 2015 are based on the newer Blink-based Opera product.</p>

<p>Update history:</p>

<ul>
  <li>15 September 2011: change from Opera CDK to Opera TV Emulator</li>
  <li>20 December 2011: clarify <code>outline</code> handling for <code>:focus</code> styles</li>
  <li>11 April 2012: clarify lack of support for <code>media="tv"</code> type</li>
  <li>25 September 2012: include note about <code>outline:none</code> support in Opera Device SDK 3.4</li>
  <li>22 January 2013: clarification on lack of support for <code>:active</code> style</li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>This guide is aimed at web developers wishing to optimize their web sites and applications for better compatibility with web-enabled/connected televisions — with a particular emphasis on the <a href="http://www.operasoftware.com/products/devices-sdk">Opera for Devices SDK</a> and its functionality.</p>

<ul>
  <li><a href="#sdk-emulator">The Opera SDK and Opera TV Emulator</a></li>
  <li><a href="#standards">Standards support on web-enabled TVs</a></li>
  <li><a href="#context-form-factor">Designing for context and form factor</a></li>
  <li><a href="#adaptive-layouts">Adaptive layouts</a>
    <ul>
      <li><a href="#fluid">Fluid layouts</a></li>
      <li><a href="#media-types">CSS2.1 Media Types</a></li>
      <li><a href="#media-queries">CSS3 Media Queries</a></li>
    </ul>
  </li>
  <li><a href="#safe-areas">Safe areas</a></li>
  <li><a href="#single-window">Single-window browsing</a></li>
  <li><a href="#scrolling">Scrolling</a></li>
  <li><a href="#text">Use of text</a></li>
  <li><a href="#graphics">Graphical elements</a></li>
  <li><a href="#colour">Colour</a></li>
  <li><a href="#ui-controls">User interfaces and controls</a>
    <ul>
      <li><a href="#spatnav">Spatial navigation</a></li>
      <li><a href="#focus">Indicating focus</a></li>
      <li><a href="#active">Indicating <code>:active</code> element</a></li>
    </ul>
  </li>
  <li><a href="#performance">Performance considerations</a>
    <ul>
      <li><a href="#processors-hw-acceleration">Processors and hardware acceleration</a></li>
      <li><a href="#javascript">JavaScript</a></li>
      <li><a href="#layering-opacity">Layering and opacity</a></li>
      <li><a href="#animations">Animations</a></li>
    </ul>
  </li>
  <li><a href="#caching-optimisation">Caching and content optimisation</a></li>
  <li><a href="#multimedia">Multimedia</a></li>
</ul>

<p>For discussions on creating web content for TV, visit our <a href="http://forums.opera.com/categories/en-opera-tv-store">Opera TV Content Development Discussions forum</a>.</p>

<h2 id="sdk-emulator">The Opera SDK and Opera TV Emulator</h2>

<p>The Opera for Devices Software Development Kit (SDK) is aimed at device manufacturers wishing to provide a customized browser and widget manager for use on their devices. It is compatible with pretty much any device that could conveniently require web access, with existing implementations ranging from web-enabled TV sets and set-top boxes to tablet PCs and connected picture frames.</p>

<p>The SDK provides building blocks, modules and example implementations. Manufacturers who choose the Opera SDK then do further integration work to hook the browser (and other components not covered in this guide, such as the widget manager) into their specific devices. As such, the SDK itself is not publicly available for download.</p>

<p>However, developers wanting to more easily test and debug their sites for delivery on web-enabled devices can use the Opera TV Emulator. Built on the same core technology as the SDK, the emulator comes as a <a href="http://virtualbox.org">VirtualBox</a> image which runs on Windows, Linux and Mac OS X. It allows for a more accurate test environment that matches the capabilities of the SDK. In addition, the Opera TV Emulator allows for remote debugging with Opera Dragonfly — a feature that is normally turned off on retail TVs and devices.</p>

<p>Download the <a href="http://www.operasoftware.com/products/tv-emulator">Opera TV Emulator</a>.</p>

<p>It’s worth noting that, even though the emulator can facilitate testing and debugging, developers should — if possible — still test their content on actual devices, as certain features and specific constraints (such as the speed of the device’s processor and available memory) can vary from device to device.</p>

<h2 id="standards">Standards support on web-enabled TVs</h2>

<p>When building web sites and applications accessed through a web-enabled TVs regular web browser, developers can take full advantage of the web standards supported by the browser on the device. For Opera’s suite of products (desktop, mobile and devices), the specific features that are supported depend on the Presto engine version running at the heart of each browser. At the time of writing, the Opera SDK deliveries are based on Presto 2.6 — the same engine found in the current desktop and mobile releases. This allows developers to take advantage of some of the latest standards:</p>

<ul>
  <li>HTML5: <code>&lt;canvas&gt;</code>, <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code>, expanded forms support (although certain features, such as the new datetime types, are implemented, but not currently optimised for keyboard/spatial navigation access)</li>
  <li>CSS3: backgrounds and borders, Web Fonts, Media Queries, transitions and 2D transforms</li>
</ul>

<p>For more details, see the list of <a href="https://www.opera.com/docs/specs/">web specifications supported in Opera</a>. Note that certain features (such as the Geolocation API and Offline Web Applications), though present in the specific Presto version, may still be disabled on certain platforms running the Opera SDK. In addition, web-enabled TVs and devices already in use will have older versions of the browser shipped as part of their firmware. Since end users can’t easily update their browser, unless it’s part of a firmware update provided by the device manufacturers, it is safe to assume that most current of these devices will be running an older browser version, and many of the latest features will not be present. Developers should employ techniques such as JavaScript feature/object detection to determine the capabilities of the user’s browser.</p>

<p>Developers can find which Presto version is present in a particular Opera browser by checking the user agent identification string in the internal <code>opera:about</code> information page. In the case of the Opera SDK, the string is currently:</p>

<pre><code>Opera/9.80 (Windows NT 6.0; U; en-GB) **Presto/2.6**.33 Version/10.61
</code></pre>

<h2 id="context-form-factor">Designing for context and form factor</h2>

<p>Although actual usage may vary, there are some general considerations with regards to context when talking about web content on TV.</p>

<p>Consumption of content (including web content) on TV, because of its traditional setting in the living room, is often a shared/social experience.</p>

<p>Primary activity often revolves around quick information look-up (for instance, cast and crew details for a particular movie, weather reports, TV listings) and quick access to services. Web content for TV should therefore be optimised — in terms of overall presentation, navigation and functionality — and task-focused, giving quick and clear access to all relevant features and information.</p>

<h2 id="adaptive-layouts">Adaptive layouts</h2>

<p>TVs usually run at the following resolutions:</p>

<ul>
  <li>Standard-definition television (SDTV): 720×480 (NTSC) and 720×576 (PAL), splits the display into two separate interlaced fields (243 and 288 lines, respectively).</li>
  <li>Enhanced-definition television (EDTV): 720×480 (NTSC) and 720×576 (PAL), delivered as single progressive scan images.</li>
  <li>High-definition television (HDTV): 1280×720 (also referred to as “HD Ready” or 720p, using progressive scan) and 1920×1080 (“Full HD”, in either 1080i interlaced or 1080p progressive scan variants).</li>
</ul>

<p>Most modern web-enabled TVs support 1280×720 as a minimum resolution. On TVs capable of displaying the full HD resolution of 1920×1080, 720p content is usually upscaled (although this depends on the individual device). Set-top boxes and similar web-enabled devices may be connected to standard-definition or enhanced-definition TV sets — in these situations they will usually downscale and letterbox their virtual resolution to fit the physical resolution of the TV screen.</p>

<p>Regardless of what type of TV set they’re connected to, some web-enabled devices may run at a variety of virtual resolutions — as an example, the Nintendo Wii Internet Channel (which uses a custom version of the Opera desktop browser) has a virtual width of 800 pixels, with the height varying based on the type of TV (4:3 or 16:9 aspect ratio) and user settings.</p>

<p>Developers targeting only web-enabled TV devices should opt to design for 1280×720 as a minimum, or provide separate versions of their content optimised for 1280×720 and 1920×1080.</p>

<p>If content should also be displayed on standard-definition and advanced-definition TVs, developers could potentially create an additional version optimised for this resolution as well.</p>

<p>However, a more sustainable and maintainable solution would be to ensure that content — and specifically the screen layout — is built with enough flexibility to adapt to a variety of screen resolutions.</p>

<p>There are a few technologies that can be employed for these types of adaptive layouts:</p>

<h3 id="fluid">Fluid layouts</h3>

<p>Using percentage-based values to define the width and height of layout containers. This can further be combined with <code>max-width</code>, <code>min-width</code>, <code>max-height</code> and <code>min-height</code> in pixel values, to provide some upper and lower limits to the fluidity of the containers.</p>

<h3 id="media-types">CSS2.1 Media Types</h3>

<p>CSS2.1 allows for the definition of styling blocks that only apply to specific classes of device. This technique is most commonly used to provide separate styling for screen and print, negating the need for creating separate printer-friendly pages. CSS2.1 also allows the definition of styles specifically for TVs.</p>

<p>Whether or not a web-enabled device identifies itself as a TV depends on how its browser has been set up and integrated by the manufacturer, so developers should only use this method if they’re sure their target platform has this setting enabled. For reasons of compatibility with the majority of web content “in the wild” which assumes a <code>media="screen"</code> device, practically all current-generation devices ignore <code>media="tv"</code>.</p>

<p>CSS2.1 Media Types can be specified when linking to separate external stylesheets:</p>

<pre><code>&lt;link rel="stylesheet" media="screen" href="…"&gt;
&lt;link rel="stylesheet" media="tv" href="…"&gt;
</code></pre>

<p>or within a single stylesheet, by defining separate <code>@media</code> sections:</p>

<pre><code>@media screen { /* styles for normal on-screen presentation */ }
@media tv { /* tv specific styles */ }
</code></pre>

<h3 id="media-queries">CSS3 Media Queries</h3>

<p>While CSS2.1 Media Types classify devices into very broad categories (<code>screen</code>, <code>print</code>, <code>tv</code>, etc.), and rely on devices actually identifying themselves as such, CSS3 extends this concept by allowing developers to define specific conditions under which styles should be applied, providing far more granular control over how a layout is to be rendered under different conditions. For example, it is possible to create layouts that change depending on various factors, including the device’s screen width, screen height, resolution and color depth.</p>

<p>CSS3 Media Queries, just like CSS2.1 Media Types, can be defined as part of the <code>&lt;link&gt;</code> elements:</p>

<pre><code>&lt;link rel="stylesheet" media="screen and (min-width: 1920px)" href="…"&gt;
&lt;link rel="stylesheet" media="screen and (min-width: 1280px) and (min-width: 1920px)" href="…"&gt;
&lt;link rel="stylesheet" media="screen and (max-width: 1280px)" href="…"&gt;
</code></pre>

<p>or using <code>@media</code> sections in the stylesheet:</p>

<pre><code>@media screen and (min-width: 1920px) { /* Full-HD styles */ }
@media screen and (min-width: 1280px) and (max-width: 1920px) { /* HD-Ready styles */ }
@media screen and (max-width: 1280px) { /* smaller than HD-Ready styles * }
</code></pre>

<h2 id="safe-areas">Safe areas</h2>

<p>Traditionally, TV sets were not able to display the full width and height of their nominal resolution, resulting in content positioned in the edges of the screen to be cut off or not displayed at all. Although this problem has been mitigated or – on some high end devices – resolved on modern digital TV sets, developers are still advised to only place important content and controls in the “safe area”, leaving a margin of approximately 5% along each edge of the viewport.</p>

<h2 id="single-window">Single-window browsing</h2>

<p>Although some devices will include the ability for browsers to open separate tabs, together with an interface for end users to switch between them, the large majority of web-enabled TVs will only run in single-window mode. Any calls to open a new window (be it through JavaScript, or simpler techniques such as providing a <code>target</code> attribute on links) will only affect the current window. Developers need to be particularly aware of this if their sites and applications currently use separate windows to provide contextual help or in more complex situations (such as web-based email clients) where child windows use JavaScript to communicate back to their parent windows in order to keep state or provide the bulk of commonly-used functions. In these cases, web applications will need to be reworked to only use a single window.</p>

<h2 id="scrolling">Scrolling</h2>

<p>Ideally, developers should aim to present all content contained within their TV-optimised sites and applications on the screen, without the need for the user to scroll. If this is not possible, content should at least fit the width of the screen, requiring the user to just scroll vertically.</p>

<p>Using iframes or containers styled with <code>overflow: auto;</code> will work as expected in the Opera SDK, and users will be able to scroll these — as well as the entire page, if needed — using the default spatial navigation method of their web-enabled device. However, it may be more user-friendly to create customised controls and interface elements (such as content carousels) instead of relying on the browser’s default scrollbar mechanism.</p>

<h2 id="text">Use of text</h2>

<p>Although TVs run at resolutions that are comparable to desktop and notebook devices, users are traditionally positioned further away from the screen (typically a few meters). It’s important to keep this in mind when deciding on the size of text and graphical elements.</p>

<p>To increase the readability of text on a TV screen, developers should:</p>

<ul>
  <li>Choose an appropriately large font size. The exact dimensions will vary depending on the specific typeface used, the physical size of the screen and the virtual resolution the device runs under, but a general minimum size of around 22px is advised</li>
  <li>Keep overall line length to around 10 words or less</li>
  <li>Use generous leading/line-spacing</li>
</ul>

<p>The number of fonts available on devices is usually limited — much more so than on desktop computers. Typically, only widely available Linux fonts such as Bitstream Vera (serif, sans-serif and monospaced) are present. End users are not able to install any fonts beyond those that came pre-installed with their device. However, the Opera SDK browser offers support for CSS3 web fonts (including fonts served through third-party services like Typekit or the Google Font API).</p>

<h2 id="graphics">Graphical elements</h2>

<p>For graphical elements, it is best to make the design bold and “chunky”, particularly for interface elements such as buttons. Overly fine detail such as single pixel borders should be avoided, as these can be particularly problematic on devices running on interlaced resolutions (such as SDTV and 1080i). This does not mean that subtlety and texture should be avoided altogether, but distinguishing features need to be clearly visible even when viewed at a distance.</p>

<p>When combining graphical elements with adaptive layout techniques, it may be useful to employ Scalable Vector Graphics (SVG), which can be resized and transformed without distortion or pixelation. However, complex SVG elements (involving a large number of vectors and layered, semi-transparent sections) do require more processing power to calculate and render, so their usefulness needs to be balanced against their performance impact.</p>

<h2 id="colour">Colour</h2>

<p>Certain colour combinations can be problematic when displayed on a TV screen. Even on high-end devices pure white, orange and red, as well as extreme contrasts, can lead to distortion and interference of the image and should be avoided.</p>

<p>In addition, the dynamic range of TV screens may not be the same as traditional computer monitors. Subtle gradients and low contrast colours may result in colour bands or indistinguishable combinations.</p>

<h2 id="ui-controls">User interfaces and controls</h2>

<p>TVs are “low interaction” devices. When designing interfaces, developers should ensure that they are clear and uncluttered, and that controls are pared down to the minimum necessary.</p>

<p>User interaction with a web-enabled TV is usually performed via a remote control. In addition to the regular number/channel keys, these remote controls feature directional/cursor buttons, OK/confirmation buttons, and a variety of special feature keys.</p>

<p>Devices will also provide users with a way to enter regular text — for instance, to fill in username/password fields in a login dialog or to enter keywords in a search field — by means of an on-screen keyboard or multi-tap interface. This is similar to traditional mobile phones, where a series of characters is mapped to a single key — ABC on the 1 key, DEF on the 2 key, and so on. However, these text entry methods are often slow and cumbersome for users. Applications should avoid or minimise the need for this kind of text entry, opting instead for alternatives such as selectable drop-downs, menus, checkboxes or custom-built scrollable interfaces.</p>

<p>Some devices may offer the option of providing an on-screen pointer, which is moved with the cursor keys or motion sensors in the remote control, as is the case on the Nintendo Wii. On-screen controls should generally be large, with ample padding, to provide a large hit area that facilitates user activation without the need for too much accuracy in moving the pointer.</p>

<h3 id="spatnav">Spatial navigation</h3>

<p>As is the case on desktop, the Opera browser uses spatial navigation. While on the desktop this mode requires the use of SHIFT+cursor keys, on TV spatial navigation is mapped directly to the directional keys on the remote.</p>

<p>The most common interaction method is functionally equivalent to keyboard access on desktop/notebook devices. Therefore, designers should ensure that their content is keyboard accessible.</p>

<p>Traditionally, only certain types of element — links, form elements, image map areas, etc. — are keyboard focusable. It is good practice (from an accessibility point of view) to use these elements for controls, rather than simply attaching JavaScript behaviours to other/generic elements, as these are then usually not focusable and usable via the keyboard alone.</p>

<p>In addition, Opera’s spatial navigation mode features built-in heuristics that allow the focus to also be placed on any element that has a <code>click</code> or <code>mouseover</code> JavaScript handler, either in an <code>onclick</code> or <code>onmouseover</code> attribute, or hooked into the element via the <code>addEventListener</code> method. In addition, spatial navigation also allows elements with a <code>tabindex</code> attribute (with a value of 0 or above) to receive focus.</p>

<p>Note that for these non-traditional elements, spatial navigation mimics mouse behaviour, meaning that only <code>mouseover</code> and <code>mouseout</code> events are automatically fired when moving to/from these elements. <code>focus</code> and <code>blur</code> events are still only fired on elements that can receive traditional keyboard focus.</p>

<p>Although spatial navigation works “out-of-the-box” in most situations, developers can take further control over the order in which elements receive focus using the <a href="http://www.w3.org/TR/css3-ui/#nav-dir">CSS3 Basic User Interface specification for directional focus navigation</a>. See our separate article on <a href="https://dev.opera.com/articles/view/tweaking-spatial-navigation-for-tv-browsing/">Tweaking spatial navigation for TV browsing</a> for more details.</p>

<h3 id="focus">Indicating focus</h3>

<p>By default, Opera will place an outline around the element that currently has focus. If the design of the specific content does require it, though, this standard outline can be partially suppressed.</p>

<p>The appearance of this outline can vary between devices, as manufacturers can re-skin the default styles applied to the focus indicators and the various elements of a web page. Developers should therefore test their sites on a variety of devices, or ensure that their styles explicitly set all necessary values rather than relying on defaults.</p>

<p>In Opera Device SDK versions prior to 3.4, suppressing the outline with <code>outline:none</code> is ignored, as this particular rule has traditionally been (ab)used on a variety of common <code>reset.css</code> stylesheets, without authors providing any alternative indications of focus.</p>

<p>Starting with the Opera Device SDK 3.4, it’s possible to suppress the outline using a simple:</p>

<pre><code>:focus { outline: none; }
</code></pre>

<p>However, for backwards compatibility with older Opera Device SDK versions, developers should still use the slightly longer syntax to suppress Opera’s default outline indicator:</p>

<pre><code>:focus { outline: 0 solid; }
</code></pre>

<p>Developers will still need to ensure that there is a sufficiently clear alternative way of indicating to the user where their current focus on screen is, such as setting a contrasting background colour on control elements instead. For example:</p>

<pre><code>:focus { **background: #f00;** outline: 0 solid; }
</code></pre>

<p>Developers using specific styles for <code>:hover</code> should — as with generic keyboard accessibility considerations — also consider doubling-up these style rules for the more generic <code>:focus</code> state (note that this still requires the elements to be focusable in the first place).</p>

<p>Instead of just using something like</p>

<pre><code>a:hover { /* styles applied when hovering over a link */ }
</code></pre>

<p>the style selector should be modified to also cover <code>:focus</code>, like so:</p>

<pre><code>a:focus, a:hover { /* styles apply to hovering AND keyboard/spatial navigation focus */ }
</code></pre>

<h3 id="active">Indicating <code>:active</code> element</h3>

<p>As is common across all browsers at the time of writing, keyboard navigation (including Opera’s spatial navigation, as used in the Opera Devices SDK) does not trigger any <code>:active</code> styles that may be defined. For this reason, additional style rules such as</p>

<pre><code>a:active { /* styles applied when a link has been activated */ }
</code></pre>

<p>will not have any effect. If your application relies on giving the user feedback when a particular element (such as a link or button) has been activated, this will need to be “faked” with something like</p>

<pre><code>a.active, a:active { /* styles applied when a link has been activated */ }
</code></pre>

<p>and the use of additional JavaScript that sets/unsets the <code>.active</code> class on the <code>click</code> event.</p>

<h2 id="performance">Performance considerations</h2>

<h3 id="processors-hw-acceleration">Processors and hardware acceleration</h3>

<p>Typical web-enabled TV sets have modest hardware specifications compared to desktop computers. The main processor power of a TV comes somewhere between high-end smart phones and low end laptops.</p>

<p>By default the Opera SDK just uses the main processor for all operations, including visual compositing through the Vega graphics library (which is also responsible for advanced CSS3 visual effects such as box shadows, text shadows, transforms and transitions), SVG rendering, and JavaScript processing through the Carakan engine.</p>

<p>The main processor is also used for software-based blitting of the rendered page to the screen itself.</p>

<p>TVs often come with specialised chipsets that can provide hardware acceleration for “expensive” operations such as decoding of video streams. Whether or not the browser running on a TV set takes advantage of these chipsets will depend on the specific device, as it’s a step usually taken by the manufacturers during the integration stage of the SDK. On recent TV sets, the most commonly accelerated feature is the blitting stage, through standardised DirectFB and OpenGL libraries.</p>

<p>It is possible to accelerate most processor intensive features of the Opera SDK — including Vega and Carakan itself — but in general developers should not rely on any particular feature being hardware-accelerated, and instead be mindful of the processing power on web-enabled TVs being comparatively modest.</p>

<h3 id="javascript">JavaScript</h3>

<p>Because of the comparatively low spec processors found on most common TVs, developers should avoid overly heavy and complex JavaScript. For general visual/GUI effects such as carousels, slideshows and expanding/contracting boxes, custom-written and optimised scripts are usually preferable to large multi-purpose frameworks. Also, in light of cache restrictions and content optimisation, it is recommended to use “lazy loading” techniques to only call scripts when needed.</p>

<h3 id="layering-opacity">Layering and opacity</h3>

<p>The act of displaying images on a webpage (blitting images onto the viewport) is generally hardware-accelerated on most devices. However, complex layouts — for example with overlapping, semi-transparent graphics and layered blocks with reduced opacity that blend together — require large amounts of additional processing power to calculate the actual value of each pixel that needs to be displayed on screen. These can adversely impact overall performance of pages — particularly scrolling and animations — and should be used sparingly.</p>

<h3 id="animations">Animations</h3>

<p>One of the strengths of many JavaScript frameworks is the ability to easily script complex visual effects and animations.</p>

<p>However, if these are simply “eye candy” effects — often given in response to a user interaction — that are simply triggered and don’t require frame-accurate control, it is worth considering the use of new CSS3 capabilities such as transitions and transforms. As these are executed by the Vega graphics library, they should generally perform better than generic solutions using JavaScript, which typically use intervals and timers to explicitly change certain values — like colour, position, dimension — in discrete steps.</p>

<p>Generally however, such effects should be kept to a minimum, as any form of animation can be expensive in terms of performance, potentially rendering sites and applications slow and unresponsive.</p>

<h2 id="caching-optimisation">Caching and content optimisation</h2>

<p>Most web-enabled TVs don’t have a hard drive or solid state drive to cache web content (although some DVRs will, these are generally used to record videos, and are not generally available for use by the browser). In these circumstances the browser will run in diskless mode, using only the available RAM to cache any downloaded web content.</p>

<p>The amount of memory available for caching can vary from device to device, but is generally in the region of 5-10MB.</p>

<p>Because of this fairly low limit on the available cache, it is not safe to assume that any assets are cached when moving from one page of site to the next, or on return visits. This also applies to cookies, which may not be stored after a user has left a particular website — although they should be safe to use to store information during a single visit. Web-enabled TV and device download speeds, however, are usually close to regular broadband speeds, so not having a cache that persists for return visits may not be a huge issue. Nonetheless, developers should aim to optimise all their content — graphics, multimedia files, and even HTML, CSS and JavaScript files — as much as possible, to ensure that they don’t hit the cache limit.</p>

<p>In addition to this regular cache, browsers on devices will also have a fairly limited amount of memory available to store the decoded pages — the browser’s internal representation of a web page, which includes assets such as the DOM, JavaScript objects, and all uncompressed images. Once the limit for the decoded pages’ memory has been reached, the browser will generally stop rendering and loading the current page until the cache is freed again. How this happens is up to individual manufacturers — for instance, users may be alerted through a pop-up that loading has stopped and that the browser is unable to continue rendering the page. After confirmation, the page and its associated cache can then be purged. For this reason, developers should be careful when using large numbers of images and JavaScript resources, as this can potentially cause out-of-memory issues on lower-end devices.</p>

<h2 id="multimedia">Multimedia</h2>

<p>Starting with Presto 2.5, Opera comes with built-in support for the HTML5 <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code> elements, allowing developers to include multimedia content in their web sites without plugins. However, the specifics of which codecs are supported on devices can vary considerably, as this depends on the underlying platform and integration work carried out by device manufacturers. Current devices are often optimised for hardware-accelerated playback of MP4/H.264 content in the <code>&lt;video&gt;</code> element. Other codecs (such as MPEG2 for video or MP3 for audio) may be available, but this cannot be guaranteed on all web-enabled TVs.</p>

<p>Certain TVs allow for the use of Adobe Flash or <a href="http://www.adobe.com/devnet/devices/flashlite.html">Adobe Flash Lite</a> content — for instance the latter is available to the Opera browser on the Nintendo Wii. Others may come with integrated support for displaying audio/video files delivered through an <code>&lt;object&gt;</code> element. Once again though, this cannot be relied on as it’s an integration feature. Consumers cannot install plugin technologies and codecs themselves, and such plugins are updated regularly, meaning potential compatibility issues with future content that relies on new features.</p>

<p>This guide only gives a generic overview of content on TV. If you are developing for environments like the Opera TV Store, please consult the specific articles relating to those products, as there will be further restrictions and requirements with regards to visual design, layout and multimedia codec availability.</p>
]]></content></entry></feed>