Created
June 3, 2016 06:13
-
-
Save oojikoo-gist/e1566f295580981813ce5142f0e94594 to your computer and use it in GitHub Desktop.
rails: video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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