Creating Flash Video Object on Silverstripe

Last Update : 31/03/2010 7:31am
assets/Uploads/_resampled/SetWidth250-adobe-flash-video-flv-icon.png

One time ago, I was ever asked to do a web project in which there is a web page containing the video look like on youtube. The video file should be able to upload by their self. Later after the video uploaded, it have to be converted automatically to the .flv format which is will be displayed in the browser.

Actually, there is extension provided by Silverstripe to manage video called Youtube Gallery. But this extension provides only features to take videos from youtube. While my client wants to manage their own videos without using youtube or other video sharing website. For that, I tried to make an object FlashVideo to accommodate a request from my client.

Requirements

1. FFMPEG

FFMPEG is an opensource application that can be used to record, convert and stream audio and video. FFMPEG application is required to be used to convert uploaded video results from the user. These applications can be downloaded for free from http://ffmpeg.org/. If you use a hosting server, ask your admin to install this application.

After downloading and installing on a computer that is used by silverstripe. You must know the path of ffmpeg binary file. If on my computer ffmpeg file is located in /usr/local/bin/ffmpeg. We must make sure ffmpeg run by running the command /usr/local/bin/ffmpeg on the console (microsoft windows in command prompt). Usually output looks like:

bash-3.2# /usr/local/bin/ffmpeg
FFmpeg version SVN-r17910, Copyright (c) 2000-2009 Fabrice Bellard, et al.
configuration: --enable-libmp3lame --enable-shared --disable-mmx
libavutil 50. 0. 0 / 50. 0. 0
libavcodec 52.21. 0 / 52.21. 0
libavformat 52.31. 1 / 52.31. 1
libavdevice 52. 1. 0 / 52. 1. 0
libswscale 0. 7. 1 / 0. 7. 1
built on Mar 10 2009 22:33:58, gcc: 4.0.1 (Apple Inc. build 5465)
At least one output file must be specified

If no error message means that ffmpeg is installed correctly.

2. FLV Player

We need a flv player to play the video on the web. In general, you can use any flv player. How to get it quite easily, search in google search engine with keywords "flv player" or "flash video player". I myself use the JW Player which can be downloaded for free at http://www.longtailvideo.com/players/jw-flv-player/. Flv player files will be .swf as a flash file.

FlashVideo Object

If you've installed ffmpeg and download flv player then we are ready to begin making the FlashVideo object on Silverstripe.

First of all, create a directory called FlashVideo in the main directory of silvertripe. Inside the FlashVideo directory, create two directories named code and swf, so the directory structure will look like in the picture below.

Directory Structure

The purpose of creating this directory is to separate the FlashVideo object and its components  from the main directory of our website (mysite) directory. However, we could actually make the object in the FlashVideo mysite directory, because its structure is same.

After making FlashVideo directory, copy the .swf files of flv player that you have downloaded in the swf directory. Flash video player file  that I use is called player.swf, this file name will be used in viewing the FlashVideo file.

Create a file called _config.php in FlashVideo/code/ directory  with the following contents:

FlashVideo/_config.php

<?php 
define('FFMPEG_BIN',"/usr/local/bin/ffmpeg");
$dir = "video";

/*
Don't change these code bellow if you dont know what you're doing!!
*/
define('VIDEO_PATH', ASSETS_PATH."/".$dir);
define("VIDEO_DIR", ASSETS_DIR."/".$dir);

if (!file_exists(VIDEO_PATH)){
@mkdir(VIDEO_PATH);
@mkdir(VIDEO_PATH."/_resampled");
@mkdir(VIDEO_PATH."/_thumbnail");
}
?>

_config.php configuration File which will FlashVideo use later. Silverstripe MVC will read the _config.php file first before processing the other FlashVideo files in the directory. In this file there is constants named FFMPEG_BIN used to inform the location of the application binary FFMPEG file. Then there is the definition of $dir= "videos", where $dir is the name of the directory to save the file processing results. This directory ($dir) will be located in the directory assets, so for our flv files can be managed easily through the Files & Images on silverstripe admin page.

After creating the file _config.php, next is create a FlashVideo.php file that is placed on FlashVideo/code/ directory. The contents of FlashVideo.php are as follows:

FlashVideo/code/FlashVideo.php

