Subscribe to RSS
get email updates
home | about | pixDif AIR app | video tutorials
polyGeek.com

place your ad here

Web Premium



Get Qwest High Speed Internet



Video streaming with PHP and xmoov

November 24th, 2008 . by polygeek

pgTV
Watch the video tutorial:

Streaming video with xmoov/PHP

How to set up xmoov to create a video player that can stream videos on an server without installing any streaming server software. Includes overview of video player built with Flex.

[ Other video tutorials ]

It used to be that if you wanted to do video streaming you had to use Flash Media Server or that Red5 thing. The problem with that is first the cost and secondly you can’t just toss this stuff on your server and say go stream. But xmoov fixes all that, very simple to use and for the low, low, low, discount price of absolutely nothing.

What is streaming? ( skip to the next heading if you already know this stuff. )

Code to download

  • xmoov : php code to do the streaming
  • FLVMDI : metaData injector
  • example videoPlayer : source code for a Flex video player built to do xmoov streaming
  • Sample videos : videos with keyframe data injected into the metaData.

In case your not familiar with video playback there are two methods of delivery: progressive and streaming. Playing a video progressively is much like downloading an image from a server. You don’t need any special software on the server. The downside to progressive is that users can’t seek to a portion of the video until it has been downloaded.

That isn’t a big problem if you have fairly short videos, like commercials or maybe a music video. But for long videos it can be an issue.

Streaming a video allows the user to jump to the very end of a video and watch that without downloading all the bits that came before.

Another difference between the two is that progressive videos end up on the user’s browser cache. With streaming you can keep it out of the cache which is important for videos that you don’t want users to redistribute – like movies.

You can read more about Flash video streaming at the Wikipedia.org.

Installing xmoov
xmoov is simple to install. How simple? Well, can you FTP? Cause that’s about all you need to do. Just drop one little file – xmoov.php – into the root of your server. One thing to look at is the opening PHP tag in the xmoov.php file. I’m just learning PHP and one thing I’ve noticed is that sometimes a block of PHP script begins with: <? and sometimes it begins with <?php. Apparently that’s a server setting or something. The developers for

view source

xmoov must have their servers set up so that they don’t have to include the php part of the <?. But that script wouldn’t work at all on my development system here or on my host. If you are having trouble getting the code to work then just add the php to the <? and that might fix your problem, like it did for me.

How xmoov works
With progressive videos you would tell your video player to play a video. Again, it’s much the same as telling an <image> component in Flex what it’s source is. Here’s some Flex code as an example:

<mx:VideoDisplay
source="http://polygeek.com/videos/sea.flv"
width="320" height="240" />

With xoov it’s nearly the same. You need to tell the <VideoDisplay> component to play everything through the xmove.php script. All you would need to do is change the source to this:

source="{ videoFileName }"

Where videoFileName = “http://polygeek.com/xmoov.php?file=sea.flv&position=0″;

You can see that you’re passing the file and position to the xmoov. It’s pretty obvious what the file is. The position is the number of bits into the movie from where the script will start sending the file stream. In this case we’re starting at the beginning.

This is an ultra-important point: you can only stream from the file position of a key frame in the video. You can’t just make up a number of bits into the stream and expect it to work. So, the question is, where are the key frames?

Key frame, key frame, where art thou key frame?
Here’s what you do to get a key frame: you fake a hand off to the left and then run the QB on a bootleg to the right where he… Sorry, the game is on.

Okay, here’s what you do to find the key frames: you need some tool that can inspect your video files for key frames and then add the entire list to an Array in the metaData. It’s quick and simple to do. I used FLVMDI – download link is about 2/3rds of the page down – which has a command line and GUI version. Unfortunately I couldn’t get the GUI version to work but the command line worked like a charm.

The download page for FLVMDI has full documentation. Here are the parameters that I used for the command line version: flvmdi.exe C:\wamp\www\videos /x /k

What that will do is inject the key frames metaData into the file and also output an XML file with the same data. If you don’t want the XML file then leave off the /x parameter.

