This is a neat feature because it is usually only possible to play and seek to a part of a video that has already been downloaded unless you deploy a streaming media server.
Here's the working example. You need Player 8 for this but that's only because I encoded the video using VP6. The rest is compatible with Player 7.
I have uploaded my progress and included all sources.
It should be noted that due to the support of Buraks it was much easier to implement this idea. A new version of flvmdi injects an object containg two arrays into the flv's metadata. It contains the exact starting position in bytes and timecode of each keyframe. Using this information we can request any part of the flv file starting at a specified keyframe. Check this post for more info on flvmdi - the injection is NEEDED if you want the PHP seeking to work.
Thanks to everyone on the chattyfig list who contributed to this and also to Brian Bailey for blogging about his efforts. Thanks also to Lee Brimelow whose scrubber I have used and modified for this app.
*** UPDATE ***
I have made some small changes now:
- the 'buffering' no longer appears once the video has ended. This was done by simply introducing a new variable 'ending' and checking for a NetStream.Buffer.Flush message.
- loading bar shows the download progress again, although this is not that important as you can seek beyond that point anyway :-). But it will be good to further extend the app so that it will not request the file via PHP once it has loaded completely. We could seek normally once download is complete.
- source files have been updated
- another update (09/2007): updated sources by xmoov.com are now available at http://flashcomguru.com/downloads/phpstream_update.zip
UPDATE: Steve Savage has now ported this to Coldfusion: http://www.realitystorm.com/experiments/flash/streamingFLV/index.cfm

