Kiosk mode for videofe 1

One of the first apps to be developed for the PiBox Media Center was VideoFE.  This app provides an interface for users to select a video to play from a list of videos read from a database and also wraps the hardware accelerated omxplayer.  The UI is klunky in the current version.  It’s just a simple GTK+ list.  But moving up and down the list will display a poster for videos (or a poster for a TV series and a screen shot from the specific episode) along with a description.  Posters and video metadata are read from a JSON database collected from and using the VideoLib Java desktop application.

VidoeFE was the main reason for the media center implementation.  My wife and I wanted to have some night time entertainment while camping in our small trailer.  The side of the trailer was just the right size for projecting a video inside the attached enclosed tent/awning. So I wrote VideoFE as the app for selecting and playing videos.  Hooking a handheld pico-projector to the Raspberry Pi handled the projection issue. We could then have drive-in movie night while camping without seriously annoying the neighbors at the campsite.

Kiosk Mode Extension

VideoFE works fine for the use case for which it was designed.  But the passing of my oldest dog in February gave me a reason to extend it’s use cases by one: a digital photo frame.  One feature of the photo frame is playing videos.  I needed an app that would play any and all videos found and continue to play them in a loop until stopped by the user.  I also needed to integrate touchscreen support to allow skipping videos or navigating back and forth in the playing video.  Stepping back from this use case it seems the general purpose here is a kiosk mode:  play videos (or images) until interrupted.

Since the photo frame use case needs to play videos it seemed like a variation of VideoFE, but with no user interaction for choosing which video to play.  VideoFE works by reading all VideoLib generated databases from a directory tree, normally found on USB mounted media sticks.  The databases are found under a dbtop directory, which is configurable, that specifies where the USB stick mount points reside.  Searching for database files is by filename and extension.  The JSON data is parsed and kept in memory since there isn’t that much of it per video and there aren’t likely to be 10’s-of-thousands of videos on a couple of USB sticks.  Even if there are it still won’t take up that much memory.

In kiosk mode there would be no databases.  Videos are simply dropped on a USB stick in one of a number of formats (omxplayer supports a variety of file formats via ffmpeg).  So the search just needs to change to look for specific file types.  For simplicity, the types are specified by filename extension.  Omxplayer will simply not play any files with proper extensions that aren’t really video files.  VideoFE would simply reap the omxplayer child and then start it again on the next file in its list of filenames.

Setting the file types is already supported by VideoFE.  A config file can be made that specifies which file types are supported by a given player.  VideoFE is designed to work with players other than omxplayer so it could, for example, be used on the desktop.  However, for kiosk mode on the Raspberry Pi the default configuration used by VideoFE is sufficient.

In the end kiosk mode just does two things.  The first is to remove the video selection UI.  The first video is started as soon as the list of videos is generated.  The second change is a tie in to the new touchscreen support in libpibox.  The latter is also peripheral to the use case.  The FAVI keyboard is still supported and will work whether the touchscreen is in use or not.

With these two features integrated kiosk mode can be enabled by simply using the -k option to the videofe command.

Controlling Video Playback

The digital photo frame use case has a requirement to allow users to jump forward and back in a video.  Movement to the next or previous video is handled by VideoFE’s touchscreen support by simply killing the current child process of omxplayer and starting a new one.  But moving back and forth in the current video stream requires sending navigation commands to omxplayer directly.

Omxplayer provides support for external control through the use of a FIFO.  If omxplayer is started with standard input directed from a file then omxplayer uses that as the FIFO. The program will then accept any commands sent through that FIFO.  VideoFE starts omxplayer with standard input redirection.  When a touchscreen event is caught for navigating forward or backward in the video, VideoFE opens the FIFO and submits the command.  Generally there is a short delay before the command is processed by omxplayer but this delay is outside the scope of VideoFE.

    char    right_arrow[3] = {0x1b, 0x5b, 0x44};

    write(fifo_fd, right_arrow, 3);
    sprintf(buf, "p");
    write(fifo_fd, buf, 1);
    write(fifo_fd, buf, 1);

In this case a three byte sequence is sent to the FIFO followed by the character p twice.  The latter seemed to be required to force omxplayer to actually change file position.  It’s unclear at this point if that is the correct solution, but it works.  The characters to send are based on the official key bindings and a discussion on how to use the FIFO in a shell script.  A similar sequence is used for fast forward

    char    left_arrow[3] = {0x1b, 0x5b, 0x43};

    write(fifo_fd, left_arrow, 3);
    sprintf(buf, "p");
    write(fifo_fd, buf, 1);
    write(fifo_fd, buf, 1);

Still a Problem

The original VideoFE playback via omxplayer requires launching an xterm that then runs omxplayer.  This is done so that the xterm will send the proper notification when omxplayer exits that causes the X display to get redrawn.  Since omxplayer and both write to the framebuffer (and in this case the same framebuffer) the latter must be told to do a screen refresh after omxplayer is done munging the buffer.  The xterm is also used to clear the buffer to black before omxplayer starts to render what might be only a partial framebuffer update.

But even using xterm as a handler for omxplayer isn’t enough as doesn’t actually do the screen refresh xterm tells it to do.  In order to get to really do the update VideoFE has to switch virtual terminals (aka VTs) once to an empty VT and then back to where is being displayed.  Then an X refresh has to be issued manually.  Only then do we get back to a visible managed display.

All of this finagling to get the framebuffer updated causes noticeable blinking of the display.  It’s not clean by any means.  But I’ve not found any other way to make it all work.  So for now, the technique stays.  This includes under the new kiosk mode because even though VideoFE has no components (there is no UI to select videos in kiosk mode) we still need it to do all this so will show the launcher properly once VideoFe exits.

Future Work

I have plans to give VideoFE a much nicer UI for selecting videos in non-kiosk mode.  Now that I have a much better grasp of using gdk_pixbuf and Cairo it shouldn’t be difficult to implement a carousal of posters and descriptions.  But kiosk mode has no need for this.  The only possible updates may be to order videos using a prescribed naming scheme or to allow blending from one video into the next.  But the latter will only happen after fixing the vt-switching problem.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

One thought on “Kiosk mode for videofe