Configure an MRSS feed (such as iTunes) with Fire App Builder
If you have an iTunes MRSS feed, which follows a formal specification used for services such as iTunes, you can follow an example configuration to simplify the setup. The sample MRSS feed in Fire App Builder uses a feed for a This Week in Tech (TWIT) podcast called Ham Nation, whose feed is publicly available here.
- MRSS Configuration Overview
- Demo: Configure Fire App Builder with the TWIT Feed
- Configure Fire App Builder with Your Own MRSS Feed
MRSS Configuration Overview
If your feed contains the same elements as the example iTunes feed, your setup can be as simple as swapping in your own feed URL and using the existing TWIT category and content recipes.
However, iTunes MRSS feeds have a variety of potential elements. In the sample TWIT feed, the content elements in the feed are matched through an XPath query with the query
and matchList
parameters in the categories recipe contents recipe. You might need to adjust some of this query syntax if your MRSS feed differs from the sample TwitTV MRSS feed. More details are provided in the steps that follow.
url
in your feed element cannot point to a source on YouTube, Vimeo, or Dropbox. Your videos need to be on a host that allows your app to access the media directly. Additionally, your app must match on all of the elements listed in the previous code sample. For example, you cannot omit one of the elements (such as the url
). Otherwise your build will fail.Demo: Configure Fire App Builder with the TWIT Feed
Before swapping in your own MRSS feed into the sample TWIT configuration, let's build Fire App Builder using the TWIT feed to get a sense of how it looks and works. To configure Fire App Builder to use the TWIT feed:
-
Open BasicFileBasedUrlGeneratorConfig.json (in your app's assets > configurations folder). Change the value for the
url_file
property totwitTvUrlFile.json
:{ "url_file": "twitTvUrlFile.json" }
-
Press Shift twice to open the Search Everywhere dialog box, and type Navigator.java to locate this file. Change the NAVIGATOR_FILE field's value to
Navigator_TwitTv.json
:public static final String NAVIGATOR_FILE = "Navigator_TwitTv.json";
This tells Fire App Builder to use this particular navigator file rather than the default (Navigator.json).
-
Click the Run App button . (If you need help running your app on a Fire TV device, see Connect to Fire TV Through ADB.)
The TWIT feed populates in Fire App Builder and looks somewhat as follows:
Configure Fire App Builder with Your Own MRSS Feed
To configure Fire App Builder with your own MRSS feed, essentially you just swap it in place of the TWIT feed and make sure the same elements match in your recipes. You can also rename some files so they reflect your own feed rather than saying "Twit."
-
Before configuring your app, make sure your iTunes MRSS actually validates. Go to Cast Feed Validator and ensure your feed is valid. Beyond validating, your feed must also have the following elements to satisfy Fire App Builder's minimum requirements:
title
guid
itunes:subtitle
media:content url
media:thumbnail url
You can see the sample TWIT feed as an example for these elements in context. These elements will map to the
mTitle
,mId
,mDescription
,mUrl
,mCardImageUrl
, andmBackgroundImageUrl
model elements in the Fire TV UI. If your valid iTunes feed doesn't have these elements, you can later adjust the category recipe and contents recipe to target similar elements. More detail is provided in the steps that follow. -
Duplicate the twitTvUrlFile.json file (in your app's assets folder) and give the copy a unique name, such as AcmeUrlFile.json.
Tip: To duplicate a file, you can either right-click the file name and choose Refactor > Copy, or just highlight the file and use Cmd + C to copy and Cmd + V to paste (on Windows, Ctrl instead of Cmd). -
Open your "AcmeUrlFile.json" file and replace the URL with your own iTunes MRSS feed URL:
{ "urls": [ "http://acmewebsite.come/myfeed.xml" ] }
-
Open BasicFileBasedUrlGeneratorConfig.json (in your app's assets > configurations folder). Change the value for the
url_file
to the name of the file you created in the previous step (e.g., "AcmeUrlFile.json").{ "url_file": "AcmeUrlFile.json" }
-
Press Shift twice to open the Search Everywhere dialog box, and type Navigator.java to locate this file. Change the NAVIGATOR_FILE field's value to a unique name, such as
Navigator_acmemedia.json
:public static final String NAVIGATOR_FILE = "Navigator_acmemedia.json";
This tells Fire App Builder to use this particular Navigator file rather than the default (Navigator.json).
-
Duplicate the Navigator.json file (located in app > assets) and give the new file the same name you used in the previous step (e.g., Navigator_acmemedia.json).
-
Open the Navigator_acmemedia.json file (or whatever you named it in the previous step). The default
globalRecipes
code has a special hard-coded category with content processed by a different recipe. This section is highlighted in red below. Remove this section."globalRecipes": [ { "categories": { "dataLoader": "recipes/LightCastDataLoaderRecipe1.json", "dynamicParser": "recipes/LightCastCategoriesRecipe.json" }, "contents": { "dataLoader": "recipes/LightCastDataLoaderRecipe1.json", "dynamicParser": "recipes/LightCastContentsRecipe.json" } }, { "categories": { "name": "Hardcoded Category Name" }, "contents": { "dataLoader": "recipes/LightCastDataLoaderRecipe1.json", "dynamicParser": "recipes/LightCastAllContentsRecipe.json" } } ]
Your
globalRecipes
object should look as follows:"globalRecipes": [ { "categories": { "dataLoader": "recipes/TwitTvDataLoaderRecipe0.json", "dynamicParser": "recipes/TwitTvCategoriesRecipe.json" }, "contents": { "dataLoader": "recipes/TwitTvDataLoaderRecipe0.json", "dynamicParser": "recipes/TwitTvContentsRecipe.json" } } ]
-
In the same Navigator_acmemedia.json file, change the "TwitTv" names in the following files to reflect your own project's name:
- TwitTvDataLoaderRecipe0.json
- TwitTvCategoriesRecipe.json
- TwitTvContentsRecipe.json
For example, if your app were named AcmeMedia, you might rename these JSON files as follows:
"globalRecipes": [ { "categories": { "dataLoader": "recipes/AcmeMediaDataLoaderRecipe0.json", "dynamicParser": "recipes/AcmeMediaCategoriesRecipe.json" }, "contents": { "dataLoader": "recipes/AcmeMediaDataLoaderRecipe0.json", "dynamicParser": "recipes/AcmeMediaContentsRecipe.json" } } ]
- Now, in the Android Studio left pane that lists the files, either duplicate or rename the TwitTvDataLoaderRecipe0.json, TwitTvContentsRecipe.json, and TwitTvCategoriesRecipe.json files (located in app > assets > recipes) to match the names you customized in the previous step.
- Open the AcmeMediaCategoriesRecipe.json file (or whatever you renamed it) and make sure that the query targeting the categories will work for your feed:
- Go to the XPath Tester.
- Paste in your XML feed into the XML Input box. Be sure to remove the text at the top that says "This XML file does not appear to have any style information …." Also, escape any
&
characters (which are illegal in XML) by changing them to&
. - In your AcmeMediaCategoriesRecipe.json file, copy the
query
value (//item/category/text()
) into the XPath Expression field in the XPath Tester. (Don't include the quotation marks.) -
Click Test XPATH. If you see a result such as what's shown in the following code sample, you're all set because the
query
correctly identifies the categories in your feed.Text='Technology' Text='Ham Radio' Text='Technology' Text='Ham Radio' Text='Technology' Text='Ham Radio'
If the query doesn't correctly select your categories, you'll need to adjust your query syntax to select your feed.
Targeting Elements with Namespaces
If you're trying to target an element with a namespace, such as<media:category>
, you can't simply update the query syntax to//item/media:category/text()
. This is because Fire App Builder's XML Parser doesn't support namespaces directly in the XPath expressions. Instead, you would use//*[name()='media:category']/text()
. For more details, see the "Targeting Elements with Namespaces" section in the XML tab in Step 7: Contents Recipe: Query Parameters.
For more details on creating XPath queries in general, see Step 4: Categories Recipe: Query Parameters. For more on XPath query syntax, see XPath Syntax or other online resources.
- Open the AcmeMediaContentsRecipe.json file (or whatever you named this file) and make sure that the query syntax targeting the contents will work for your feed:
- From the previous step, your feed should already be in XPath Tester.
- In your AcmeMediaContentRecipe.json file, copy the
query
value (//item[./category='$$par0$$']
) into the XPath Expression field in the XPath Tester. (Don't include the quotation marks.) - Because XPath won't understand the
$$par0$$
variable (which is specific to Fire App Builder and not standard XPath syntax), substitute in one of your category names instead. For example,//item[./category='Lifestyle']
. -
Click Test XPATH. If you see a result containing your items such what's shown in the following code sample, you're all set because the
query
syntax correctly identifies the contents in your feed's items.Element='<item> <title>HN 361: Tonight: Hams Young and Old</title> <itunes:title xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">Tonight: Hams Young and Old</itunes:title> <itunes:episodeType xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">full</itunes:episodeType> <pubDate>Wed, 01 Aug 2018 21:36:19 PDT</pubDate> <itunes:episode xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">361</itunes:episode> <link>https://twit.tv/shows/ham-nation/episodes/361</link> <comments>https://twit.tv/shows/ham-nation/episodes/361</comments> <itunes:author xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">TWiT</itunes:author> <category>Technology</category> <category>Ham Radio</category> <itunes:explicit xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">clean</itunes:explicit> <itunes:subtitle xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"> Don Wilbanks interviews 2018 Young Ham of the Year Bryant Rascoll KG5HVO. </itunes:subtitle> <itunes:keywords xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"> Ham Radio, arrl, young ham of the year, ham holiday </itunes:keywords> <description> ...
If the query doesn't correctly select your categories, you'll need to adjust the query recipe to match your feed. See Step 7: Contents Recipe: Query Parameters for details.
-
Now look at the AcmeMediaContentsRecipe.json file (or whatever you named this file) again and examine the
matchList
parameter. By default, thematchList
parameter looks like this:"matchList": [ "title/#text@mTitle", "guid/#text@mId", "itunes:subtitle/#text@mDescription", "media:content/#attributes/url@mUrl", "media:content/media:thumbnail/#attributes/url@mCardImageUrl", "media:content/media:thumbnail/#attributes/url@mBackgroundImageUrl" ]
The syntax in the
matchList
parameter doesn't use XPath expressions, but it's similar. Here's how thismatchList
syntax works.matchList
starts with the result returned from thequery
parameter — in this case, the items in your feed. Thus, you don't need to use XPath syntax to target your items.On the left of the ampersand (
@
) you put the property you want to target (for example,title
). On the right of the ampersand (@
), you put the Fire App Builder model element you want to map the element to (for example,mTitle
).Special Notes about Mapping Syntax with the matchList Parameter
Note that the syntax in thismatchList
parameter uses some special techniques for targeting text, attributes, and CDATA elements:
— To capture text inside an element, use#text
. (See "Targeting Text" on the XML tab on Step 8: Contents Recipe: Matchlist Parameters for more info.)
— To capture attributes specified in an element, use#attributes
. (See "Targeting Text" on the XML tab on Step 8: Contents Recipe: Matchlist Parameters for more info.)
— To capture text inside aCDATA
element, use#cdata-section
. (See "Targeting Text" on the XML tab on Step 8: Contents Recipe: Matchlist Parameters for more info.)
— More details about these special selectors and other matching requirements are provided in Step 8: Contents Recipe: Matchlist Parameters.</li></ul>Make sure that all the elements on the left of the
@
appear in your feed's items (specifically, in the result returned from your Contents recipe query —//item[./category='Lifestyle']
). You should have at least the following elements in your items:title
,guid
,itunes:subtitle
,media:content
withurl
attribute, andmedia:content/media:thumbnail
withurl
attribute. If these items don't exist or are named differently, fix the mapping here before going to the next step.Important: As noted earlier, theurl
in your feed element cannot point to a source on YouTube, Vimeo, or Dropbox. Your videos need to be on a host that allows your app to access the media directly, using a file extension (e.g., .mp4) and not requiring special authentication.
- Click the Run App button . (If you need help running your app on a Fire TV device, see Connect to Fire TV Through ADB.)
If successful, your app should look similar to the sample TWIT Ham Nation app but with your own feed's content. The feed items are grouped into different categories based on the category
element in your feed. If the same item has multiple categories, that item will appear in each category group.
If you get a "Service Unavailable" message, Fire App Builder probably had trouble parsing your feed and mapping it to the UI. Check to see that all elements targeted in your category recipe and contents recipe are present in your feed. You might need to adjust the syntax a bit to target the right elements.
To identify the error, expand the Logcat tab at the bottom of Android Studio and filter on "Error." Look for a reason for the failure in the messages (such as "The provided query string is not valid for the given xml.")
For information on how to change the look and feel of the app, including how to change the logo, see Change the App Logo, Icon, and Splash Screen.