This work is licensed under a Creative Commons Attribution 2.0 England & Wales License.
I am very excited about Red5. What I like about this approach is its easy implementation. A webserver and PHP - it doesn't get much easier than that.
Also I noticed that the video doesn't really end well...gets to the end and flashes Buffing Video. Perhaps some simple check to autoRewind or something.
Thanks again!
I had checked your php file. You are reading whole flv file at a time, i think this will become then progressive download. You need to read file from the seek point. I will suggest you to improve your coding in php to read from any given location by clicking on progress bar while playing flv.
Glad to hear it's useful to you though. Make sure to email me if you improve it. I think Patrick Mineault's suggestion is a good one, once the file has been downloaded completely we should use the cached version and not request the file again.
Also, I think is not possible to replay the video from cache if you skip some part of the video, as the stream changes everytime you change the play position you get only the remaining part and not the full video, is this right?
anyway, good stuff, keep it going ;)
I tried to use this method with a huge video (68Mo, 40mn) and the player is freezing when i try to seek.
Do you think it comes from PHP script or actionscript ?
Anyway, very good job, i really like it and would like to enhance the player .
I think for a huge video, the search in the actionscript could get a big performance improvement by using binary search.
Best regards,
Burak
www.asvguy.com
Post the link of big flv somewhere, i like to test.
I think the problem do not come from actionscript as it freezes when i try to seek to the begining of the movie.
The actionscript routine should retrieve the number of the keyframe very quickly in this case so probably it comes from PHP.
I got another question, what should happen if a user try to play a file bigger than the space defined for Temporary Internet Files. Would it crash ?
And one more question : i can't understand why the movie will be downloaded even if you seek to the end of the movie at the begining.
Why classic players are not able to read a FLV with keyframe location metadata injected in it ?
Regards
I would also assume that the 'slowness' may come from PHP but I do not know.
Question 2: What do you mean by 'classic players'? The keyframe info can be read by any player which 'listens' for the 2 new arrays. However only flvs injected with flvmdi27b will hold this info.
http://www.rich-media-design.com/test/scrubber.htm...
Concerning classic players, i understand that keyframe info can be read by player asking for this metadata. But what i mean is that with 'classic players' (not yours) i can read a FLV file without keyframe info metadata but not FLV file containing these metadata.
Strange as other players do not process such metadata so it should not create an issue.
Regards
i've tried ... everything works fine,
but I actually dont know how to use Buraks FLVMDI. I dont which metadata should I add to my FLVs.
With golfers.flv everything goes great. With my FLVs it doesnt SEEK.
Please tell me where is the problem
Thanks
Tom
I'll post an article shortly that shows you how it's done.
Kind regards
tom.krcha.com
while (!feof($fh))
{
print (fread($fh, filesize($file)));
}
..are causing the problem. When you fread($handle, $buffer_size), the interpreter allocates $buffer_size bytes for reading. This causes a problem with large files or, to be more specific, files larger than the memory available to the PHP script. Changing the above to this:
while (!feof($fh))
{
print (fread($fh, 10000));
}
Fixes the problem. You can use a much larger buffer (up to little less than your script memomry limit), but please do some performance testing first.
your comments and fix is much appreciated. However I never claimed that this script is anywhere near production ready, it's merely a proof of concept. In fact I don't even know PHP very well so keep that in mind. Anything posted on my site is meant to be for demo purposes only.
Again, thank you very much for your comments.
Thanks to Michal's new PHP script, we were able to play a huge video using PHP streaming method
(about 90Mo / 40 Min).
Performance seem to be ok when several users try to get the video.
We are looking for a PHP expert that could enhance the script in order to increase performance.
Here is the sample (Flash Player 8 is needed as we used On2 VP6 codec) :
http://www.rich-media-project.com/test4/cool.html
I'm not an expert in PHP, so. I came here to ask about the path. I'd like to make this video works through the internet. How should I set this path: 'C:/.../clips/'
I tryied 'http://www.myurl.com/videos/' and I put my flv into the folder videos, but is not working.
I'll appreciate your help,
Thanks
Fabio
that path is a local webserver filepath, it cannot be substituted by a URL. It will only work if you have access to a webserver running PHP.
It's working now!
Do you know where can I find a FLA sample with a component lists with xml to apply to this?
Best,
F
What should be wrong with my playear, when I drag the button on the progress bar the video doesn't go to the frame and the buffering message start blinking without stopping.
Thanks for your help,
Fabio
it says unexpectet file format. Is the zip file corruptet or ?
I'm on a big scholar project with it but i try to find a way to use it with flvplayback (or netstream but i don't know how to inject cue point to the flv correctly, and dynamically) ... because of netstream doesn't support cuepoint adding ! ThX
Sorry for my english ...
This is a real good one. I am trying to use the Media Server only for realtime streams for a project of mine so this could help. What could be some problems using this in a project with a lot of users? Has anyone tried? Thanks a lot.
I do not know FLVTool2 but I would imagine that it will not offer the functionality of flvmdi (which is needed to make this PHP solution work).
For everyone's information: FLVTool2 is the first tool that implement this feature. FLVMDI followed a day after since I've explained Nicolas (from FLVMDI) how this really cool feature works. He's as soon implement it in his version for others benefit of.
just my two cents on history.
Cheers!
Have you seen Rich Media Project amazing PHP player at :
http://www.rich-media-project.com/test4/cool3.html...
I have written a mail to this french company and they told me that PHP streaming components will be available soon.
Have someone heard about other products ?
David
Other than this, I think the link you posted looks like a great example of the usage of this PHP seeking technique that has been elaborated and enhanced by multiple peoples.
"For everyone's information: FLVTool2 is the first tool that implement this feature."
I don't really care which tool implemented it first. For the record: Stefan Richter (Flashcomguru), asked about this to us on October 25, 2005. We releassed a beta version of FLVMDI with this feature on November 2, 2005.
I think "the idea" was important here; if it had occured to us, we would have implemented this years ago.
So thanks again Frederic and Stefan.
Best regards,
Burak
Sorry I did a mistake, your right Burak.
"FLVTool2 is the first tool that implement this feature. FLVMDI followed a day after since I've explained Nicolas (from FLVMDI) how this really cool feature works."
Should be changed to:
FLVMDI is the first tool that implement this feature. FLVTool2 followed a day after since I've explained Nicolas (from FLVTool2) how this really cool feature works.
:)
Cheers
Thanks
VP6 allow to put keyframes every x frames/s but object keyframe doesn't work ... so using flvmdi !
For me after using flvmdi, I have too much keyframes (double or more) but i have de keyframe object, cool ... but don't really works on the player ...
I just want your settings when you encode video in VP6 ... which is the best codec for flv (i can't return to sorenson) ...
THX and sorry for my english !
As far as we are aware there's no bug with FLVMDI.
If you think any problem is related to FLVMDI, or, have a suggestion how we can improve it, please let me know (burakk at buraks.com).
Thanks,
Best regards,
Burak
So, I think about something : it should be so good to delete all keyframes from a flv movie and to put keyframes with personnal interval (10 frames / s or 1 kframe / s ... for example) with FLVMDI ! We already can ? say me how ! :D
I just wanted to know how encode with on2 vp6 for flv streaming with php ... thanks.
Alexandre
But otherwise I seem to have it working. Thanks a bunch!
In other words, I want to use this to stream my video, but when I take the video off the server, I don't want people to still be able to see the video from their cache (In other words copyright protecting it). Is this possible?
I needed this, as I have a 30MB file to stream. And each time the user changes position (the way the php file originally works), the rest of the file from the scrub point gets re-downloaded. So if a user is in the first few seconds of watching and waits until the whole video downloads (all 30MB), and then the user scrubs back to the say the third second from the beginning, almost the whole 30MB will be downloaded again at the users FULL connection speed. I don't want to waste that much bandwidth.
The code below is limited to 30k/2sec or 15k/sec. Using 30k/sec is more of an average than 15k/sec as the limit is over 2 seconds instead of one, giving the download more of a chance to allow bursts to get the player the amount of file it needs to continue playing while the bandwidth limiting sleep is happening.
Hope this posts readable!
//set below to be your bandwidth
$bytes_per_timeframe = 30000;
$time_frame = 2;
while (!feof($fh)) {
// get start time
list($usec, $sec) = explode(" ", microtime());
$time_start = ((float)$usec + (float)$sec);
print (fread($fh, $bytes_per_timeframe));
// get end time
list($usec, $sec) = explode(" ", microtime());
$time_stop = ((float)$usec + (float)$sec);
// Sleep if output is slower than bytes per timeframe
$time_difference = $time_stop - $time_start;
if ($time_difference < (float)$time_frame) {
usleep((float)$time_frame*1000000 - (float)$time_difference*1000000);
}
}
Also, my bandwidth limit above of 15k/sec is pretty low. Obviously you can change it to 100k/s for videos that need more bandwidth.
Thanks again.
Would be glad of any pointers and suggestions&
Thanks
Without loading the complete file into the player !?
Like that the php file sends chunks of the file to the player, and the player stats playing directly without having the complete 40mb loaded.
anyone ideas on this?
I tried some things with the code 'terry' posted above at 1/25/06 7:53.
But the video doesn't start directly, it starts when the complete 40mb file is loaded.
that is exactly what this script is supposed to do: making it possible to seek to a point in time that hasn't yet been downloaded. As you can see from the demo on the page this works well.
When I test it with a 40mb .flv file I have here, it doesn't start playing at all.
It does nothing.
Concerning switching between local and PHP mode i found a working solution (still beta testing) but it is not really interesting with giant movies.
The main point is to be able to kill the php file in Temporary Internet Files folder.
Anyone has an idea on how we can make this :
From Flash ?
In the PHP script ?
Still will always be flawed. We may be able to discourage local caching but at the end of the day the file you are playing is available online and for that reason it can be downloaded.
Have you experimented with the headers, trying to get the browser to expire the file right away?
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>
Will that make any difference?
I realize that its not going to be 100 percent. I just need to weed out the vast majority from being able to easily watch the file again, especially if their browser is too lazy to check for a new version.
However, I moved the name of the file into the php script and set the file name with an identifier from the swf file. So the URL won't contain the flv file name. In other words the url will be www.mysite.com/stream/flvprovider?name=clip1&position=2345. In the php file, clip1 equates to the flv file I want to play.
I also replaced the line in restartIt()
from...
ns.play( _vidURL );
to...
trace("play " + _phpURL + "?file=" + _vidName + "&position=" + 0;
the _vidURL is then no longer used, so I also removed the variable. (jeroen -- do this and I think your problem will be solved because now the file always comes form the php and is constantly regulated)
Since the php file streams the flv file from the backend, the actual flv file name is never seen by the viewer or their machine. If the person is smart enough to download the flv file by just entering the correct url parameters on the php file (www.mysite.com/stream/flvprovider?name=clip1&position=0), then they will be able to get the file as a download. However, they will have to save the file as an flv file and then create an swf file to play the flv file (or find an flv player). This all takes some intelligence, which weeds out a vast majority (80%) of the internet viewers.
if (ns.time >= ns.duration - 3){
bufferClip._visible = false;
}
(Thanks to flashcomguru for posting his original code, or I would not be able to do this. I am hugely appreciative as it got me started.)
Would you mind sending me your updated code? stefan AT flashcomguru.com
I'd like to check it out and give it a test run. I think other people will also find it very useful. A cheap (if not totally reliable) way to achieve some DRM with flv files. Great stuff.
And i've moved the .flv file location outside the http docroot, so they're not accessible directly.
Also i've used terry's code earlyer with $bytes_per_timeframe = 256000;
The working demo i've setup now:
An flashvideo behind an pay per minute phone number.
If the viewer(caller) hangs up the phone, the flvprovider stop's sending blocks of the flv video, and the player stops playing after the current buffer ( 256000b) is empty.
It looks like it's working correctly now, and the viewer can't even watch the part he've already seen after hanging up the phone.
I'm going to clean up the code a bit tomorrow, it's kinda messy now ;)
please post your files so we can keep track of the modifications and additions that everyone adds to this.
Thanks!
also, i realized my post above with the line:
trace("play " + _phpURL + "?file=" + _vidName + "&position=" + 0;
should have been (I copied the trace instead of the line that actually does the work - but the idea is the same)
ns.play( _phpURL + "?file=" + _vidName + "&position=" + 0);
You seem to be on the same page with me...
I just realized that we can make the player even better by including whether or not the buffer is full in the variables that are sent to the php file.
In other words, we can check the current buffer time:
_bufferFull = 1;
if(ns.bufferLength<ns.bufferTime){
_bufferFull = 0; // False
}
then add it to the call to the php file:
my_ns.play( _phpURL + "?file=" + _vidName + "&position=" + positions[i] + "&bufferFull=" + _bufferFull);
The php file then has the the ability (with a check of the incoming _bufferFull variable)to remove or increase the bandidth limit until the buffer is full!! Thus, increasing the amount of feedback and making the performance for the user better.
this is the dreamsolution for my videosite!
But (I think) I'm in the same path-trouble as demiurgu:
"when I drag the button on the progress bar the video doesn't go to the frame and the buffering message start blinking without stopping. I use flvmdi to inject metadata on flv and i am able to read this data so metadata is corect"
What are the right $path?
Please, give me a hint. ;) thx!
For Linux, if you have access to the command line, navigate to the directory where your flv file is stored and type "pwd" (present working directory).
That comand will show your current path, which is the path to your flv file because you are in the flv folder. Set the $path variable to that output. (should be something similar in form to: /home/users/www/flv/ -- make sure you include the training slash if its not there)
I had some problems when I first tried the script with my own .flv file.
The reason why it didn't play the file was because apache/php didn't had the rights to access the file.
( I forgot to chmod the file )
@terry:
Indeed we're on the right page. I didn't had time the last 3 days to work on the code. So I've no progress on new things.
I won't have any time next week to work on it.( wintersports )
So I'll pick it up again after 12 Feb.
The next problem was the memorylimit of my php-host (16MB),
because my FLVs are 290 to 450 MB! (each)
The example golfers.flv run and seek correct - but my FLVs run only once and don't seek a later position.
The hint from Michal Tatarynowicz are the solution:
>>> print (fread($fh, filesize($file)));
to
>>> print (fread($fh, 10000));
@demiurgu
some time its run, somtimes not? Eventually it is the filesize (or a late seekposition) of your flv. Test the hint from Michal.
Thanks!
But there is one thing : why choose 10000 instead of filesize ? it's in bits, if memory limit is 16MB, why not choose 16000000 (or a bit less) ? ;)
You can theoretically use 16384. But the script also runs it self in the memory. A better value: 15360? (sorry for my very bad english!)
Btw. - its a integer (byte) and 1 MB == 1024 Byte...
I am trying to implement the xml loader, the thumbnail previewer and the progressive functionality all in one.
(See the thumbnail preview and xml stuff on this site)
Here's what happens:
All five videos play when selected in the list (simple with the tutorial). I placed the srubit function inside the event listener.
Here is what happens:
1) All videos load and play the first time
2) Can scrub the first video
3) Cannot scrub any other video.
4) Scrubber resides on the same location as the first video WHY???
Do I need to reset some values. Is my code completely ridiculuos.
(I hope to port the xml from Php and be able to have it all dynamic...)
Here is a code snippet.
Sorry about the formatting...
//Tell Function to do stuff when a user selects an item
listListener.change = function( evtobj ){
// close any current stream
ns.close();
video.clear();
//create a new stream
ns = new NetStream(nc);
//"attach" (pipe) stream to this video object
video.attachVideo(ns);
//Build FLV file name
var flvfile = evtobj.target.selectedItem.data + ".flv";
var _phpURL ="http://www.name.com/Example12/flvprovider.php";
var ending = false;
var amountLoaded:Number;
var duration:Number = 0;
var loaderwidth = loader.loadbar._width;
loader.loadbar._width = 0;
//ATTEMPT TO RESET X VALUE TO RESET SCRUBBER
loader.scrub._x = 0;
// play selected flv
ns.play(flvfile);
//PULL METADATE FROM INJECTED ARRAY FROM FLVMDI
ns["onMetaData"] = function(obj) {
duration = obj.duration;
// suck out the times and filepositions array, this was added by flvmdi
times = obj.keyframes.times;
positions = obj.keyframes.filepositions;
}
//END OF METADATA FUNCTION
//SCRUBBING FEATURE CALLED WHEN USER MOVES SCRUBBER
function videoStatus() {
amountLoaded = ns.bytesLoaded / ns.bytesTotal;
loader.loadbar._width = amountLoaded * loaderwidth;
loader.scrub._x = ns.time / duration * loaderwidth;
}
loader.scrub.onPress = function() {
clearInterval (statusID );
ns.pause();
this.startDrag(false,0,this._y,loaderwidth,this._y);
}
loader.scrub.onRelease = loader.scrub.onReleaseOutside = function() {
scrubit();
this.stopDrag();
}
function scrubit() {
var tofind = Math.floor((loader.scrub._x/loaderwidth)*duration);
if (tofind <= 0 ) {
restartIt();
return;
}
for (var i:Number=0; i < times.length; i++){
var j = i + 1;
if( (times[i] <= tofind) && (times[j] >= tofind ) ){
trace("match at " + times[i] + " and " + positions[i]);
bufferClip._visible = true;
ns.play( _phpURL + "?file=" + flvfile + "&position=" + positions[i]);
trace("play " + _phpURL + "?file=" + flvfile + "&position=" + positions[i]);
break;
}
}
}
//END OF SCRUBBING FEATURE
}
It looks like when you change files, you play the file from the start, so I would expect the headers to get through.
Does everything work if you remove the scubbing? In other words can you change files and have each of them them start and play all the way through from the beginning of the video after changing videos?
One thing I might try (again I'm not a great programmer):
Destroy (or empty) the duration, times, and positions variables before putting the meta data of the new file in them (I'm not sure how the assignment works works, but maybe the new file information just overwrites as much of the arrays as there is information, leaveing any extra length on the array unchanged?)
(replace the AT with an @ and remove the spaces)
I would think for it to work, it would have to be implemented by a second call from within the swf file to another php file (the way you might load an xml file, or maby through another hidden NetStream?) that somehow communicates with the streamprovider.php (maybe it sets a flag in a file that the streamprovider.php opens and checks every few seconds? or maybe php files can somehow share variables and the swf just periodically calls another php file that injects the variable into the streamprovider.php? ) -- don't now if that makes sense, but if possible, coding it would be a little beyond me.
Sorry for my spell.
it looks like keyframes.times and keyframes.filepositions are a large amount of numbers for each frame in the video. Macromedia's video encoder doesn't put this information in the Video, so your scrubber do only work with flvmdi.
On the Website of flvmdi they say, that they do this with a commercial 'flv-library', and they want to keep it secret.
Do you think there is a possibility to build the php to calculate the byte position from a given time position and do like flvmdi does, without having the metadata injected?
Very great stuff, it works on the demo but not in my environment.
When moving to another position, I always got StreamNotFound. I got this message without having done any modification on the source code (except, of course, the URL).
Thanks in advance to provide any advise.
Cheers.
Xris
Actually, the problem was coming from the (fread($fh, filesize($file)); line.
Replacing the filesize by a constant fixed the problem.
Now, let's try to have it running with FLVPlayBack.
Did someone already succeed ?
Cheers.
Xris
FLVPlayback needs a XML file (from Flash Communication Server) or a *.flv for the contentPath parameter. Any other extensions (php here) doesn't work.
Anyway, to get back metadata from FLV using FLVPlayback, I create a netStream connection and get them (ns.play() + onMetaData + ns.close()). There is no onMetaData method for FLVPlayback. You must use a listener like that :
var listenerObject:Object = new Object();
listenerObject.metadataReceived = function(eventObject:Object):Void {
trace("canSeekToEnd is " + my_FLVPlybk.metadata.canSeekToEnd);
trace("Number of cue points is " + my_FLVPlybk.metadata.cuePoints.length);
trace("Frame rate is " + my_FLVPlybk.metadata.framerate);
trace("Height is " + my_FLVPlybk.metadata.height);
trace("Width is " + my_FLVPlybk.metadata.width);
trace("Duration is " + my_FLVPlybk.metadata.duration + " seconds");
};
my_FLVPlybk.addEventListener("metadataReceived", listenerObject);
But I couldn't access to keyframes object by this method.
I think there is no way to stream FLV with FLVPlayback and this method. Sorry ! :(
I think in order to make this work with FLVPlayback we would need to modify a few of its classes. I am sure the metadata can also be added but right now the event may simply dispatch a hardcoded series of properties.
I will look into modifying another, simpler player to provide this functionality. FLVPlayback is good but has some baggage that we don't need for this PHP streaming scenario.
stoem
here's a MX 2004 version of the scrubber.fla:
www.flashcomguru.com/downloads/scrubber.zip
http://philflash.inway.fr/phpstream
This is a beta version.
All sources are available.
Philippe
This is a beta.
All is ok with Internet Explorer but with Mozilla Firefox
there are some bugs.
With Firefox, we will get "NetStream.Play.Stop" events
if there is a seek.
I'm working on a solution but the problem is difficult...
Philippe
www.post-television.com
The generated FLV contains the metadata to use PHP streaming.
Podawan
http://www.realitystorm.com/experiments/flash/stre...
The code probably needs some work, and the site's definitely does, but the code does work.
I thought it would never happen. Great stuff, I'll give it a try as soon as I the chance as most of my apps run on CF too.
PS: my real name is Stefan Richter ;-)
Great program. Looks like it will be quite handy.
Just a thought. In the following line in the as code
if( (times[i] <= tofind) && (times[j] >= tofind ) ){
then ns.play( _phpURL + "?file=" + _vidName + "&position=" + positions[i]);
might want to put a check just before that and have something like this
if( (times[i] <= tofind) && (times[j] >= tofind ) ){
if(times[j]==tofind) // check upper boundary
i=j;
bufferClip._visible = true;
ns.play( _phpURL + "?file=" + _vidName + "&position=" + positions[i]);
}
Also, if anyone can point me to some code that reads/seeks binary files in asp i would be happy to change the code to work in asp.
With the php code:
print (fread($fh, filesize($file)));
Might be a good idea to check where abouts in the file you. Say if the flv is 10mb and u seek to the mid part of the flv then fread from mid to the length of the file won't it read 5mb of garbage ? Been awhile since i've used these functions so i'm probably wrong :)
Just curious you will never have the complete flv in the temp int folder ? Unless the user watches the whole video without seeking ?
Terry would it be possible to get a copy of the code you are working on ? Looks interesting. Email is benassi at tpg.com.au
In our project, we work with huge file (2 hours and 1 keyframe by second !) and the actual code seems to be optimized ton find the right position on the positions tab.
Instead of linear search on the tab, I thought to cut the tab in 2 parts while the searched value (tofind) is on one part. So, to be clear, if we have 3000 keyframes, we don't test 3000 times the tab as actual. In this code we have only 11/12 loops (3000/2^12) instead of 3000.
The code :
function scrubit() {
//Value can be a float ...!
var tofind = (loader.scrub._x/loaderwidth)*duration;
if (tofind <= 0 ) {
restartIt();
return;
}
var moitie = times.length; //get number of keyframes to test
var tab_test:Array = times; //Copy of the times tab
var positions_test:Array = positions; //Copy of the positions tab
var j = null;
var valeur = 0; //Index of the searched value in the tab
if (moitie > 0) {
//Showing buffer clip
bufferClip._visible = true;
/*************************
Here, we cut tabs on 2 parts. If value is superior of the value in the middle of the tab,
we delete (slice) the left part of the tab. If value is inferior, we delete the right of the tab.
We do many times and when the tab has only 2 values, we verify
*************************/
while (tab_test.length != 1) {
/************************
This if can be deleted if you want the inferior value (in the exemple, it will be 11 and not 12)
of the tab near the value to find.
Exemple : if tofind = 11.6 and the time tab has two value 11 and 12, it's the value 12 which
will be selected. We take this position and find the searched positions on the tab positions
************************/
if (tab_test.length == 2) {
var ecart = (tab_test[1] - tab_test[0])/2;
var verif = tab_test[1] - tofind;
if (verif < ecart) valeur = 1;
if (verif >= ecart) valeur = 0;
break;
}
else {
j = Math.round(moitie/2);
if (tofind > tab_test[j]) {
tab_test = tab_test.slice(j, tab_test.length);
positions_test = positions_test.slice(j, positions_test.length);
}
else {
tab_test = tab_test.slice(0, j);
positions_test = positions_test.slice(0, j);
}
moitie = tab_test.length;
}
}
trace("play " + _phpURL + "?file=" + _vidName + "&position=" + positions_test[valeur]);
ns.play( _phpURL + "?file=" + _vidName + "&position=" + positions_test[valeur]);
}
}
Perhaps there is error(s) beacause I write it for the function scrub_it() quickly (I tested it correctly with my own tab not times and positions added to a flv).
Here is the original code :
var tab:Array = new Array(3,5,8,10,15,17,19,31,33,34,36,48,52,67,78.1,90,101,111,112,113,114,115,116,120,
121,130,131,132,145,189,190,193,215,234,235,245,253,256,456,478,500,511,512,513);
var positions:Array = new Array(3,5,8,10,15,17,19,31,33,34,36,48,52,67,78.1,90,101,111,112,113,114,115,
116,120,121,130,131,132,145,189,190,193,215,234,235,245,253,256,456,478,500,511,512,513);
var toFind = 234.6;
trace("Taille du tableau
Perhaps there is error(s) beacause I write it for the function scrub_it() quickly (I tested it correctly with my own tab not times and positions added to a flv).
Here is the original code :
var tab:Array = new Array(3,5,8,10,15,17,19,31,33,34,36,48,52,67,78.1,90,101,111,112,113,114,115,
116,120,121,130,131,132,145,189,190,193,215,234,235,245,253,256,456,478,500,511,512,513);
var positions:Array = new Array(3,5,8,10,15,17,19,31,33,34,36,48,52,67,78.1,90,101,111,112,113,114
,115,116,120,121,130,131,132,145,189,190,193,215,234,235,245,253,256,456,478,500,511,512,513);
var toFind = 234.6;
var moitie = tab.length;
var tab_test:Array = tab;
var positions_test:Array = positions;
var j = null;
var valeur = 0;
while (tab_test.length != 1) {
if (tab_test.length == 2) {
var ecart = (tab_test[1] - tab_test[0])/2;
var verif = tab_test[1] - toFind;
if (verif < ecart) valeur = 1;
if (verif >= ecart) valeur = 0;
break;
}
else {
j = Math.round(moitie/2);
if (toFind > tab_test[j]) {
tab_test = tab_test.slice(j, tab_test.length);
positions_test = positions_test.slice(j, positions_test.length);
}
else {
tab_test = tab_test.slice(0, j);
positions_test = positions_test.slice(0, j);
}
moitie = tab_test.length;
}
}
trace("Position" + positions_test[valeur]);
And SORRY FOR MY ENGLISH ...
Alexandre
function scrubit() {
var b_match = false
var f_percentage = loader.scrub._x/loaderwidth;
var i_selected = Math.floor(f_percentage*duration);
/* Guess that the key frame I'm looking for is about the same percentage through
the array of times/keyframes as the position that was selected in the "scrub" slider.
*/
var i_guess = Math.floor(f_percentage*times.length);
if (i_selected <= 0 || i_guess <=0) {
restartIt();
return;
}
do {
if(times[i_guess-1] <= i_selected && times[i_guess+1] >= i_selected) {
trace("match at " + times[i_guess] + " and " + positions[i_guess]);
bufferClip._visible = true;
ns.play( _streamerURL + "?vidID=" + _vidID + "&vidFile=" + _vidFile + "&vidPosition=" + positions[i_guess]);
trace("play " + _streamerURL + "?vidID=" + _vidID + "&vidFile=" + _vidFile + "&vidPosition=" + positions[i_guess]);
break;
}
else if (times[i_guess] >= i_selected) {
i_guess = i_guess - 1; }
else { i_guess = i_guess + 1; }
}
while (i_guess >= 0 && i_guess < times.length)
}
The next step will be to apply Newton's Method for further improvement.
Steve Savage -> Another approach that I thought before. The code works near perfect only if the "video encoding" adds keyframes as much as secondes ! But I doesn't thought about pourcentage ! Very good idea.
For example (a video of 100 secondes, more easy)
loaderwidth = 100;
loader.scrub._x = 10;
var f_percentage = 0.1;
var i_selected = 10;
//There is as much as keyframes than secondes (times.length = 100)
var i_guess = 10;
-->The code make one loop only ! So quick :)
//There is 2 keyframes by secondes (times.length = 200)
var i_guess2 = 20;
-->The code make 10 loops to find the good index.
//There is 1 keyframe by 4 secondes (times.length = 25)
var i_guess3 = 2;
-->The code make only one loop I think ! Cool !
With my code and same video :
1-4 loops
2-5 loops (better)
3-3 loops
Another example with a huge video (4000 secondes)
loaderwidth = 100;
loader.scrub._x = 10;
var f_percentage = 0.1;
var i_selected = 400;
//There is as much as keyframes than secondes (times.length = 4000)
var i_guess = 400;
-->1 loop
//There is 2 keyframes by secondes (times.length = 8000)
var i_guess2 = 800;
-->The code make 400 LOOPS to find the good index (ouch ! but better as actually)
//There is 1 keyframe by 4 secondes (times.length = 1000)
var i_guess3 = 100;
-->1 loop
With my code and same video :
1-12 loops
2-13 loops (better way only here)
3-10 loops
I think I haven't take the best examples here but ... I can say that your code works perfect with small files and/or with keyframes number <= secondes.
If we need precision and a lot of keyframes, my way can be quicker. But finally the two codes are really fast.
A BONUS : with my code, I work with float value (Math.floor not used) and find the nearest keyframe and not the "under keyframe" (ex : times[12] for 11.7 value instead of times[11] as actual).
So, I take note about your "pourcentage method" and I'm interested in Newton's method (but can't find a way to implement it correctly ...)
PS :
with this line : "while (i_guess >= 0 && i_guess < times.length)"
I think it should be no scrub in the last keyframe ... "times[i_guess+1]" is undefined if "i_guess = (times.length - 1)" ... so, "while (i_guess >= 0 && i_guess < (times.length - 1))" is the good way ...
!!! : I notice with this postscriptum that the actual method doesn't scrub correctly if we take a value of timeline > of the last keyframe (ex : last keyframe at 100 secondes and we search 100,34 secondes) because of comparaison "if( (times[i] <= tofind) && (times[j] >= tofind ) )" ...!
It's not a problem with my "slice method".
Alexandre
Alexandre
We have extended this player to an advanced level.
Please check below URL.
http://www.dearmyfriends.com/v13/popup.php?idx=390...
Points covered:
i) dvd kind of chapters ( list of intersting poitnsto jump directly to that video part).
ii) can be viewed in different sizes. ie 1x,2x etc
iii) Previous and Next Video buttons( Yes..the two korean buttons provide this)
iv)Exact loadbar showing what bytes loaded to browser.
v) Enhanced php to send bytes to browser
http://www.dearmyfriends.com/v13/popup.php?idx=390...
Thanks
Sudhi
http://fmx.exellen.com/v13/popup.php?idx=311&m...
Sudhi: your page does not contain embed tags for the swf, therefore the page only work in IR and not in Firefox.
Also can you make the source files available?
thanks
It is still under improvement, SO I cant open sources at this stage. If you have any thing to say , you can mail me.
http://fmx.exellen.com/v13/popup.php?idx=398
check above video, which is streaming at 2 MBPS.
I have added Embed tag, so it will work in other browsers too..
--Sudhi
<object type="application/x-shockwave-flash" data="scrubber.swf?file=video.flv" width="420" height="315" wmode="transparent" VIEWASTEXT>
<param name="movie" value="scrubber.swf?file=video.flv" />
<param name="wmode" value="transparent" />
</object>
Now from what I have gathered I need it to look like this
<object type="application/x-shockwave-flash" data="scrubber.swf?file=flvprovider.phpfile=" width="420" height="315" wmode="transparent" VIEWASTEXT>
<param name="movie" value="scrubber.swf?file=flvprovider.php?file=video.flv" />
<param name="wmode" value="transparent" />
</object>
and I have tried both and neither work? I get buffer that never buffers. Any idea?
Thanks for your help.
Roger
Here are the details:
I'm embedding the flash player on a website that uses PHP and MySQL to pull information about a house/property from a database.
There is a PHP variable called $ID which corresponds to the folder that the FLV file sits in on the web server. So there will be a main folder called "properties" with many subfolders inside ("1", "2", "3"....) Inside each subfolder will be a "name.FLV" file which I want the one player to play. The actual SWF Flash Player will sit in the root folder of the webserver.
When I showed videos in the WMV format I used URL's that looked like this to pass the variables.
http://www.domain.com/m.php?video=ID
Then the code for the embedded player would look something like this:
<embed src="properties/< echo $ID; ?>/name.wmv" ></embed>
My question is how do I