A question regarding the embedding of SWF content came up on the Ruby on Rails mailing list. In this instance, the problem was related to the tags used to embed a SWF in Internet Explorer and Mozilla browsers. Internet Explorer requires an <object> tag, while Mozilla (and most other) browsers require an <embed> tag.
Further to that, the ridiculous EOLAS patent requires changes in the way that objects are embedded in web browsers. One of the effects of this is that Internet Explorer users must now click a plugin in order to activate it (which is a problem for SWF files, especially if they are used in navigation, since two clicks are required to navigate).
There is a workaround, however, in the form of the extremely lightweight SWFObject javascript library. It is very easy to use, and actually I prefer this method of embedding SWF files since:
- There is no need to deal with
<embed>or<object>tags at all. It’s all handled for you behind the scenes. - Cross browser embedding is implied; the exact same code embeds a SWF in any browser automagically.
- Passing parameters to a SWF is trivial.
- Supplying alternative content for browsers without the Flash Player is trivial.
- Embedding with SWFObject bypasses issues caused by the ridiculous EOLAS patent.
Because of these issues, SWFObject has quickly become the de-facto standard for embedding SWF files.
I was in the process of replying to the mailing list, but I figured it would be more useful to write up a blog post for everyone. So here is a short tutorial on embedding SWF content in Ruby on Rails using the SWFObject library.
- Download the zip file from the SWFObject homepage (direct link here)
- Extract the contents of the zip file anywhere on your machine, and copy
swfobject.jsto#{RAILS_ROOT}/public/javascripts - Include
swfobject.jsin the head of your layout file using:
<%= javascript_include_tag 'swfobject' %>
- Copy your SWF file(s) to
#{RAILS_ROOT}/public/swf - Include the following code in the body of the template file in which you wish to embed the SWF content:
<div id="flashcontent">
<strong>You need to upgrade your Flash Player</strong>
This is replaced by the Flash content.
Place your alternate content here and users without the
Flash plugin or with Javascript turned off will see this.
Content here allows you to leave out <code>noscript</code>
tags.
</div>
<script type="text/javascript">
// <![CDATA[
// path_to_swf, swf_id, width, height, fp_version, bgcolor
var so = new SWFObject(
"/swf/my_swf.swf", "my_swf", "320", "240", "9", "#FFF"
);
// An example parameter passed to the SWF file
so.addVariable("my_var", "my_var_value");
// This is where the magic happens
so.write("flashcontent");
// ]]>
</script>And that’s all there is to it. More information is available on the SWFObject homepage :-)
UPDATE: Meekish kindly posted a comment pointing out a plugin for Ruby on Rails that provides a flashobject_tag to use directly in your views. More info here. Thanks Meekish!
UPDATE: I know I’m a little behind here, but it appears that the EOLAS patent infringement case against Microsoft has been resolved. According to WikiPedia:
Microsoft and Eolas agreed in July 2007 to delay a pending re-trial, in order to negotiate a settlement. On August 27, 2007, Eolas reported to its shareholders that a settlement had been reached, and that Eolas expected to pay a substantial dividend as a result; the exact amount and terms of the settlement were not disclosed.
Also it appears that EOLAS will (probably) offers free licenses for open source browsers, so FireFox will more than be unaffected. I’m not sure how Safari stands, since the browser itself is not open source – but the web browser component itself (WebKit) is.
All said however, SWFObject is still a useful and hassle free method of hosting SWF in a browser independent fashion and continues to be a useful tool.
UPDATE: Marc-Andre has very kindly pointed out in the comments:
Just to let you know that SWFObject is now at version 2.1 and has moved to http://code.google.com/p/swfobject/
I’ve upgraded the flashobject plugin to use this new version of SWFObject and made it more “rails-like” with swf acting like other assets. It’s all on github: http://github.com/marcandre/swf_fu
I’ve updated the post to reflect this, thanks!
Nice. Unlike every other example on the web this one actually worked for me!
This was exactly what I needed. If only all the web was this useful!
Thanks.
Glad I can be of assistance :-)
Or in pure Ruby, if that suits your fancy: http://agilewebdevelopment.com/plugins/flashobject
Very cool, I’ll add that to the article. Thanks Meekish!
Hey.
Been checking out your past works. You are great in flash! Kudos!
Hi. If I would like to protect the Flash (swf) files from unregistered users? Any ideas how that could be done ? Not talking about the authentication/authorization part, but how could I render SWF files or something like that instead of having them in public directory ?
thanks.
Hi Stewie,
Take a look at the send_file function in your controller, which will obscure the true location of your SWF. This function will send the data in chunks of 4096 bytes, so it’s pretty efficient to use for these purposes.
Then all you need do is point your SWFObject to /path/to/controller/action (e.g. /media/swf?file=foo.swf) and job done :-)
More info here: http://www.rubyinside.com/railstips/tag/send_file
Hi
i use in view
and how to rest of the parameter
my file location is
http://122.169.104.164:3002/video_screenshots/logo.flv”
how to show that in the view
Thanks
amit Agarwal
Hi Amit,
To display a FLV file you will need to either embed it or play it dynamically via a SWF. You can’t serve a FLV file directly to the browser and have it play the movie, unless the user has a media player such as VLC installed that can read it.
If it’s just a simple playback you need, try giving the VideoPlayback component a whirl in Flex, or pick up one of the various FLV players on the ‘net, or simply build your own :-)
I cannot get this to work at all. I have read through the google page and blog completely. The page just sits there and stares at me…. no flash playback. (The div never gets the flash player loaded into it).
I am hosting at bluehost.com, but that shouldn’t matter. I placed all the files where there articles say to… (so far after 6 months of intense development at bluehost, everything else tends to work as RoR standards indicate it should.)
I even tried using the (longer) swfobject.js in the src subdirectory. No use.
Here is my reduced-to-its-simplest web page
http://me2you.client-express.com/mtyuser/tpl0
in case you want to see the trivial code behind it. I have verified the da_player.swf file is in
#{RAILS_ROOT}/public/swf and permissions look okay…
Any ideas?
@dave
I just checked your site, and it appears that your SWF isn’t actually accessible. I did a ‘view source’ on your page, took the URL for your SWF you are passing to SWFObject (‘da_player.swf’) and then requested that directly in the browser (http://me2you.client-express.com/mtyuser/da_player.swf).
In fact, the error suggests that you’re using send_file to serve the SWF, but you’re looking in the wrong place for it (I’m pretty sure /da_player.swf isn’t correct on your local filesystem). Try instead passing “#{RAILS_ROOT}/public/da_player.swf” and see if that works :-)
You helped me get it working, but it isn’t working quite the right way: Your clue about direct access to the SWF file led me to getting that located and working, but in order to do that I have to insert a default route in the routes.rb as:
map.connect “*anything”,:controller => “mtyuser”, :action => “swf_handler”
then in the controller I put an action:
def swf_handler
p = params[:anything]
if p[1] == “da_player.swf”
send_file(“#{RAILS_ROOT}/public/swf/da_player.swf”);
end
end
to serve out the swf file.
AND it only works with the standard Flash script (Adobe’s AC_RunActiveContent.js), not the swfobject advocated on this site. I still cannot get that to work yet. I think it cannot find the videoplayer skin.
I will spend more time on this, but for right now wanted to get you a reply status and a big thanks for getting me past that hump.
Hi Cliff
Thanks for the blog post. I’m pretty new to this and have run into trouble. I took your code and just added the name of my swf file where you had:
“/swf/my_swf.swf”, “my_swf”
I have my flash file in the swf directory under public. Is there something I’m missing.
Thanks for your help!
Steve
@dave Interesting, if I recall correctly the video player component looks in the same directory as its owning swf for the player skins. You may need to add a rule/route to handle the player skin too – or perhaps add one for *.swf and re-route all flash content. Check your browser and/or server logs to see where the swf expects to find the skins. Let me know if and how you fixed this and I’ll update the article to include it :-)
@Steve I’ll need a little more information than this to be of any help :-)
This is really simple and very good. Thanks a lot!!!
tx a lot. U saved my day ! and nit too ;)
Hey man :D
I keep on reading this page each time I have to work with Rails and swfs (yeah, work is interesting these days :)
I wanted to ask you if this could work in partials?
TY
OK, sorry for double posting, I’m impatient as usual, it works, you’re the man :p
Good page. Just to let you know that SWFObject is now at version 2.1 and has moved to http://code.google.com/p/swfobject/
I’ve upgraded the flashobject plugin to use this new version of SWFObject and made it more “rails-like” with swf acting like other assets. It’s all on github: http://github.com/marcandre/swf_fu
Thanks!
hi, i got a prob while running the swf i got an error=> SWF OBJECT UNDEFINED…
can anyone tell me how to rectify it..
i’m new to Ruby on Rails
Cliff, this is just what I am looking for but am having problems. I am new to flash and rails that I am working with. I followed your steps – when I run I get the alternative message displayed rather than a flash screen. I do have flash installed.
As an aside I also tried using the swf_fu plugin but that is not working either. A very frustrating afternoon.
@John, sorry about the delay in responding. Are you still having this problem?