Tuesday 25 February 2014

Extend GNOME Videos with Lua

As you've probably seen in my previous post, the new Videos UI has part of its interface focused on various channels from online sources, such as the Blip.tv, or videos from the Guardian.

Grilo recently grew support for Lua sources, which means you can write about 100 lines of lua, and integrate videos from an online source into Videos easily.

The support isn't restricted to videos, GNOME Music and GNOME Photos and a number of other applications will also be able to use this to be extended.

Small tutorial by example

Our example is that of a source that would fetch the list of Ogg Theora streams from Xiph.org's streaming directory.

First, define the "source": the name is what will show up in the interface, supported_keys lists the metadata fields that we'll be filling in for each media item, and supported_media mentions we only show videos, so the source can be skipped in music players.


source = { 
  id = 'grl-xiph-example',
  name = 'Xiph Example',
  supported_keys = { 'id', 'title', 'url', 'type' },
  supported_media = 'video',
}

We'll then implement one of the source methods, to browse/list items in that source. First, we cheat a bit and tell the caller that we don't have any more items if you need to skip some. This is usual for sources with few items as the front-end is unlikely to list items 2 by 2. If that's not the case, we fetch the page on the Xiph website and wait for the callback in fetch_cb


function grl_source_browse(media_id)
  if grl.get_options("skip") > 0 then
    grl.callback()
  else
    grl.fetch('http://dir.xiph.org/by_format/Ogg_Theora', 'fetch_cb')
  end
end

Here's the meat of the script, where we parse the web page into media items. Lua doesn't use regular expressions, but patterns. They're different, and I find them easier to grasp. Remember that the minus sign/dash is a reserved character, '%' is the escape character, and '()' enclose the match.

We create a new table called for each one of the streams in the HTML we scraped, with the metadata we said we'd give in the source definition, and send it back to Grilo. The '-1' there is the number of items remaining in the list.

Finally, we call grl.callback() without any arguments to tell it we're done fetching the items.


function fetch_cb(results)
  if not results then
    grl.callback()
  end 

  for stream in results:gmatch('<p class="stream%-name">(.-)</p>') do
    media = {}
    media.url = stream:match('href="(.-)" ')
    media.id = media.url
    media['type'] = 'video'
    media.title = stream:match('<a href.->(.-)</a>')

    grl.callback(media, -1) 
  end 

  grl.callback()
end

We're done! You just need to drop this file in ~/.local/share/grilo-plugins/grl-lua-factory, and you can launch Videos or the test application grilo-test-ui-0.2 to see your source in action.



Why Lua?

This screen scraping is what Lua is good at, with its powerful yet simple pattern matching. Lua is also easily embeddable, with very few built-in functions which means we can have better control over the API plugins use, a low foot-print, and all the benefits of an interpreted garbage-collected language.

I hear heckles of "Javascript" in the background, so I guess I better address those as well. I think Lua's pattern matching is better than Javascript regexes, and more importantly, Lua is more easily embeddable in big applications, because of its simplicity as a language and a VM. Basically, Javascript (and the gjs implementation we'd likely have used in particular) is too powerful for our use case.

Better sources

It's obviously possible to avoid this screen scraping when the online source provides data in an easily parseable format (such as Json for which we have Lua bindings). That will be the case of the Guardian videos source (once we've figured out a minor niggle with the 50 items query limit) thanks to the Guardian's Open Data work.

Hopefully it means that we'll have sources for the Wiki Commons Picture of the day (as requested by GNOME alumni Luis Villa) for use in the Background settings, or for Mediagoblin installations.

Videos sidenote

An aside, for those of you who have videos on a separate network storage, or not indexed by Tracker, there's a hidden configuration to show specific paths in the Channels tab in Videos.

gsettings set org.gnome.totem filesystem-paths "['smb://myserver.local/videos/']"

Epilogue

I'm looking forward to seeing more Grilo sources. I feel that this Lua source lowers the barrier to entry, enabling the evening hacker to integrate their favourite media source into GNOME, which probably means that we'll need to think about parental controls soon! ;)

Thanks to Victor Toso for his work on Lua sources, both during and after the Summer of Code, and Juan Suarez for his mentoring and patch reviewing.

Wednesday 5 February 2014

Videos is here!

It's been some time in the making, with the redesign work started a couple of release cycles ago, but we finally reached a state where it's usable, and leaps and bounds easier to use than the previous versions.

I should note that I use Totem and Videos interchangeably, Totem is still the name of the project, code repository, but the user-visible name is Videos (or GNOME Videos if differentiation is necessary).

Discovery

The old UI made it particularly hard to consume media from various web sites, as you can see from the screenshot below. It's cramped, we had separate sidebars for search and browse, we didn't show icons for browse, etc.


And here's the new UI, browsing the same source (Apple Trailers).


This is definitely easier to find media. Totem also had a number of specific plugins to find media sources, usually from third-party developers. We don't support those anymore, and if you have been writing such a plugin, you should port them to grilo, now a hard-dependency.

I've also spent some time working on Grilo and its plugins, creating a few new sources along the process.


Amongst the new ones are the Freebox TV plugin, the under-powered Guardian Videos source, and the not-yet-fully-integrated Pocket videos list. Don't forget to check for blocker bugs if you're trying to test those!

Playback

This is also a pretty big upgrade. We now have video-specific menu item, the gear menu, and better looking pop-ups. This matches the design used in GNOME Documents for sliders. It's also better suited for touch: a mouse move will show the OSD for a short time, but a touchscreen tap will show the OSD until you tap it again.


The older version had some features only available in windowed, such as rotation, or zoom, and some we tried to cram into the context menu (subtitle or sound track selection for example). Here, there's no loss of accessibility for features, they're all in the same gear menu, whether fullscreen or windowed.

Bugs, bugs, bugs

With a few valiant testers and designers, we tried to fix a number of bugs. This release doesn't mean Videos is bug-free, far from it, but it's certainly robust and usable enough to make this development release.

There's some theming bugs, as can be seen in that last screenshot's previous/next buttons, there's bugs in grilo and grilo-plugins, and there's bugs in Videos itself.

Do file bugs when you see something amiss, it'll help designers and myself move items from our own TODO lists :)

What's next

A lot :)
You can see some of those in the design wireframes.

"Make available offline" is something I have a great interest in, especially coupled with the Pocket source. Selecting a bunch of items to watch later, on the train, or on the plane.

Better metadata, especially for films and series. This isn't just for films you snarfed from Usenet and torrent sites either. The already existing Rai.tv source has a number of films, and a BBC iPlayer source is planned.

Finally, remote playback, to "throw" videos from your laptop to the TV. Controls should still work, and we'll want to allow browsing through sources when playback is remote.

Notes on development

Half notes, half thanks. As mentioned in the introduction, this release has been some time in the making, but it also comes at a time when we've had the necessary plumbing to make all this possible.

To name but a few, we've made good use of gnome-documents' widgets to list videos, the GtkStack, GtkRevealer and GtkPopover. The GtkSearchBar and GtkSearchEntry widgets are also examples of widgets that moved to GTK+ for Videos' development.

Getting it

Soon in your development distributions, in totem's master git branch, and in GNOME's FTP server.