If you want to inspect the metaData then you can use RichFLV – a free AIR app – that will play videos and gives you a panel to display the metaData. In the case of the key frame metaData it will only show an [ object object ] for the value. But at least you know it’s there. Obviously you can just run your app in debug mode and set a break-point in the onMetaData event handler to inspect the values if you want – more on that later.

Seeking to a key frame
Now that we’ve gone through all this work you might want to actually set your video player up to seek. When the user seeks forward, or backward, in the video you need to know the time value in the movie that they are targeting – in seconds.

The metaData that FLVMDI has injected is two parallel arrays. The times array is a list of all the time values in the video that correspond to a key frame. You will need to loop through that array looking for the value that is nearest to where the user wants to seek. Once you have the index of the times array then you can use the corresponding element in the in the filepositions array – which is a collection of all the file positions that correspond to a key frame – to tell xmoov what part of the video file to start sending from.

The code in my onSeek() method looks like this:

private function onSeek( e:SliderEvent ):void {
var seekTo:Number = e.value;
var i:int = 0;
while( _keyFrame_timePositions[i] < seekTo ) {
i++
}
vidWin.source = "http://polygeek.com/xmoov.php?file=?sea.flv&position=" + _keyFrame_filePositions[i];
}

Settings in the xmoov.php file

There are only two settings that you must change from the defaults of the xmoov.php file. When you download it find lines 33 and 36. By default they look like this:

define('XMOOV_PATH_ROOT', '' );
define('XMOOV_PATH_FILES', 'videos/' );

If you are testing on a local machine you can set the first line to something like ‘C:\wamp\www\’. On my server I used: $_SERVER['DOCUMENT_ROOT']

The second line is just the folder on your server where the videos are located. That’s all the changes that you need to make to xmoov.php. There are other settings for bandwidth limiting and caching that you can read more about in the documentation – if you can find it.

So in the end my file looks like this:

define('XMOOV_PATH_ROOT', $_SERVER['DOCUMENT_ROOT'] );
define('XMOOV_PATH_FILES', '/videos/' );

Issues
Originally when I used FLVMDI to inject metaData I added the parameter to add an event for when the last second of video is played. For some reason that caused the <VideoDisplay> to bounce at the end of playback back a second or so. So if you don’t need to know when the last second of video plays then I’d leave that off.

You can see in the source of the example that I had to do some trickery to keep the timeline-thumb ( that the user drags to do the seeking ) from bouncing after a seek.

Closing
That pretty much covers it. The source code in my example is extensively commented so give it a looksy.

Please let me know if you have any questions or comments on how this could be improved.

If something here has proved valuable to you then feel free to drop a couple of bucks in the tip-jar.

Post to Twitter Post to Delicious Post to Facebook Post to Reddit Post to StumbleUpon


similar posts

27 Responses to “Video streaming with PHP and xmoov”



[...] Video streaming with PHP with xmoov By polygeek xmoov : php code to do the streaming; FLVMDI : metaData injector; example videoPlayer : source code for a Flex video player built to do xmoov streaming; Sample videos : videos with keyframe data injected into the metaData. … polyGeek.com – http://polygeek.com/ [...]

comment number 2 by: Judah

Great post! Thanks for sharing! :)

comment number 3 by: CinePost

Very informative….does xmoov only work with flash? What about H.264?

comment number 4 by: polyGeek

@CinePost, good question. Technically xmoov isn't directly tied to Flash. It is only responding to input and doesn't know where that input comes from.

If you want to try it on H.264 you would have to find some meta-data injector first. No idea how to go about that.

Let me know if you have any luck.

comment number 5 by: Kris

I have watch the video tutorial and read the instruction but somehow I miss something.

I have download all the 4 code needed. I have put xmoov.php, folder videos, PHPstreaming.mxml and folder extensions in C:wampwww.

Here is the xmoov.php settings:

define('XMOOV_PATH_ROOT', trim('C:wampwww '));

define('XMOOV_PATH_FILES', '/videos/');

Here is the PHPstreaming.mxml settings:

private var _videoFilename:String = "matrix.flv&position=0";

