Jump to content
H.264 video streaming/seeking via Java servlet
Asked by kion
Posted Nov 04 2009 03:18 PM
Hello, Java gurus
I'm working (as a lead Java-developer) on the internet-TV startup, which is currently on it's final way to first public stage (access by invites only).
There're several critical issues to resolve before we can open it to the whole world and the most critical one so far is: H.264 video (*.mp4 files) streaming/seeking via Java servlet.
I know there're some quite powerful OSS solutions on the market, like Red5, but i'd rather stick with some easier to integrate option (separate server/webapp for video streaming isn't the best option for me so far). I also know that it is possible to implement streaming servlet for such a purposes and this seems to be the solution that will suite me enough for now...
Though, i'd like to know whether there's some easy and stable enough (+free/open) implementation of such a servlet (or, as variant, a library that i will be able to integrate within a servlet) that i can (re)use instead of implementing my own one (more so, i have no big experience in solving problems like that).
If anybody is aware of such a solution, i would greatly appreciate your help in sharing it with the rest of the community (i believe this is a common problem for projects using video-streaming).
Comment by kion : Nov 05 2009 06:16 AM
Hmm... I have found a temporary workaround: Jetty servlet container can be used instead of Tomcat (which i was using for deployment initially). This looks a bit strange to me... Why Jetty serves video-files correctly while Tomcat doesn't?...
Anyway, this is, as i said above, not a solution, but rather a workaround.
If anyone is aware of some generic solution, which won't depend on certain servlet container - you're still very welcome to share your knowledge.
Answered by metakey
Posted Nov 05 2009 07:31 AM
The ability to seek in video may depend on your player implementation and on how your web server handles partial content (206) requests. While the obvious way is to use one of native FLV streaming solutions like Wowza or FMS that provide precise frame handling (from the server and client view), you can get satisfactory results using the frontend server module. Please google for "nginx flv streaming" or, in your case, "nginx mp4 streaming". The equivalent module for Light HTTPd also exists.
Comment by kion : Nov 05 2009 07:42 AM
Thanks for replying.
Actually, i already have compiled and installed streaming module for Apache server, but this seems to be not the best solution out there for me (more so - it did not work in my case...).
Concerning "player implementation" - yes, it depends of course. But i'm trying to achieve correct *server-side* behaviour for the beginning here...
Actually, i use mplayer on my Linux-box to test server's video streaming - if stream is not seekable, it gives me an appropriate error message about that (if i use Jetty on server side for web-app deployment, mplayer doesn't give this message, while in all other cases, when i use standard Apache with streaming module or Apache Tomcat, - it does).
So, in general, i believe, this is, first of all, a server-side issue. If this is solved, then i can use an appropriate player implementation which will handle seekable video-stream correctly.
Comment by metakey : Nov 05 2009 08:01 AM
Ok, I assumed you have an issue the Flash player. I think that the difference is how your servlet container's static resource handler serves Range: requests. Try to turn range request support off in Jetty (acceptRanges in for DefaultServlet). If it will work and seeking will fail on this step, try insert some kind of reverse-proxy like nginx between your Java web server and the player, switch locations seamlessly in config and notice what the access logs will show. For sure, you can watch traffic using the Wire Shark or any other tcp/ip sniffer.
Comment by kion : Nov 05 2009 08:15 AM
Indeed, metakey, it started as an issue with Flash player, but later i have found out that the problem is on the server side...
I also know it's about handling byte-range headers in the request, that's why i asked if there's a ready to use solution (servlet) that can handle that.
Concerning "proxy" - i have, actually, already thought about such a way, though i'm not yet sure that will work flawlessly and will be easy to maintain after all... It's just because of the overall complexity of app (and, you know, i'd rather like to keep app design and deployment process as simple as possible) - i have a bunch of other things i need to handle, like catching stats for video views (which is done via additional filter), so having a "proxy" is definitely a way, but i would like to figure out a solution that will let me keep deployment process as simple as possible (i still mean "native" java-based solution that will be easy to integrate within webapp codebase).
In any case, i'll have to try all the options, so whenever i have anything that suits me enough - i'll report it back here.
P.S. Thanks for discussion participation, metakey!
Answered by kion
Posted Nov 05 2009 10:25 AM
Ok, solved: there seemed to be a bug in Tomcat which prevented it from correctly handling ranges accepting even in case "useAcceptRanges" property was set to "true" (which, actually, should enable byte-range serving in default servlet; more on that here)...
I used 6.0.18 version with this option enabled and it did not work. Updating to version 6.0.20 solved the problem. So, server-side streaming works now (tested with mplayer)...
This is not a generic solution, but rather a servlet-container-dependent, but for me this is good enough (i just need to use OSS software capable to stream my video, so i don't have to implement it myself).
So, after all, if you're good to go with Jetty/Tomcat (other servlet containers may have something similar, i believe) - issue can be marked as "solved" now!
Now i need to adjust client-side (Flash player) to be able to use this server-side-enabled video-streaming
BTW, JW Player, which i was going to use seems to be unable to handle this (it can use separate streamer script, but seems to be not able to make use of "plain" server-side video-streaming)
To finish this thread completely - can anyone advice a good Flash-player that will work with server-side video-streaming enabled? I assume this should be the one that correctly sends byte-range headers within it's requests...
Comment by kion : Nov 05 2009 12:32 PM
Oh, well... After all, it seems that Flash is not capable to send Content-Range headers, so this method will work for standard desktop-players like MPlayer, VLC and so on (thus, client-apps can be implemented for displaying streaming video from server), but will NOT work for most Flash-players out there...
And it looks like HTTP pseudo-streaming support on the server-side is the only way...
So, the question is still open.
P.S. I guess, i need to look for Java-analog of XmooV PHP... Otherwise - i'll have to implement something similar myself.
Comment by Norma21Walter : Apr 08 2010 04:52 AM
Lots of specialists argue that <a href="http://lowest-rate-loans.com">loan</a> help a lot of people to live their own way, because they are able to feel free to buy needed things. Furthermore, banks give commercial loan for different classes of people.
Answered by jim85133
Posted Mar 14 2011 09:10 PM
Are there really no solutions for this? I would like to be able to stream from a java servlet as well and have searched everywhere for it. Are you the only one that has ever thought of it? I thought there would be samples everywhere. Instead it looks that we have to install a seperate product from Tomcat.
I have it working fine with Apache but I need more control over the input/output stream. I have considered just extending the DefaultServlet and doing that but can't beleive there is not a better solution.
Does Spring handle streaming at all? I have searched it's website to no avail.
I am attempting to stream to mobile devices and to web players.