question

Kelly Balthrop avatar image
Kelly Balthrop asked

Debugging Fire App Builder configuration of feed

Hopefully this time will post...

I'm getting null back instead of the value for my video url.

Our feed is located here: https://s3-us-west-2.amazonaws.com/go-vegas-videos/JSON-Media-Files/GoVegasRoku.json

The relavant part is:

    "content": {
        "dateAdded": "2018-02-14T13:21:42-08:00",
        "captions": [],
        "duration": 1623,
        "videos": [
          {
            "url": "https://d344pw8zzw9s43.cloudfront.net/specials/TheOpioidCrisis_ThePainBehindtheAddiction.mp4",
            "quality": "HD",
            "videoType": "MP4"
          }
        ]
      },

content contains the videos node which contains the url key\value pair.

My config files are :Categories

{ "cooker": "DynamicParser",

"format": "json",

"model": "com.amazon.android.model.content.ContentContainer",

"translator": "ContentContainerTranslator",

"modelType": "array",

"query": "$..tags[*]",

"queryResultType": "[]$",

"matchList": ["StringKey@mName"],

"keyDataType": "StringKey@keyDataPath"}

Content file is:

{ "cooker": "DynamicParser",

"format": "json",

"model": "com.amazon.android.model.content.Content",

"translator": "ContentTranslator",

"modelType": "array",

"query": "$.shortFormVideos[?(@.tags[0] in [$$par0$$])]",

"matchList": [

"title@mTitle","id@mId",

"shortDescription@mDescription",

"content/videos/url@mUrl",

"thumbnail@mCardImageUrl",

"thumbnail@mBackgroundImageUrl",

"content/videos/videoType@mFormat"]
}

While traversing the videos node the translator returns a null object.

Line 97 in AModelTranslator.java:

Object value = PathHelper.getValueByPath(map, fieldPath);

Returns null when looking at the videos node.

fire app builder
10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Tom@Amazon avatar image
Tom@Amazon answered

Hi Kelly, I see that this feed follows the Roku JSON spec. I'll explore this and see if I can figure out why it's returning the null value. We should really have this example in the Fire App Builder docs, so I'll work on adding more documentation details around this as well as the other updates. Just wanted to let you know that we're working on it.

10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Kelly Balthrop avatar image
Kelly Balthrop answered

Great Tom, thanks. I'm looking forward to publishing our content to FIre TV. My boss is eager to see what I've been up to.

10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Tom@Amazon avatar image
Tom@Amazon answered

I checked with engineering on the query syntax, and did some other testing. Here are the results. The easiest solution would be for you to modify your feed to remove the array brackets from the videos element. If you do this, your existing query syntax will work fine. The feed change would be as follows. Instead of this:

"videos": [
    {
      "url": "https://d344pw8zzw9s43.cloudfront.net/specials/TheOpioidCrisis_ThePainBehindtheAddiction.mp4",
      "quality": "HD",
      "videoType": "MP4"
   }
]

You would just have this:

"videos": 
    {
      "url": "https://d344pw8zzw9s43.cloudfront.net/specials/TheOpioidCrisis_ThePainBehindtheAddiction.mp4",
      "quality": "HD",
      "videoType": "MP4"
   }

Removing the array tags from videos would actually make sense because arrays are for lists of items, and within your videos element, you just have one object, not a list of objects. So there doesn't seem to be a need for an array there anyway, right?

If you make this change, then the other code should work. Your LightCastContentsRecipe.json file stays as is:

{
  "cooker": "DynamicParser",
  "format": "json",
  "model": "com.amazon.android.model.content.Content",
  "translator": "ContentTranslator",
  "modelType": "array",
  "query": "$.shortFormVideos[?(@.tags[0] in [$$par0$$])]",
  "matchList": [
    "title@mTitle",
    "id@mId",
    "shortDescription@mDescription",
    "content/videos/url@mUrl",
    "thumbnail@mCardImageUrl",
    "thumbnail@mBackgroundImageUrl",
    "content/videos/videoType@mFormat"
  ]
}

And your LightCastCategoriesRecipe.json file also stays the same:

{
  "cooker": "DynamicParser",
  "format": "json",
  "model": "com.amazon.android.model.content.ContentContainer",
  "translator": "ContentContainerTranslator",
  "modelType": "array",
  "query": "$..tags[*]",
  "queryResultType": "[]$",
  "matchList": [
    "StringKey@mName"
  ],
  "keyDataType": "StringKey@keyDataPath"
}

In the Navigator.json file, remove the following from the globalRecipes object:

   {
      "categories": {
        "name": "Hardcoded Category Name"
      },
      "contents": {
        "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
        "dynamicParser": "recipes/LightCastAllContentsRecipe.json"
      }
    }

(This code was just inserted in the sample application to make the Lightcast feed show categories properly.)