private var _host:String = "http://localhost/xmoov.php?file=";

And then I do not know how to run it. I have tried to call xmoovphp, it did not work, also called PHPstreaming.mxml, a download bos appear.

Would you tell me how to run it please?

Thank u

Regards

Kris

comment number 6 by: polygeek

@Kris, What happens when you call the file? You are running Apache server on your machine, correct?

comment number 7 by: Kris

@Dan Florio. Yes, apache server, I am using Wampserver2. I tried to call http://localhost/xmoov.php?file=delivery.flv&position=0 and the result is a download box appeared. Then I copied PHPstreaming.mxml and folder extensions into C:&#92wamp&#92www&#92videos, and call http://localhost/xmoov.php?file=PHPstreaming.mxml&position=0, and the result is an empty page. What should I do?

comment number 8 by: polyGeek

@Kris, there's the problem – or at least one of them – the MXML file is the source code. It needs to be compiled into a SWF using Flex Builder. I'm guessing that you aren't a Flash/Flex developer, right? Is there a PHPstreaming.swf file in the zip that you downloaded? You should ultimately be calling http://localhost/PHPstreaming.HTML. That HTML file will load the SWF and the SWF will play the movie.

comment number 9 by: Kris

@Dan Florio. Yes I am not Flash/Flex developer, I am still a newbie in web developing. I do not have PHPstreaming.swf or PHPstreaming.html file. Would you tell me the steps so I can run the HTML file to load SWF? Many thanks in advance:)

comment number 10 by: polyGeek

@Kris, I'm really sorry but this is way beyond just a simple "do this" sort of thing. I don't know what you really know so I have no idea where to start. Plus, even if you did get it running you would have to install Flex Builder just to change which movie it played. This isn't really suitable to anyone who isn't a Flex developer.

comment number 11 by: polyGeek

@Kris, This won't help with streaming the video files but if you just want to make a video player then check out videoMaru.com. I created that for Flash designers who don't know how to make custom video players. It's really quite flexible and easy to use. But you must have the Flash IDE to make/edit the video players.

comment number 12 by: Kris

@Dan Florio: I am thankful for your reply. Well I guess I have to learn Flex or find another way.

comment number 13 by: E. L. Perry

I used Flex Builder 3 to compile your mxml code for the video player but it gets an error on the "<extensions SmoothVideo" as an unrecognized type.

Can you help me?

comment number 14 by: polyGeek

@Perry, not sure what the problem might be. The SmoothVideo.as file is included in the source. Are you using it?

comment number 15 by: sivam

I used Flex Builder 3 and compiled PHPstreaming.mxml and have the PHPstreaming.html and PHPstreaming.swf.But when i run the url "http://localhost/PHPstreaming.html" in IE, script error shown and says object expected.

Can you help me?

comment number 16 by: polygeek

@sivam, I’ll need some more info than that to be able to try and help. My first suggestion would be to set a break point in FB and step through the code looking for the error. There is probably an object somewhere that is set to null or something like that.

comment number 17 by: Nasheet

I'm new in php and don't know about flash. I want to do video streaming in php.Can u help me in this regardd

comment number 18 by: polygeek

@Nasheet, I’m not trying to be a smart ass but I’d suggest that you start learning Flash and PHP. There is no easy path to this. You can’t just slap some stuff together. It took me about 4 hours to figure out has to do the PHP streaming and that’s after I had been doing Flash development work for about 10 years. Get some books and start hammering away. It’s a good skill to have. And having a project in mind to work on helps the learning process. Good luck.

comment number 19 by: Joseph Gutierrez

@Dan,

It is cool that you live near Big Bear. I live in Yucaipa the back-end side of the mountain. My blog isn't specifically about Flash/Actionscript. It's more about the complexity of developing for the web.

I noticed that you have a linear search O(n) in your OnSeek method. I know you talked about optimization using while instead of for loop. A couple of things. First when a video player starts at the beginning and users click greater than the beginning. You might have faster seek position if you decremented from the back-end of the key-frame array. Secondly, I would get rid of the linear search and go with a binary search O(log n).

