(Quick Reference)

GVPS (Grails Video Pseudo Streaming) Plugin - Reference Documentation

Authors: Ryan Vanderwerf, Peter N. Steinmetz

Version: 0.3

1 Introduction

This plugin provides facilities for converting video formats and streaming videos from a Grails application.

To do so, it provides the following primary functions:

  1. A Movie domain object to represent movies which are stored on the local file system.
  2. A tag library to display videos on a page as well as include required libraries.
  3. Controllers and views for uploading, managing, and showing movies.
  4. A VideoService to manage movie files stored on the file system, convert movie formats, and stream their contents to clients.

These functions provide a ready-to-use package for uploading and streaming videos from your Grails application.

Two video player libraries are presently supported. The JW-FLV player is used to serve content in flv files, whereas the Flowplayer is used to serve content in mp4 files.

Most video formats which are understood by the ffmpeg program can be uploaded and will be converted into the flv and mp4 formats used by the plugin to serve content.

Credits.

This plugin was originally developed as the Cantina Consulting pre-1.0 Grails Plugin, and was converted to be compatible with Grails 2 by Ryan Vanderwerf and Burt Beckwith.

2 Prerequisites

The gvps plugin uses several helper applications to perform functions such as converting videos or retrieving information about the video files.
  1. ffmpeg. This is a widely used video format conversion program which is available at ffmpeg.org. It is available in package format for most major operating systems and distributions. This program is required to convert videos using the gvps plugin.
  2. ffprobe. This program, which is normally installed along with ffmpeg, retrieves metadata, such as length, for a video file. It is required to convert videos using the gvps plugin.
  3. qt-faststart. This program is an optional install included with the source of the ffmpeg program. It is often available as a separate package. It is required if the gvps plugin will be serving MP4 files.
  4. yamdi. This program injects metadata into FLV video files. It is available at yamdi.sourceforge.net and is often available in packaged form. It is required if the gvps plugin will be serving FLV files.

The location of each of these helper programs in configured in a stanza of the BuildConfig.groovy file. See Configuration for details.

The functions of the gvps plugin can be used without these helper programs if no video file conversions will be performed by the plugin. An example would be when files are uploaded by a separate mechanism onto the server in the correct format.

3 Getting Started

This section will guide you through creating a basic application to store and stream videos. It assumes that the Prerequesites are installed on the server where the Grails application is running.

Installing the plugin.

For Grails 2.x add the following to BuildConfig.groovy:

grails.project.dependency.resolution = {
  plugins {
    compile ">>
  }
}

For earlier versions, execute install-plugin gvps.

Configuration.

The plugin is configured using a block in the Config.groovy file. Insert the following:

video {
    location = "/tmp/"  // location for storage of videos, can be on a shared drive
    yamdi {
        path = "/usr/bin/yamdi"    // FLV metadata injector (IF TYPE= FLV)
    }
    ffmpeg {
        fileExtension = "flv"  // use flv or mp4
        conversionArgs = "-b 600k -r 24 -ar 22050 -ab 96k"
        path = "/usr/bin/ffmpeg"
        makethumb = "-an -ss 00:00:03 -an -r 2 -vframes 1 -y -f mjpeg"
    }
    ffprobe {
        path = "/usr/bin/ffprobe" // finds length of movie
        params = ""
    }
    flowplayer {
        version = "3.1.2" // use empty string for no version on file
    }
    swfobject {
        version = "" // used for jw-flv player, empty to not specify version
    }
    qtfaststart {
        path = "/usr/sbin/qt-faststart" // if ffmpeg.fileExtension == mp4 used to rearrange metadata
    }
}

This may require several adjustments depending on your operating system. Be sure to set the yamdi, ffmpeg, ffprobe, and qtfaststart paths to point to the binary executables on your system. Also set the location property to a directory which you have write privileges on (the system tmp directory will normally have global write permissions).

Run the application.

At this point, you should have a basic running application which will allow creation, conversion, and viewing of videos. First run the application with grails run-app, then access the MovieController to create a video. This should then appear in the Movie List and be viewable.

4 Configuration

