|
My company Atomik Studios is currently developing RIAs for the streaming services of a fortune 500 technology company. One of the requirements is support for H.264 video and the RTSP streaming protocol, which limits our options to AJAX with a video playback plug-in, maybe Silverlight? Last week Adobe announced Flash Player 9 Beta supporting H.264 video (more info on labs.adobe.com), which gives us a new option: Flash! I tested the new Flash Player a bit and I could play H.264 mp4 files in progressive mode, but I didn't manage to play video over the RTSP protocol. Adobe will support streaming H.264 video over their Flash Media Server, but I don't know if we will be able to stream from other streaming servers. And that would be very unfortunate for us and our client. And it would give Silverlight an advantage. (Assuming that Silverlight supports RTSP, but I would think so, because it uses Windows Media Player)
Below more details on the test: The setup I have 2 computers on the LAN, a Windows Vista with the FireFox and Internet Explorer 7 and an Ubuntu Linux with an Apache webserver and a Darwin Streamin Server. Darwin Streaming Server is the open source version of Apple's QuickTime Streaming Server. As with all Apple products, it is easy to install and to use. The Windows machine has ip 172.19.3.4 and the Linux 172.19.3.5. Flash Player 9 beta You must first uninstall your current Flash Player and install the Beta release. More details on: http://labs.adobe.com/downloads/flashplayer9.html The Flash movie First I created a Flash movie video.swf. It just loads and plays a movie, from a url specified by the videoPath parameter, which is passed as an argument from the HTML embed and object tag. For example: <param name="movie" value="video.swf?videoPath=sample_h264_1mbit.mp4" /> Here is the as 3 code: package { import flash.display.*; import flash.media.*; import flash.errors.*; import flash.events.*; import flash.net.*; import flash.text.*;
public class App extends MovieClip { public function App() { var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters; var p = String(paramObj["videoPath"])
var nc:NetConnection = new NetConnection(); nc.connect(null);
var ns:NetStream = new NetStream(nc); ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); ns.play(p); function asyncErrorHandler(event:AsyncErrorEvent):void { // ignore error } var vid:Video = new Video(); vid.attachNetStream(ns); addChild(vid); this.videoPath.text = p; } } } The variable p is the path passed by the HTML page and this.videoPath.text refers to a TextField I put on the stage to debug the path. Testing an .flv file First I tested with an .flv file to make sure everything runs OK. I changed the HTML parameter to (I'm just showing the Embed parameter, but I did the same in the Object tag): <param name="movie" value="video.swf?videoPath=video.flv" /> And it ran fine. Testing an .mp4 file I changed the HTML parameter to: <param name="movie" value="video.swf?videoPath=video.mp4" /> Great! Halfway to a streaming mp4 experience. But there it stopped for me. Testing a streaming mp4 I tried the path to the mp4 stream first in QuickTime to make sure the path is OK and the streaming server is up and running. Then I changed the video path to: "rtsp://172.19.3.5/video.mp4" and nothing happened. The log of the Darwin Streaming Server doesn't show any requests coming in and FireFox's FireBug plug-in didn't show any request for the mp4 file going out. OK. Time for the big equipment : WireShark Network protocol analyzer. Here an extract of the capture:
3 1.262615 172.19.3.4 172.19.3.5 TCP 49948 > http [SYN] Seq=0 Len=0 MSS=1460 WS=2 4 1.262768 172.19.3.5 172.19.3.4 TCP http > 49948 [SYN, ACK] Seq=0 Ack=1 Win=23360 Len=0 MSS=1460 WS=2 5 1.262799 172.19.3.4 172.19.3.5 TCP 49948 > http [ACK] Seq=1 Ack=1 Win=65700 [TCP CHECKSUM INCORRECT] Len=0 6 1.262876 172.19.3.4 172.19.3.5 HTTP GET /lab/video.html HTTP/1.1 7 1.263057 172.19.3.5 172.19.3.4 TCP http > 49948 [ACK] Seq=1 Ack=423 Win=6912 Len=0 8 1.263772 172.19.3.5 172.19.3.4 HTTP HTTP/1.1 200 OK (text/html) 9 1.417134 172.19.3.4 172.19.3.5 HTTP GET /favicon.ico HTTP/1.1 10 1.418305 172.19.3.5 172.19.3.4 HTTP HTTP/1.1 404 Not Found (text/html) 11 1.452718 172.19.3.4 172.19.3.5 HTTP GET /lab/video.swf?videoPath=rtsp://172.19.3.5/video.mp4 HTTP/1.1 12 1.453512 172.19.3.5 172.19.3.4 TCP [TCP segment of a reassembled PDU] 13 1.453624 172.19.3.5 172.19.3.4 HTTP HTTP/1.1 200 OK (application/x-shockwave-flash) 14 1.453644 172.19.3.4 172.19.3.5 TCP 49948 > http [ACK] Seq=1264 Ack=4749 Win=65700 [TCP CHECKSUM INCORRECT] Len=0 15 1.604723 172.19.3.4 172.19.3.5 HTTP GET /favicon.ico HTTP/1.1 16 1.606269 172.19.3.5 172.19.3.4 HTTP HTTP/1.1 404 Not Found (text/html) 17 1.803640 172.19.3.4 172.19.3.5 TCP 49948 > http [ACK] Seq=1603 Ack=5249 Win=65200 [TCP CHECKSUM INCORRECT] Len=0 I am not a protocol wizard, but this is how I read it: Frame 3 - 5: my client and server are very polite, they shake hands. Frame 6 - 8: the HTML page is loaded Frame 9 - 10: favicon.ico is requested and not found. Frame 11 - 14: the swf file is loaded Frame 15 - 17: favicon.ico is requested again and not found. No request for the mp4 file. Testing a streaming mp4, second try Now I changed the path to: "http://172.19.3.5:554/video.mp4". The Darwin Streaming Server is running on port 554. This works in QuickTime and it requests the video over HTTP. The streaming server then returns a link over RTSP. The client is suposed to follow this link, but it doesn't happen. This extract starts right after the swf file has been loaded. 54 15.720493 172.19.3.4 172.19.3.5 TCP 49981 > rtsp [SYN] Seq=0 Len=0 MSS=1460 WS=2 55 15.720646 172.19.3.5 172.19.3.4 TCP rtsp > 49981 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 WS=2 56 15.720683 172.19.3.4 172.19.3.5 TCP 49981 > rtsp [ACK] Seq=1 Ack=1 Win=65700 [TCP CHECKSUM INCORRECT] Len=0 57 15.720764 172.19.3.4 172.19.3.5 RTSP Continuation 58 15.720959 172.19.3.5 172.19.3.4 TCP rtsp > 49981 [ACK] Seq=1 Ack=422 Win=6912 Len=0 59 15.721177 172.19.3.5 172.19.3.4 RTSP Continuation 60 15.721224 172.19.3.5 172.19.3.4 TCP rtsp > 49981 [FIN, ACK] Seq=151 Ack=422 Win=6912 Len=0 61 15.721245 172.19.3.4 172.19.3.5 TCP 49981 > rtsp [ACK] Seq=422 Ack=152 Win=65548 [TCP CHECKSUM INCORRECT] Len=0 62 15.721387 172.19.3.4 172.19.3.5 TCP 49981 > rtsp [FIN, ACK] Seq=422 Ack=152 Win=65548 [TCP CHECKSUM INCORRECT] Len=0 63 15.721475 172.19.3.5 172.19.3.4 TCP rtsp > 49981 [ACK] Seq=152 Ack=423 Win=6912 Len=0 Frame 54 - 56: the client shakes hands with the streamin server (rtsp = port 554) Frame 57: the client requests the mp4 file. If we look a the details of the request: GET /video.mp4 HTTP/1.1 Host: 172.19.3.5:554 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: nl,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Frame 58: server acknowledges the request Frame 59: server sends the link back: HTTP/1.0 200 OK Server: QTSS/4.0 Connection: Close Content-Type: video/quicktime Content-Length: 43 rtsptext rtsp://172.19.3.5:554/video.mp4 Frame 60 - 63: server closes the connection, server and client say goodbye. Now if you do the same thing in QuickTime after the server closes the connection, the client will open a new connection and request the file over the RTSP protocol: DESCRIBE rtsp://172.19.3.5:554/video.mp4 RTSP/1.0 CSeq: 1 Accept: application/sdp Bandwidth: 384000 Accept-Language: en-US User-Agent: QuickTime N-/7.1.6 (qtver=7.1.6;os=Windows NT 6.0) Time for a conclusion. Either Flash Player 9 H.264 doens't support RTSP (yet) or it isn't as simple as putting rtsp:// in the video path. Maybe the NetConnection needs to be set up to work with RTSP. If anyone finds out, let me know. |