Also, remember that xmoov.php has not been optimized for speed. If you look at the output file section you will see that your doing an if-else decision inside a while loop. The if-else should be on the outside of the while loop. You only need to check if your bandwidth is limited once.

Presently, I'm refactoring xmoov.php for readability and more tighter loop optimization.

comment number 20 by: polygeek

@Joseph, I don’t live near Big Bear anymore. Just moved to Camp Verde, AZ.

Nice tips on the loop optimization. You’re right, going backward would be more efficient. I didn’t write the xmoov.php code. In fact I don’t understand most of it. I would love to see your version.

comment number 21 by: xmoovStream

This is a great post!

xmoov-php has been updated and has a new site @ http://stream.xmoov.com

cheers

comment number 22 by: Fred

Does anyone know how I would incorporate this with FLVPlayer?

<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ codebase=”http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0″ width=”560″ height=”385″ id=”FlvPlayer” align=”middle”>
<param name=”allowScriptAccess” value=”sameDomain” />
<param name=”allowFullScreen” value=”true” />
<param name=”movie” value=”sugar_player/sugarplayer.swf” />
<param name=”quality” value=”high” />
<param name=”bgcolor” value=”000000″ />
<param name=”FlashVars” value=”flvpFolderLocation=flvplayer/&flvpVideoSource=http://picksmart.org/streamer.php/xmoovstream.flv&flvpWidth=560&flvpHeight=385&flvpInitVolume=50&flvpTurnOnCorners=false&flvpBgColor=000000″ />
<embed src=”sugar_player/sugarplayer.swf” flashvars=”flvpFolderLocation=flvplayer/&flvpVideoSource=http://picksmart.org/streamer.php/xmoovstream.flv&position=0&flvpWidth=560&flvpHeight=385&flvpInitVolume=50&flvpTurnOnCorners=false&flvpBgColor=000000″ quality=”high” bgcolor=”000000″ width=”560″ height=”385″ name=”FlvPlayer” align=”middle” allowscriptaccess=”sameDomain” allowfullscreen=”true” type=”application/x-shockwave-flash” pluginspage=”http://www.adobe.com/go/getflashplayer” />
</object>

comment number 23 by: polyGeek

I have no idea what you're asking. That code you gave is the embed code for a SWF. Isn't FLVPlayer a desktop app for playing FLVs? What are you trying to do?

comment number 24 by: Ben

We are experiencing an odd problem with using this xmoov-php script.

When we send a lot of HTTP requests to xmoov in a short amount of time, we can "crash" PHP in such a way that all future PHP requests generate "Internal Server Errors". Once this happens, all PHP pages on our site

give us this error.

What's interesting is that this error is only visible to those of us here on our LAN.

Anyone from outside our LAN can continue to use the PHP and the entire site.

Also, after maybe 5-15 minutes, the error disappears and we can then resume running PHP on the site again.

This is very troublesome, as it is essentially limiting our ability to interact with the site. It may also limit the number of connections that can be made per IP address, so if a company has a very

large network of employees who would like to access xmoov, this is going to cause problems.

Does anyone have experince with this sort of error? And does anyone have a suggestion for dealing with it?

comment number 25 by: polygeek

@Ben, Sorry, I have no idea how to fix it. The only thing I would suggest is perhaps putting the videos on a separate server so that they don’t interfere with the site.

comment number 26 by: Andre Long

How would you use XMOOV to create a viedo chat application?

comment number 27 by: polygeek

@Andre That’s not what Xmoov is for. I think you’d need FMS or something similar for that. Or use the P2P capabilities of the Flash Player.

   Welcome back (Change)

Leave a Reply

comment feed RSS   subscribe to this comment thread

Recent Posts

   



polyGeek.com

© Copyright 2008 polyGeek.com / Dan Florio, All Rights Reserved Except Where Explicitly Stated
Web Developement Blogs - Blog Catalog Blog Directory
M2 Websites
Local Directory for Los Angeles, CA

Better Tag Cloud