The operation of the gvps plugin is configured in a stanza within the Config.groovy file. The primary items to be configured are whether the plugin will work with FLV or MP4 files and the locations of the helper programs (see Prerequisites.

A sample configuration is as follows.

video {
    location = "/tmp/"  // location for storage of videos, can be on a shared drive
    yamdi {
        path = "/usr/bin/yamdi"    // FLV metadata injector (IF TYPE= FLV)
    }
    ffmpeg {
        fileExtension = "flv"  // use flv or mp4
        conversionArgs = "-b 600k -r 24 -ar 22050 -ab 96k"
        path = "/usr/bin/ffmpeg"
        makethumb = "-an -ss 00:00:03 -an -r 2 -vframes 1 -y -f mjpeg"
    }
    ffprobe {
        path = "/usr/bin/ffprobe" // finds length of movie
        params = ""
    }
    flowplayer {
        version = "3.1.2" // use empty string for no version on file
    }
    swfobject {
        version = "" // used for jw-flv player, empty to not specify version
    }
    qtfaststart {
        path = "/usr/sbin/qtfaststart" // if type == mp4 used to rearrange metadata
    }
}

5 Using Videos with Tags

The gvps plugin provides a tag library which is one of the primary methods of using the plugin after the Movie domain objects have been created. All tags for this plugin are available in the vid: namespace.

Two tags in a gsp are required to display a video. The first is the includes tag, which is placed in the <head> of the page to pull in the appropriate video player library. The specific library used is specified with the player attribute, which must be set to either 'jwflv' or 'flowplayer'. Use the 'jwflv' setting if the 'ffmpeg.fileExtension' configuration variable is set to 'flv' and the 'flowplayer' setting if 'ffmpeg.fileExtension' is set to 'mp4'.

The second tag is the display tag, which is inserted into the markup of the body to render the player object. The player attribute is again used to specify the type of player and the id or movie attribute is used to specify the video to be displayed. Additional attributes are used to specify whether to stream the video and its size.

Lastly, the convertVideoPlaytime tag is used to render video play times in readable form.

6 Using the VideoService

The gvps plugin provides a VideoService object with methods to convert and serve video files. It can be injected into a controller with a statement like def videoService.

You can stream the content for a Movie object using either the streamFlv or streamMp4 methods.

The putMovie method is used to add a new Movie to the database and the convertVideo method is used to convert the video to serve-able files on the file system. The convertNewVideo method will convert all Movies whose status 'new'.

7 Administrative Interface

The gvps plugin provides a MovieController and several views for an administrative interface to create, rename, update, and delete Movie objects.

To use this interface, access the <ctx>/MovieController URL, which should direct you to the Movie list. From here you can modify existing Movie objects or create a new one.

The show action for a Movie object shows the fields of the object as well as 5 views of the movie:

  1. A view shown with the JW-FLV player and pseudo-streaming flv content.
  2. A view shown with the JW-FLV player and downloading flv content.
  3. A view shown with Flowplayer and pseudo-streaming mp4 content.
  4. A view shown with Flowplayer and downloading mp4 content.
  5. A view shown with the JW-FLV player with captioning turned on.

8 Security

Security can provided for the the actions of the MovieController, the administrative interface, or specific Movie objects.

Securing MovieController Actions.

It is important to secure the MovieController actions as these will be available by default when the gvps plugin is installed. When using the SpringSecurity plugins, one method of doing this is to override the 'streamFlv' or 'streamMp4' actions and add an annotation:

@Secured(["isAuthenticated()"])
    def streamflv = {
			def movie = Movie.get(params.id)
			if (movie.status != Movie.STATUS_CONVERTED) return
			videoService.streamflv(params,request,response,movie)
		}

Other methods would be to secure these actions using a Map in the Config.groovy file (see Simple Map in Config.groovy) or adding RequestMap entries to the database (see Requestmap Instances Stored in the Database.

Securing the Administrative Interface.

While securing the MovieController streamFlv or streamMp4 actions will prevent viewing of video content itself, it will often be important to secure even the listings of the available videos and their metadata. Since other actions on the MovieController, such as list, edit, and show are available by default, it is also important to secure these actions.

Although overrides such as described above can be implemented with attached security annotations, the use of a Map in Config.groovy or RequestMap objects in the database may be easier for most applications.

Securing Movie Objects.

Securing access to specific Movie objects will in general require the use of access control lists. The spring-security-acl plugin plugin provides this level of fine-grained control.

9 Miscellaneous

The following are a number of additional pieces of information which may be useful to users or developers of the gvps plugin.

Conversion parameters.

The gvps plugin uses ffmpeg to perform conversion to the video formats which are used to serve video content. The parameters for the conversions are defined in the video.ffmpeg.conversionArgs setting, and are typically set as '-b 600k -r 24 -ar 22050 -ab 96k'.

The meanings of these are as follows

SettingMeaning
-b 600kset video bitrate of video to 600kbps
-r 24set framerate to 24 fps
-ar 22050audio sampling frequency rate
-ab 96kaudio bit rate

The specific values required may depend on the version of ffmpeg you have installed.

How to Help

Currently we need someone more familiar with flowplayer to upgrade the taglib to use the current version, which has changed significantly.

Other items to be improved:

  1. toggle related binary-based domain object so actual videos can be stored in DB (or no-SQL db) instead of FS
  2. toggle temp files being stored in working table in database, to avoid needing shared filesystem to process videos
  3. update html and styles on admin screens
  4. write actual unit tests
  5. convert taglibs to use gsp includes for flowplayer/jw-flv html
  6. add support for latest flowplayer versions

Sources of Additional Information

Updated slides from SpringOne2GX. https://github.com/rvanderwerf/grails-video/doc/streaming-grails-slides-v2.pdf

Source. https://github.com/rvanderwerf/grails-video

Terracotta. http://terracotta.org/downloads/open-source/catalog

Flowplayer. http://flowplayer.org/

JWPlayer. http://www.longtailvideo.com/players/jw-flv-player/

FFMpeg. http://ffmpeg.org/

Flowplayer plugins. http://code.google.com/p/flowplayer-plugins/

Contacting the Author

Via twitter: https://twitter.com/RyanVanderwerf

Google+/email: rvanderwerf@gmail.com

Blog: http://rvanderwerf.blogspot.com