<?php
/*
Flash Video Model File for uploading Video Files and convert it to flv extension
By Firnas Nadirman
*/
class FlashVideo extends File {

public static $thumbnail_width = 114;

public static $thumbnail_height = 87;

public static $cms_thumbnail_width = 100;

public static $cms_thumbnail_height = 60;

public $allowedExtensions = array("mov","mp4","avi","flv","mpeg","mpg");

public $flvplayer = "FlashVideo/swf/player.swf";

function getOriginalFileURL() {
return Director::baseURL() . $this->FileName;
}

function getURL() {
if (!file_exists($this->getFlvFilePath())){
$this->generateFlv();
}

return Director::baseURL().$this->getFlvFileName();
}

function URL() {
return $this->getURL();
}

function forTemplate(){
if(!file_exists($this->getCMSThumbFilePath())) {
$this->getThumbnail($this->stat("cms_thumbnail_width"), $this->stat("cms_thumbnail_height"), $this->getCMSThumbFilePath());
}
return "<embed width=\"400\" height=\"300\" flashvars=\"file=".$this->getURL()."&amp;image=".$this->getCMSThumbFileName()."\" allowscriptaccess=\"always\" allowfullscreen=\"true\" quality=\"high\" bgcolor=\"#FFFFFF\" name=\"player\" id=\"player\" style=\"\" src=\"$this->flvplayer\" type=\"application/x-shockwave-flash\">";
}

function getThumbFileName(){
return VIDEO_DIR."/_thumbnail/thumb_".strtolower($this->Name).".png";
}

function getThumbFilePath(){
return VIDEO_PATH."/_thumbnail/thumb_".strtolower($this->Name).".png";
}

function getCMSThumbFileName(){
return VIDEO_DIR."/_thumbnail/CMSthumb_".strtolower($this->Name).".png";
}

function getCMSThumbFilePath(){
return VIDEO_PATH."/_thumbnail/CMSthumb_".strtolower($this->Name).".png";
}

public function CMSThumbnail() {
return $this->generateCMSThumbnail();
}

public function getImage() {
return $this->generateThumbnail();
}

function generateThumbnail(){
if(!file_exists($this->getThumbFilePath())) {
$this->getThumbnail($this->stat("thumbnail_width"), $this->stat("thumbnail_height"), $this->getThumbFilePath());
}
return "<img src=\"".$this->getThumbFileName()."\" title=\"".$this->Title."\">";
}

function generateCMSThumbnail() {
if(!file_exists($this->getCMSThumbFilePath())) {
$this->getThumbnail($this->stat("cms_thumbnail_width"), $this->stat("cms_thumbnail_height"), $this->getCMSThumbFilePath());
}

return "<div style=\"text-align:center;width: 100px;\"><a target=\"_blank\" href=\"$this->URL\" title=\"Download: $this->URL\"><img src=\"".$this->getCMSThumbFileName()."\" alt=\"".$this->getCMSThumbFileName()."\" /></a><br /><br /><a style=\"color: #0074C6;\"target=\"_blank\" href=\"$this->URL\" title=\"Download: $this->URL\">Download</a></div>";
}

function getThumbnail($width, $height, $filedest){
$videoFile = BASE_PATH."/".$this->Filename;
if(file_exists($videoFile)){
$execthumb = FFMPEG_BIN." -i ".$videoFile." -r 1 -s ".$width."x".$height." -f image2pipe -vframes 1 -ss 00:00:01 ".$filedest;
exec($execthumb);
}
}

function getFlvFileName(){
return VIDEO_DIR."/_resampled/"."flv_".strtolower($this->Name).".flv";
}

function getFlvFilePath(){
return VIDEO_PATH."/_resampled/flv_".strtolower($this->Name).".flv";
}

function generateFlv(){
$videoFile = BASE_PATH."/".$this->Filename;
$execvid = FFMPEG_BIN." -i ".$videoFile." -r 16 -ar 11025 -ab 32k -s cga -qscale 10 -y ".$this->getFlvFilePath();
exec($execvid);
}

}
?>

FlashVideo.php contains objects FlashVideo. This object is derived from the File object, so  this object has all the attributes and methods that are owned by the File object. In this FlashVideo object there are several variables used to configure the FlashVideo files:

  • $thumbnail_width, this variable is used to determine the width of the thumbnail images of video.
  • $thumbnail_height, this variable is used to determine the height of the thumbnail images of video.
  • $cms_thumbnail_width, this variable is used to determine the width of the thumbnail images of video on the admin page.
  • $cms_thumbnail_width, this variable is used to determine the height of the thumbnail image of video on the admin page.
  • $allowedExtensions, this variable contains an array of file extension to be uploaded. You can add other file extensions on these variables.
  • $flvplayer, this variable contains the relative path to the flv file player from silverstripe  directory.

If you've made a second file, then run the command db/build/?flush=1 on silvertripe url to add FlashVideo objects into the silverstripe database structure. Later this object we can use on our pages.

Using FlashVideo Object

To use the FlashVideo object on silverstripe page, we can add a fields type FlashVideo like adding fields of type Image. If in the previous post in ArticlePage.php, we can add the following code:

    public static $has_one = array(
'Picture' => 'Image',
'Video' => 'FlashVideo'
);

We can use FileIFrameField for uploading video files on getCMSFields() method.

    function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Content.Main', new CalendarDateField('Date'), 'Content');
$fields->addFieldToTab("Root.Content.Main", new ImageField('Picture'));
$fields->addFieldToTab("Root.Content.Main", new FileIFrameField('Video'));

return $fields;
}

FlashVideo Upload

For our templates call variable of FlashVideo type ($Video) and placed on ArticlePage.ss as we want.

<h2>$Title</h2>

$Picture
$Video
$Content
$Form
$PageComments

Do not forget to do the command db/build/?flush=1. After that will appear flv player on ArticlePage which will contain uploaded video.

Page with Flv Player

You can download the source code files of the above FlashVideo objects here.

Post your comment

Comments

Sami Kamal said...

this is exactly what I needed, and it works! thank you so much..
Now I need to show the thumbnail images of all availabe videos in a video page holder which I created. What's the right variable to use in my VideoPage.ss ?
thanks

Gordon said...

About to implement this exact thing. This is a helpful reference. Thanks for sharing!

RSS feed for comments on this page | RSS feed for all comments