Skip to content

Instantly share code, notes, and snippets.

@oojikoo-gist
Created June 3, 2016 06:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oojikoo-gist/e1566f295580981813ce5142f0e94594 to your computer and use it in GitHub Desktop.
Save oojikoo-gist/e1566f295580981813ce5142f0e94594 to your computer and use it in GitHub Desktop.
rails: video
# Hey Everyone -
# I've been doing some googling here and wanted to ask if anyone's done this before - streamed flash video (*.flv) via Ruby?
# Basically, I'm doing some R&D on a possible future project to use RoR for the site/db access, and Flash to stream video. Thing is, the user needs to be authorized for the video, and it needs to be streamed so it isn't cached on the client-end (for copyright protection purposes - yeah I hate it too, but gotta do it).
# I've seen one tutorial using Ming to do that, but I'd prefer something that has a separate server-side application, and separate client-side application built in Flash, so I have more control over the look and feel of the application, as well as can embed other interesting things in there if I want.
# I've taken a look at Red5 (http://osflash.org/red5), but seeing as it's in Java, I'm not too keen on working with it.
# Part of the reason I want to do this in Ruby is obviously so I can work with it through Rails, -and- so I can use Ruby to fetch videos from Amazon S3. That's where I'd like to store them (privately of course), then use ruby to fetch the video and re-stream the data to the Flash player.
# Complex, I know. Anyone have any thoughts on if this has been done, and if not, how it might be accomplished?
# Thanks wink
#
# OK, after some more research and a few tweaks, I've made a simple (very simple) ruby script work inside the rails environment.
# Here's the existing code:
#
#
class StreamController < ApplicationController
def index
# Open the FLV.
@file = File.open(File.join(RAILS_ROOT, "flv", "golfers.flv"))
# Binary
@bin = @file.read
# Send data.
send_data (@bin, :type => 'application/x-flv', :filename => 'golfers.flv', :disposition => 'attachment')
end
end
# Basically, going to http://localhost:3000/stream will give you the video.
# (Note for cut&paste: YMMV. This is a quick test hack to see if the concept is viable, you -will- have to change that code.)
# My FLA code:
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
tvid.attachVideo(ns);
ns.setBufferTime(2);
statusID = setInterval(videoStatus, 200);
ns.onStatus = function(info) {
trace(info.code);
if(info.code == "NetStream.Buffer.Full") {
bufferClip._visible = false;
ending = false;
clearInterval( statusID );
statusID = setInterval(videoStatus, 200);
}
if(info.code == "NetStream.Buffer.Empty") {
if ( !ending ) {
bufferClip._visible = true;
}
}
if(info.code == "NetStream.Play.Stop") {
bufferClip._visible = false;
//ending = true;
}
if(info.code == "NetStream.Play.Start") {
ending = false;
}
if(info.code == "NetStream.Buffer.Flush") {
ending = true;
}
}
//Play it
ns.play("http://localhost:3000/stream");
# Basically all that does is look at the instance on the first frame (only frame) of
# the move called "tvid" which is an instance of a Video object, and attach a NetStream to it, then plays the video called from this area.
# Now as far as I can tell, when Flash Player uses NetStream to play a video,
# it does NOT cache it client side. I don't know whether or not it's RTMP dependent - can anyone shed some light on this?
# I haven't implemented seeking capability yet, or a scrubber.
# That's a bit more complex than I'm able to do right now. Luckily I've found a PHP version from www.flashcomguru.com. Here's the code:
<?
/*/
security improved by by TRUI
www.trui.net
Originally posted at www.flashcomguru.com
//*/
//full path to dir with video.
$path = 'C:/.../clips/';
$seekat = $_GET["position"];
$filename = htmlspecialchars($_GET["file"]);
$ext=strrchr($filename, ".");
$file = $path . $filename;
if((file_exists($file)) && ($ext==".flv") && (strlen($filename)>2) && (!eregi(basename($_SERVER['PHP_SELF']), $filename)) && (ereg('^[^./][^/]*$', $filename)))
{
header("Content-Type: video/x-flv");
if($seekat != 0) {
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
$fh = fopen($file, "rb");
fseek($fh, $seekat);
while (!feof($fh)) {
print (fread($fh, filesize($file)));
}
fclose($fh);
}
else
{
print("ERORR: The file does not exist"); }
?>
# Now what's interesting here is how they handle a seek. The scrubber in the included FLA sends an http GET request to the script,
# which looks for an integer (as a percentage of the total length of the video, I guess), and in turn, the script returns - apparently -
# that part of the video. That's what I'm having a hard time with, is how this pack() function works.
# Now I know Ruby has a pack() method, as part of the Array class. What I'm not sure how to do is get a "Ruby equivalent" of this PHP script - a full port, if you will.
# Any Ruby pros wanna help me out here?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment