5

No doubt another silly newb question! I have a byte array in a Grails controller that contains the contents of a video file (an *.mp4 file to be exact). I am familiar with how to render JSON, XML and other basic types from a grails controller but I can't find any examples showing how to output video. In essence I want to do the following:

  render bytes as MP4

I realize that I probably need a construct such as:

  render(text:"<xml>some xml</xml>",contentType:"video/mpeg",encoding:"UTF-8")

but I'm not clear how I get the byte array in there.Obviously I am not an expert on rendering html-like content. I've been hiding behind library functions too long! Any pointers to a reference or example would be much appreciated.

So if it helps point the advice in the right direction, the bytes with the video are coming from an S3 object that I am reading with the jets3t library.

Rich Sadowsky
  • 966
  • 1
  • 12
  • 22
  • It looks like I'd be better off using the "response" object instead of the render syntax. I could still use pointers or examples. I tried it with the render syntax and got an out of memory error! So clearly I'll need to use a buffered stream of some type. – Rich Sadowsky Nov 26 '11 at 15:39
  • Do you want to embed the video or simply send the file? – Oliver Tynes Nov 27 '11 at 12:31
  • Using the response object and a context type of 'video/quicktime' I am able to get this to work when returning a QuickTime *.mov file. I'm a little unclear about what types of headers I should be sending down. Currently the only thing I am doing is setting the content type. I'm off to find either source code to a simple media server or an easy to read reference that discusses headers and video downloading. The behavior I want is "progressive download" so I don't need the complexity of a streaming protocol. – Rich Sadowsky Nov 27 '11 at 12:33
  • Oliver, just send the file. It will be a media player requesting the file. So I need the mime types to be right. – Rich Sadowsky Nov 27 '11 at 12:33

2 Answers2

1
    OutputStream out = response.getOutputStream()
    //set up byte array
    byte[] content = yourS3Object.getBytes()


    response.setContentLength(content.size())
    response.addHeader("Content-disposition", "attachment; filename=${yourS3Object.fileName}")
    response.addHeader("Content-type", "video/quicktime")
    out.write(content)
    out.close()

That should do the trick.

Oliver Tynes
  • 954
  • 4
  • 11
  • 3
    As I got deeper into this, I found that the new modern webkit-based html5 browsers are more complicated if you don't want to just download. If you want to play in place, there are issues related to "Accept-Ranges" and "Content-Range" headers. We learned this by looking at what other servers that served progressively downloaded files to these browsers did. We only looked when we still had problems with really large files with the above code. The bottom line is this is more complicated than initially meets the eye and I would love to see a comprehensive article on this somewhere. – Rich Sadowsky Dec 02 '11 at 01:19
  • 1
    I am going to dig into streaming large (huge, really.. 100gb++) files incrementally soon, will keep your article need in the back of my head and maybe cook up something as I do the work. – Oliver Tynes Dec 02 '11 at 08:51
  • 3
    Well, where's that article? :) – mtyson Jul 08 '12 at 17:28
1

While it's certainly possible to serve video from a controller, there may be a much simpler solution if your goal is only to present QuickTime video from within the browser. In this case you might instead wish to try the FlashPlayer plug-in, available with the command:

grails install-plugin flash-player

Once you get this player installed, you can then simply insert the following lines into your view GSP:

<div id="test">
  <p>You need Flash Player installed  to play this media.</p>
</div>
<g:flashPlayer id="test" varFile="${createLinkTo(dir: 'movies', file: 'my.mov')}"/>

It took a little fiddling to get the plug-in to work with Grails V2, but now that it's in place I realize how much work that plug-in helped me to avoid. If you want to learn more, visit http://grails.org/FlashPlayer+Plugin