Streaming Video

There are a ton of video modules available for Drupal. I've downloaded most of them at one time or another.

And sadly - none of them is perfect.

We have an Adobe Flash Streaming Server that we are attempting to use for all our online videos. This streaming server is not the same as the web server on which we're hosting Drupal.

Almost every video module assumes that you will be uploading video files through the Drupal interface. And hardly any of them support streaming video.

At first, I worked with the 'Embedded Media Field' module. It supports 3rd party videos. The intended audience seems to be folks who have uploaded video to Youtube and other similar services and who want to embed that video in their Drupal sites without having to use HTML. If your provider isn't already supported, (like if you have your own streaming server), you can write your own provider include file. This worked in both Drupal 5 and Drupal 6. I've used emfield with both the JW Player and Flowplayer. And I've managed to get streaming to work as well as integrating it with Swfobject_api.

However.

Emfield is enormous, and over the 6 months I waited for some of the functionality promised to develop, it never did. Also - integrating it with Flowplayer was painful and involved manually embedding js files on nodes with flash. Also - it couldn't provide the variety that we needed for the multiple sites using video without writing multiple provider files for the same streaming server.

I started looking for alternatives.

When we first started working on a video site, Drupal was in version 5, and the Flash player of choice was JW Player. The first site we released ran emfield with that player. If you wanted to change the appearance of the player, you needed to create a 'skin' (a swf file) using Flash. Since none of us was terribly familiar with how to do that, we were restricted to using the skins available for download on the JW Player site.

Flowplayer - much, much more flexible. It is a Flash player that can be configured using JavaScript and CSS. How cool is that?? It took some time to figure out how to get streaming working, and I needed to make some serious modifications to the emfield provider file I had written, but then we were using emfield + flowplayer in Drupal 6. Our next site was released using that model.

But - it still felt hackish. All our Flash files had to be in the same directory on the streaming server for the provider file to work. And all sites would have to have the same controller settings.

My eventual solution: get rid of emfield entirely.

Now, I'm using CCK, the Flowplayer module, and field-specific theming to achieve a flexible video solution.

First, I created a few new CCK fields in the content types that were going to support video: Aspect Ratio, Base URL, File Name, and Thumbnail Image. The aspect ratio would allow videos to display in either widescreen or fullscreen. Base URL was the location of the file on the streaming server (whatever server that happened to be). The File Name was the name of the flv file attached to that given node. The thumbnail image would be used as the background for the video link used by Flowplayer for embedding video. It could be set to a default image across the site using the imagefield module or specific to each given video node.

Then I downloaded the Flowplayer module and added a few additional files in the flowplayer folder: flowplayer.rtmp-3.1.0.swf and a custom play image play.png. The Flowplayer module allowed me to customize the controller color and options on a per-site basis.

These changes allowed for different sizes and ratios for videos, different flv locations, and different player appearances.

Then, I created a content field template in my base theme for the video file name field: content-field-field_video_file_name.tpl.php

Here's the code:
<?php if (!$field_empty) :
if (isset($node->field_video_base_url)) {
$flash_base_url = $node->field_video_base_url[0]['safe'];
$file = substr($items[0]['safe'], 0, -4);
$aspect_ratio = isset($node->field_video_aspect_ratio[0]['safe']) ? $node->field_video_aspect_ratio[0]['safe'] : 'Widescreen';
$background = '';
if (isset($node->field_video_link_image) && !empty($node->field_video_link_image)) {
$image_path = base_path() . $node->field_video_link_image[0]['filepath'];
$background = "background-image: url('". $image_path ."');";
}
$div_id = 'video-container-'. str_replace(array(':', '.', '/', ' '), '', strtolower(check_plain($file)));
$flowplayer = drupal_get_path('module', 'flowplayer');
if (!empty($flowplayer)) {
$flowplayer_path = base_path() . $flowplayer;
?>
<a class="flash-video-link <?php print 'video-aspect-'. strtolower(check_plain($aspect_ratio)); ?>" href="<?php print $file ?>" id="<?php print $div_id ?>" style="<?php print $background ?>">
<img src="<?php print $flowplayer_path ?>/flowplayer/play.png" alt="Play" />
</a>
<?php
flowplayer_add('#'. $div_id, array(
'clip' => array(
'autoPlay' => true,
'baseUrl' => $flash_base_url,
'provider' => 'rtmp'
),
'plugins' => array(
'rtmp' => array(
'url' => $flowplayer_path .'/flowplayer/flowplayer.rtmp-3.1.0.swf',
'netConnectionUrl' => $flash_base_url
),
)
));
}
}
else {
//Default field behavior
?>

<div class="field field-type-<?php print $field_type_css ?> field-<?php print $field_name_css ?>">

<?php if ($label_display == 'above') : ?>

<?php print t($label) ?>: 

<?php endif;?>
<div class="field-items">
<?php $count = 1;
foreach ($items as $delta => $item) :
if (!$item['empty']) : ?>
<div class="field-item <?php print ($count % 2 ? 'odd' : 'even') ?>">
<?php if ($label_display == 'inline') { ?>
<div class="field-label-inline<?php print($delta ? '' : '-first')?>">
<?php print t($label) ?>: </div>
<?php } ?>
<?php print $item['view'] ?>
</div>
<?php $count++;
endif;
endforeach;?>
</div>
</div>

<?php
}
?>
<?php endif; ?>

So - I'm using the flowplayer module supplied function flowplayer_add() to embed the video. I make sure all the fields that make up the video exist in this content type and that they aren't empty. If they don't exist, I'm using the default CCK field template code. Then, I make sure the flowplayer module exists. I build out the link to the video using the thumbnail image if it exists and pass all the video file data to the flowplayer function to build the player based on the settings chosen for that given site. I'm using CSS in the site theme to set width and height for the individual videos based on the chosen aspect ratio.