The globalRecipes object should look like this:

  "globalRecipes": [
    {
      "categories": {
        "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
        "dynamicParser": "recipes/LightCastCategoriesRecipe.json"
      },
      "contents": {
        "dataLoader": "recipes/LightCastDataLoaderRecipe1.json",
        "dynamicParser": "recipes/LightCastContentsRecipe.json"
      }
    }
  ],

Then build your app. It should build successfully. To test this, I copied your feed, reduced it down to about a dozen entries, and made the modification to the videos element. I put the feed (temporarily) here to test: https://s3-us-west-2.amazonaws.com/sample-firetv-web-app/vegasfeedmodification.json

If you are not able to modify your feed this way, then you might need to investigate other approaches. Engineering say that Fire App Builder's parsing logic runs into trouble when the videos element is an array as currently structured in your feed. Specifically, the PathHelper.getValueByPath(map, fieldPath) method runs into an error because it only knows how to follow paths in a hierarchical fashion like content/videos/url, but with the your current feed structure it would need to know how to evaluate content/videos[0]/url for a single url or content/videos[*]/url for a list of urls.

I'm not sure how you're generating your JSON feed. If it's manually configured, perhaps the update is simple to make? If it's auto-generated by your online video provider and inflexible to change, then maybe you can use an MRSS feed instead? If online video providers generate feeds, they often provide MRSS as an option. If so, you can implement MRSS in Fire App Builder following the tutorial here.

We could also submit an enhancement request to the engineering team to update the parsing logic in Fire App Builder to account for this feed structure (but that enhancement might take a while).

A question for you: Is your current feed structure generated to conform to Roku's Direct Publisher JSON feed specification? Does that specification require the videos element to contain an array like your current feed structure shows? If so, that would probably merit the change request in Fire App Builder.

By the way, one other option Amazon provides (that is more comparable to Direct Publisher) is Amazon Creator. Maybe you've already explored Amazon Creator, but if not, it provides another app development option (and much simpler). Fire App Builder requires a lot of heavy setup because of the Android Studio tooling. With Amazon Creator, you would need an MRSS feed, though. In that case, Fire App Builder would work equally well.

On another note, I've been reviewing the documentation and making some updates to some outdated code. It'll take me several more days to finish all the updates, but I'm pushing them out little by little. (Doc drift in technology is kind of inevitable without more strict and regular attention, so thanks for your feedback.)

Also, keep in mind that Fire App Builder tries to be flexible and accommodating to any JSON feed structure, which also makes the framework more complex and tricky at times. Amazon's approach is to provide this more robust, flexible framework with Fire App Builder and also a lighter, easier-to-configure tool with Amazon Creator. Both have tradeoffs.

1 comment
10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

I know this is an old thread, is there a way to leave the array brackets in there in 2020?

0 Likes 0 ·
Kelly Balthrop avatar image
Kelly Balthrop answered

Thank you Tom for an in depth and detailed answer - five stars if I could vote. Unfortunately we do not have an MRSS feed option, which is why I didn't take the easier creator path to begin with. The feed I'm using works for ROKU, and so modifying it might break that service. We have another feed we generate for Apple TV I'll take a look at, but I think it will have similar issues. The easiest fix may be to simply generate a new feed specifically for Fire TV. In any case you did an excellent job of researching the issue and providing good details. For that I'm encouraged about us developing for this platform.

10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Tom@Amazon avatar image
Tom@Amazon answered

I looked more closely at the Roku JSON feed spec for videos. As I understand it, the array is the standard format because Roku lets you provide several videos of differing qualities, and then it picks the best option for the device/bandwidth, right? I also looked at other sample Roku JSON feeds (I admit I had a hard time locating more than a few), and they all have an array for the videos element. We want to support this schema, so I filed a ticket with our engineering group to provide this capability with Fire App Builder in the next release. (Releases have a somewhat quarterly cadence.)

I also looked for feed specs for Apple TV app but couldn't find them. I'm not familiar with any feed-based app development kits for Apple TV (is there one?). I assume you have a custom-built app for that platform? At any rate, modifying your feed is the best option in part because you can also take advantage of recommendations. Take a look at the Recommendations documentation. When a user plays a video, your app can send similar content tiles to the user's home screen, which then encourages more playback and visibility for your app.

10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Pramoth avatar image
Pramoth answered

Hi ,

I was having the same problem trying to use Roku feed for FireTv. As Tom suggested , i modified the feed url to not to be inside an array ( as Roku expects).

So my json feed now has 2 video urls. The one in Roku Format and the one that will work with Firestick.

"videos":[
{"url":"xxxxxxxx",
"quality":"HD",
"videoType":"HLS"}],
"primary_video":{
"url":"xxxxxxx",
"quality":"HD",
"videoType":"HLS"}}}]

I added "primary video" attribute which is not an array object and voila it works!

The best part is , this did not break Roku.

10 |5000 characters needed characters left characters exceeded

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.