This is only a partial answer, as I'm currently stuck on this, as well.
If the files are already in FLV format, then the Static::Simple plugin will work just fine. I've tested it with a file in the root/static/ directory and with the $c->serve_static_file
method. Below is my jwplayer setup (wrapped in JQuery's ready function.
<script type="text/javascript" src="[% c.uri_for('/static/js/mediaplayer-5.10') %]/jwplayer.js"></script>
<script type="text/javascript">
$(function() {
jwplayer('mediaplayer').setup({
'flashplayer': "[% c.uri_for('/static/js/mediaplayer-5.10/player.swf') %]",
'id': 'playerID',
'width': '480',
'height': '270',
'file': "[% c.uri_for('/download') %]/dump/ffs/root/static/transcode_jEfhmk.flv"
});
});
</script>
If the file is in another format, you'll need to transcode it. The following is my current attempt. It transcodes it just fine and you can even stream the file to a download, but I'm having trouble getting jwplayer to play from the transcoded stream.
use IPC::Open3;
#path comes in as /flv/path/to/file.avi
sub index :Path :Args {
my ( $self, $c, @path ) = @_;
@path = grep($_ ne '..', @path);
my $path = join('/',@path);
my $abs_path = $c->config->{'serve_dir'} . '/';
$abs_path .= join("/", @path);
if (-r $abs_path){
my ($stdin, $stdout, $stderr, $pid);
#avconv
# -i input_file
# -b:v video bitrate
# -s video size
# -r video framerate
# -an no audio (having trouble with the audio settings)
# -f format
# pipe:1 send transcoded video to STDOUT
$pid = open3($stdin, $stdout, $stderr, "avconv -i \"$abs_path\" -b:v 600k -s 320x240 -r 25 -f flv -an pipe:1");
$c->response->content_type("video/x-flv");
$c->response->header('Content-Disposition' => "filename=transcode.flv");
my $chunk_size = 1048576;
do {
read( $stdout, my $buffer, $chunk_size );
$c->write( $buffer );
} while (kill(0, $pid)); #loop while transcoding process is alive
}
}
To add pseudo-streaming, you'll need to make a controller that looks for the start query parameter, then seek to it, and send the $c->response->body
to the file handle.
open(my $fh, "<", $path);
binmode($fh);
if ($c->req->param('start')){
seek($fh, $c->req->param('start'), 0);
}
$c->response->body($fh);
One caveat: the video must have the key frames in the metadata for jwplayer to be able to seek.
From jwplayer's HTTP streaming page:
Note: Some FLV encoders do not include seekpoints metadata when encoding videos.
Without this data, HTTP Pseudostreaming will not work. If you suspect your videos to not have metadata, use our Metaviewer plugin to inspect the video. There should be a seekpoints or keyframes list. If it is not there, use the FLVMDI tool to parse your FLV videos and inject this metadata.