Just a quick heads up to those that haven't upgraded to FMS3 and don't plan to for a bit that FMS2.0.5 has been released. Fixes some bugs, especially a big one where an exploit was in place that a DOS attack on the server could drop it.. to quote it:
A DOS attack caused by sending bad data to the server which resulted in huge memory allocations has been prevented.
The link is good for linux at the moment but the windows DL link is dead. Go figure.. Adobe, they specialize in the software but don't make sure that a link is not going to a 404 :O I'll update again when I know the link is live.
Update (6PM PST): Windows file seems to be online now.
Ever since I got up the new FMS community site fmsguru.com it's been kinda rare to get in anymore "Ask an FMSGuru" questions. I think people are just asking on the forum now or are finding their answers in the ever increasing amount of information that is on the internet about Flash Media Server. That's good I think. This particular question came in a while back and I quite literally just completely forgot about it. Sorry about that Mr. Question Sender.
The question: How do I load test my Flash Media Server applications?
The answer:
Boy this is a bit of a tough question. My first answer to this is to find a whole bunch of users to try it out. But that isn't always possible. If you happen to have a huge site with lots of users that are willing to play with the app for you to see how it runs, then great. Go for it, some people will do some testing for a free week of some service on your site or something, some will just do it because they care about the site itself. But, for the most part this isn't quite a possibility. So what else can we do?
First thing to think about is what kind of app it is. I'd say for the most part people are wondering how a data centric app is going to run. Like chats or conference applications maybe. Games are a big one too and sometimes just to see how well the server can handle lots of streams others may have a request to load test a live streaming app or prerecorded video streaming app. If you are testing a game or chat or conference app then it's important to write a bit of an AI for your app. In other words, it has to act without you doing anything so that you can watch it go.
As a basic example for a chat app you would write a quick script that randomly tosses in sentences of varying lengths to the chat at various times. This would sort of simulate a bunch of users chatting rampantly. More computers the better. Then perhaps this chat has a video feature in it where up to 5 users or something can send video. So you have to setup computers that have cameras connected to them and again have each app randomly start sending it's video. Maybe when somebody's video is detected then others will automatically play it etc. All of these things are important to see how your application is going to react to different types of loads and reacts to your code both on server and client side. Doing a very controlled test is COMPLETELY different from doing a random test like that where you don't essentially press "play" on the sending side, and after visually confirming that the video is sending and a little camera icon shows up in the userlist to then pressing "play" on the receiving side to watch that video and a little eye icon shows up on the userlist to indicate to the other user that you are watching them. This kind of stuff just plain breaks if your code has holes in it or isn't timed well.
Now, I wouldn't call it easy to go about creating that type of code and I wouldn't really know where to begin to put up some generic code to get somebody started with it because every app is different in how it's going to work and what will need to be tested and how the AI should be implemented. But the idea is there and should give you a bit of a start on where to go with the testing process.
There are a few options here for getting the numbers in. Find access to a bunch of computers and get a couple more friends etc to run a few instances of the app at the same time to see how it goes. Next best is to have a few computers running many instances of the app on one HTML page. Essentially you embed something like 10 instances in one HTML page, passing in flashvars that are all different (user IDs, usernames etc) and then they all start acting on their own with your AI code. That kind of testing will generally work with a few good computers that can handle the load of a bunch of instances running at once. Saves you from opening 10 instances of swfs too. If you don't have nonscaling on then you can squish the app size down a bit. Then you watch the server load and maybe have one dedicated PC that is running one instance of the app to see how it handles the load of 100 users or so.
Of course, the very best is to get real humans to jump in on the app. There's nothing like having people come in and double click stuff and do things out of order (at least in your head) or slightly later or earlier than you expect them too. That's when the holes in your app can show up and perhaps begin to place odd loads on your script and the server.
Well, with a little searching around I've got more info on FMS3. I knew I had read about some more info somewhere but just couldn't recall it when writing the last post.
Anyways, here's an informative PDF on the issue straight from Adobe. Along with an HTML version of all kinds of FAQ stuff on FMS3 (kinda like the PDF) and the press release is here.
The information is about 3 months old though... good for me to be right up on the times..
Anyways, I'd have to say that the most exciting features in there for me are:
- Server-side republish (even though you can kinda do this now, it's commonly requested)
- H.264 and AAC streaming support (going to be nice to get away from FLV's)
Speaking of that though, have you seen this post by Tinic about the new file types coming out? Neat.
- Improved performance (although I did mention this in the last post, I'm really happy about this)
- Mobile video delivery to Flash Lite 3 (this is very cool, looking forward to playing with this)
Delivery in the first quarter of next year? Sounds good, looking forward to it.
On a side note, if any of you have been visiting the newly released fmsguru.com site and tried the video tutorials and they all seem to be the same one.. I've fixed that problem now. They should all work as expected. Sorry for the glitch.
I'm kind of curious as to what others are thinking about the new version of Flash Media Server that should be coming out soon (I hope). Here is a bit of information via Kevin Towes (have to scroll down and click the "protecting and distributing content with FMS3").
There is some good info in there on some new features and I'm sure more will leak out soon (can't imagine they were all in that one preso). Looking forward to seeing those, and of course as soon as I find them I'll post here just in case.
But either way, I think I'm definitely looking forward to some changes. Here are a few of my requests:
- Better licensing scheme
- Better pricing to go with that better licensing scheme
- Multicasting
- Better performance (which they say they have done)
- Screensharing would be really nice, but that's a flash player issue..
- Not sure if I care too much about DRM.. but lot's of others do. So having it and knowing about it is good for business
- Did I mention pricing and licensing changes?? ah yes.. I did
- AS2 or even AS3 on the server side. Prototyping everything is getting like working on something antiquified.. like a commodore 64 or something. Not too efficient or clean sometimes
hrmm.. lots of others I'm sure but I'm more curious as to what others have taken out of that presentation by Kevin and what they would like to see further change with FMS.
Right now demand for FMS is good, I'm never ever out of work and most of the other FMS devs out there that I know are booked up for months with stuff. It's crazy. But at the same time there isn't a high demand for FMS stuff thanks to the lack of information about FMS and how to develop for it, which makes for a bit of a steep learning curve to get in, and then the licensing and pricing for it right now. For information, there is of course flashcomguru, my blog, fczone, the newly released fmsguru.com and a few others (sorry if I don't recall them off the top of my head, stick them in the comments if you know of any and I'll update this post)... I guess there is also Adobe's site, but that's a given.
If you were to compare the Coldfusion community, or Flash community or Photoshop or After Effects community, FMS community is pretty slow. The mailing list that Stefan runs off of flashcomguru is almost non existant lately. New people just aren't getting into it lately. Makes me wonder.
But, I'm all for seeing FMS apps get developed and for more FMS developers to come out and show their stuff. I still feel (even though the entry point is high) that FMS has huge potential, it's just that Adobe needs to put a bit more muscle behind it. Hopefully FMS3 will see that muscle and a big push will be made to get it out into the public much more.
Anyways, any thoughts on the above would be great. Please post in the comments.
I've been getting a few questions about developing for Flash Media Server with Flex. I sometimes am not too sure if it's for Flex 2 or Flex 3 so I'm going to just quickly post a quick tip if any of you are using Flex 3 beta at all.
When it comes to developing server side, it can be a bit of pain if you don't happen to have the API memorized because no editors that Macromedia (did) or Adobe (does) put out have the ability to understand ANY of the API's for either client or server side. I think dreamweaver has a bit and the Flash IDE has a little.. but not nearly enough.
To help with that there is a plugin for Flex 3 by Darren at FCZone. This is brilliant. What it does is allow you to create FMS application projects and then it helps with code hinting etc when you go to develop those apps. Definitely check it out if you are using Flex 3 at all and do some or lots of server side coding. Then again, if you do lots of coding then this might not help too much, but I know for sure that I have to refer to the livedocs every once in a while because I still use Sepy for my server side stuff.
Anyways, about the Flex and AS3 questions, I'll do my best to get some answers up soon. Just been a bit busy with some projects here.
I feel like some kind of weird geeky superman of sorts.. worker by day, tutorial writer by night or something.. Anyways, as I mentioned in a past post here we're putting together a new community site that revolves mostly around tutorials for Flash Media Server and Flash development. I'll talk about more details on this later.
Currently I've got most of my articles up on it from this blog and plan on putting up a couple more in the near future but am also concentrating on getting video tutorials up. Got four of them now with another coming today. I'm planning on having the first 10 or so to most likely just be covering the basics to get people up and running. This will build a foundation into more intermediate topics.
It's not that I can't think of about 2 billion things to talk about but I think I'd like to hear what the community is looking for. I'm sure there are exact items that people may be confused about and I'm interested in knowing what those are. If you happen to have anything that hasn't been mentioned in this post's comments then please post below so that I can plan out how and what order I should be putting tutorials up.
I'd say if all goes well, the new site should be up and running later on this week, or at the latest the beginning of next week. I'm pretty excited about it and hope it helps more people get into FMS and develop some cool stuff.
On a side note, this site will most certainly not be a closed tutorial admission format. If you have articles or video tutorials that you'd like to post up then that's great. I'll definitely provide more details on how to do that in the very near future.
This most definitely doesn't pertain just to Flash Media Server, but it's a good question that I think quite a few people ask themselves when working with FMS2.
The question: I'm having trouble viewing streamed video, it starts and stops a lot, what's wrong here?
The answer:
To start off, let's talk about video file encoding. Video files can be encoded in two different ways, CBR (constant bit rate) and VBR (variable bit rate). If you were to encode a file with CBR at 600 kbps then throughout the whole video it would be 600 kbps, even if there wasn't really a need to have that much information.
Whereas, if you were to encode in VBR at 600kbps, the encoder would change the bit rate based on whether or not there is a lot of information changing around etc.
So on that note for FMS, and progressive streaming for that matter, it becomes a bit more difficult for the player to properly buffer VBR because the bit rate is always changing. For CBR it becomes rather simple because it's easy math. Meaning, one question you need to ask yourself is whether it is more beneficial to encode in VBR or CBR.
This all goes down the toilet of course if you have a bad network connection that drops or just gets really bad at times and then good at times. Buffering is a bit of a science and I've got just the article for you to look at if you want to learn more about that and how to more smartly buffer video. Thanks to a super video genius, Fabio Sonnati, we all now have this article to refer to when we want to learn how to buffer video in a more intelligent way than just setting the buffer via the netStream object.
So essentially, if your video is stuttering or stopping and starting a whole bunch of time then most likely you aren't buffering properly. See the article above on how to deal with that in a better way than you are now.
I actually receive and see this one on forums quite a bit so let's see if I can shed a bit of light on things.
The question: I'm having trouble viewing streamed video, how can I confirm the server is working?
The answer:
First thing to do here is supply a link to a previous article I wrote on this subject:
http://www.sti-media.com/blog/archives/000217.html
So that's how you would setup the server for the FLV file.
For the flash side, let's cover the basics.
1. Open a new FLA file (flash 7 and up)
2. Go to the library and click the menu button and choose "New Video"
3. Choose "Video actionscript controlled"
4. Once the video object is on the stage, select it and put in an instance name of "vid" for now.
From this point forward I'll just post some quick actionscript to test if video will play from a server. We'll use the video file "myVideo.flv". So just substitute that in the code for whatever you are using. (sorry about the code unfriendly blog here..)
//create a netConnection
var nc:NetConnection = new NetConnection();
//create the net stream to play the video
var ns:NetStream = new NetStream(nc);
//attach the net stream to the video object
vid.attachVideo(ns);
//handle the information objects from the net connection
nc.onStatus = function(info){
if(info.code == "NetConnection.Connect.Success"){
//connection success, play the stream
playTheStream();
}
}
//function to play the stream
function playTheStream(){
//0 is for a prerecorded stream, -1 is to play it until it ends
ns.play("myVideo", 0, -1);
}
nc.connect("rtmp://MYSERVER/videoApplication/videoplayer");
That's pretty much it. If your video does not play in the screen when you publish that file and you are connecting up successfully then you don't have the video file in the right spot. Double check that.
If you can't connect up then double check the connection string to see if you have the right server, right application and actually check to make sure the server is running and the ports are open that you have set for the server.
That's all folks.
On that note, I will be moving forward with the video tutorials. I even have a brand new domain for them and will post more information on that in the very near future. If anybody can guess that domain I shall send you a big delicious chocolate chip cookie :)
Wow, the big three one.. almost as many tutorials as I am old. It's been a while since I've posted an FMS guru question up here because I've been responding privately with a few that just wouldn't pertain to most and found it a bit tough to write a more generic post for it. Anyways, this question falls under that category nicely, so here goes.
The question: How can I move FLV files that have been recorded with Flash Media Server 2 to another server?
The answer:
This is actually a very common request from clients and friends alike. How to get those FLV files off of the FMS server and over to the web server to played progressively.
I'd like to first start with giving a bit of insight as to why somebody would want to do this.
1. FMS2 is a lot of money for one pro license. If you can keep BW and connections to a minimum then you won't have to buy more licenses to keep up with demand. In the case of recording video, you need a connection and need to use FMS bandwidth, but not for playback. That can be done with a web server and save that cost.
2. Sometimes you just don't want to stream files and let people download the FLV to be cached for quicker playback later. It does have the drawback that the user can't seek ahead before download, but see #1 and think on the cost savings.
3. Sometimes you want both and of course FMS should be on it's own box. In this case you will need to copy the FLV files over to the web server, wherever that may be.
So how to do this?
It's going to depend on if the servers are on the same network, like an internal one maybe. In this case it's reasonably simple to make a small bit of code in a batch file or something to watch a particular folder. If a new file is put in the folder then copy it over to the other server. Unfortunately this is a rare problem for most and it's a requirement to get the files over the internet to another server.
My first and pretty much only suggestion would be to use FTP to move the files. It's just a matter of how to do that.
You can setup most FTP programs to watch a folder and when a new file is in there to copy over to another server. Or just setup a timer. The person asking this particular question is asking how to do that in ASP.NET. I don't know for sure, but I'm positive there has to be some kind of plugin(or maybe just straight out of the box) that will allow you to do FTPing. I've done it with ASP, so I would guess that ASP.NET can too.
Other than that there really isn't any other option. I suppose if you can setup virtual folders over the network then you can have FMS just record straight to another server (I've seen this done) but it's iffy when you then have to worry about network speed etc, so this is best practiced within an internal network.
Hope that helps a bit.
Lately I've been kinda juggling around in my mind whether it would be worth it to put together a set of tutorials for FMS/Flash best practices for the beginner/intermediate developer. Anybody think this is a decent idea? Would you check them out or is the internet already too saturated with beginner/intermediate tutorials?
My idea is to put together some kind of application that will take advantage of all the aspects of Flash Media Server and touch on all the topics while building it. Kind of a "this is how I build stuff" kind of thing. Any thoughts? Would that work or are certain topics a better way to go? Like, "these are shared objects and how to use them" and "this is how to stream a video file" etc.
Just kinda tossing some feelers out there. Let me know.
**UPDATE 11/07/2007**
The site has been launched. It's called FMSGuru.com and can viewed at www.fmsguru.com.
The question: How can I record a stream from Flash Media Encoder on Flash Media Server 2?
The answer:
I actually get a lot of questions concerning FME but since I don't use it much myself (it crashes on my main computer and won't start) I usually don't have much of an answer. This also tells me two things about this piece of software that Adobe has pushed out, that is that it's getting attention because it encodes video with on2's vp6 codec and people like that because the quality is better. The second is that if I'm getting so many questions, there must be a lack of docs out there. Oh well, gives me something to write I guess.
Anyways, the deal here is that a lot of people want to record on FMS2 instead of just saving the FLV locally and then uploading some huge honking file to their server.
The way to do that is actually relatively simple. Surprisingly enough.
In this case we need to have the server side of the application watch for when a certain stream is published. The only drawback with this is that we have to actually hard code in the stream name on the server side. I suppose that isn't so bad though.
First up is writing the server side code. We have to get the stream that we want to record to. This can be anything really, for the time being I'll just call it "recordvid". Notice it's all in lower case, this is a best practice in the case that you ever have to move to a unix server from windows because unix servers are case sensitive and it's easy to not play the file based on incorrect case.
So we start the application as so:
application.onAppStart = function(){
//get the stream to record to here
this.recordStream = Stream.get("recordvid");
//keep an eye on the status of the stream, we'll need this to see what's happening with the stream
this.recordStream.onStatus = function(info){
for(var i in info){
trace("i: " + i + " info[i] " + info[i]);
}
}
this.recordStream.play("vid", -1, -1);
this.recordingStream = false;
}
That's it for now. Now just publish a stream from FME that is called "vid". It should show you the following in the FMS2 admin panel:
i: level info[i] status
i: code info[i] NetStream.Play.PublishNotify
i: description info[i] vid is now published.
i: details info[i]
As you can see, you can capture the event of when the video file is being published. From this point, you just call the record function:
application.recordStream.record();
When you stop publishing to the server, you'll get this trace of the information object:
: level info[i] status
i: code info[i] NetStream.Play.UnpublishNotify
i: description info[i] vid is now unpublished.
i: details info[i]
So you can see when you should stop recording. Which is done like this:
application.recordStream.record(false);
That's about it.
The question: What are the limitations on filenames when recording a stream to FMS2?
The answer:
I used to know where this was documented but can't find it anymore. I'll keep looking. Until then, my opinion has always been that the file name has to be URL safe. So no weird characters like question marks or colons etc. I thought I had heard a while back to not start a stream name with a number so I always start mine with a character, usually "stream_" or "userstream_", or word.
I'll look around a bit for a better answer but either way you can't go wrong with the above.
Keep in mind that Windows machines are case insensitive and Unix machines are. It's a good practice to make all your stream names lower case so you don't need to worry about that later if you ever move from Windows to Unix.
Something quick, fast and easy here. Almost falls in line with the RTFM mantra actually. But I'm not one to just say that, so here's some direction hopefully.
The question: How can I get (in the server side, main.asc) the IP of client requesting connect?
The answer:
There's a property of the client object called "ip". Grab that.
Here's a direct link to the docs actually. But here's the code copied and pasted from there:
application.onConnect = function(newClient, name){
if (newClient.ip == "127.0.0.1"){
// Insert code here.
} else {
// Insert code here.
}
};
Just a quick question here. Was going to just respond by email but thought that just maybe others might search for the same thing.
The question: Can I execute an external command or program from main.asc?
The answer:
Nope. The best you have for something like this is loadVars to load a web page that may have server side code in it to run a command. Flash Media Server alone on the server side can not run an external program.
Which sucks.. and a lot of people have made requests for this. Maybe we'll see it in future versions.
Lots of questions coming through lately, I'll try to keep up. Here's one that has no good answer unfortunately but may be good to know for others if they are thinking to do the same thing. Two questions here:
The question: Is there a command or a way to trim an FLV audio stream at a particular location? and, Is there a command to append or combine two audio streams without replaying them and recording them into a new stream?
The answer:
The answer to both of these questions is an unfortunate no. The only way to trim up an audio only (or even a file with audio and video) is to record that stream again to another FLV and just stop it where you want it cut.
Which leads us to the next question on combining two streams. This would sure be a nice feature if FMS could do it. Combining streams into one would be quite cool but I don't expect it in FMS for a while. Again the only way to combine some streams is to play one server side and record it to a new stream (you could just append to one of the files I suppose if you don't need to keep it as is) and when that stream finishes playing then just play the next stream and append it to that new stream.
I sorta covered that topic here.
I suggest for these items to make a request to the FMS team themselves from here: Adobe Wishform
This question actually comes up quite often on mailing lists and forums. I thought I had addressed it in the past here but it seems I didn't. Perhaps at a seminar or something...
anyways,
The question: How do you detect when a user loses connection to the media server via network connection loss?
The answer:
Lucky for this person there just so happens to be a new thread started up on flashcomguru.com's site.
Thread is here (detecting ungraceful disconnects)
Making a long story short for this blog entry, because the answer is in the post on the forum, FCS and FMS have had this problem since it first came out and hasn't quite been addressed in any updates. There supposedly were some improvements made in that area in the latest update but I've never tested because I have found that the workaround code (there are a few out there) works just as well.
Here is another post on the forum too just in case. It's a bit of an older one and covers more on keeping a client alive when they go idle or for some reason get disconnected for no particular reason. In a way, they both are the same type of problem.
Going through my emails, I found this lost and forgotten question that I had mostly likely thought to answer when I got a moment. Well.. now that it's almost midnight I think I have a moment
The question: Is there any way to get debugging when the application itself won't load?
The answer:
The good news first. Yes there is.
The bad news, you have to look through the logs to find where the issue is.
In the past with FCS 1.5 and the admin panel that was used with it (which in fact you can also use with FMS2 for this particular purpose), the debugging panel that showed the traces in the application would stay open even if the application failed to launch properly. That way, you would be able to see traces to see where the problem was.
In the case with the new admin application for FMS2, when the application shuts down, the application panel in the admin app would just close. This in turn doesn't let you see if there were any traces that might indicate where the problem was.
Unfortunately the only real way to debug FMS apps is to use traces.. it sucks, but that's another topic all in itself.
So the application logs are all sitting in the install directory of FMS in the logs directory. You will want to look in the application00.log for the latest stuff. In there shows everything that you have been looking at in the admin application panels.
So that's it.
This is a good question about Flash Media Encoder that has just recently popped out from Adobe. If you happen to have Flash Media Server, then this is free to use with it.
The question: How can I interrupt a stream from Flash Media Encoder to FMS and put in place a previously encoded stream?
The answer:
This isn't as difficult as you would think it is actually. The deal with the Flash Media Encoder (FME) is that you can publish to FMS. FME publishes straight to an application on FMS and then subscribe to it from any client side. Even though the encoding side (FME) needs the special player because it's encoding VP6 video, the Flash player can actually just play that natively and of course FMS can stream it natively.
So that's a bit of background.
What needs to be done is a bit of coding on the client side to play certain video streams based on what an "administrator" tells them to.
So the order of business would be so:
1. Create a SWF that takes orders from the admin side on what stream to play.
2. Create the SWF that gives the orders to all the clients to tell them what stream to play.
3. Setup FME to encode to a specific application that both the admin and client side connect to. Obviously setup the stream name to something static.
Now, to make this as easy as possible I think that no server side code is needed. You could just use a shared object. So, the admin side would set a value that would be the stream name. The client side would get the update that the SO has changed, or when they first login they could grab that value, and then just subscribe to that stream. Whenever that value changes by way of the admin side, the onSync method runs on the SO and each client changes which video they subscribe to.
This way, you would be able to change from live to saved FLV's rather easily I think.
That's about it.
On a side note, I've just chatted with a DevNet Adobe person and it looks like maybe I can write an article about this and post it up there. Could be useful? If so, then I'll write it out, but I suppose if there aren't any votes for it then it might just get tossed off to the side as something that just may not be required or wanted in the community. So let me know!
Have to apologize on the delay for this question here, I've been overwhelmed this past little bit with all kinds of work.
The question: Does each NetConnection execute the server side script in it's own thread?
The answer:
Each NetConnection does not have it's own thread, but it does stand in line in one thread that lives on the server side.
For some reason, and this has it's own pros and cons, FMS still only works on one thread on the server side per application. So, if you start up an application then a thread gets created and within that thread everything runs in the order that it is received.
This can be good in ways because you can control the order in which something will execute, but at the same time it's limiting in what you can do because you have to wait for a loop to end first or something.
So, this question actually has an explanation with it and that is that this particular person is having trouble dealing with lots of users logging into the application and making remoting calls to a DB.
Sometimes in an application you may have a lot of people do the same thing at once. Logging in is a good example. In the case where you have to do something before actually letting them do something else like accepting their connection, you can put the client in a queue. Meaning that they get placed in a lineup to wait for a return object, like from a remoting call, before they can move foward with whatever they will be doing.
So, the deal with this person is that sometimes calls would made at weird times, like there is a huge delay. At least as far as can be seen using a trace statement.
Unfortunately with FMS this can happen, but more importantly the trace may also just be delayed. I've had some tough times telling which it is.
Without looking at the code it's really hard to say what the problem could be, and the best I may be able to do is just point out that some people have noticed FMS is a bit buggy concerning making remoting calls. Sometimes it's delayed and sometimes it doesn't do anything at all. In these cases, it's best to make sure Adobe knows that you think there is a bug because they really want to know what it may be and actually fix it.
Adobe's bug reporting page is here.
I find it interesting sometimes that this type of question still comes through. It means two things to me. One is that Adobe lacks easily accessible information and examples on FMS, or I suppose at the very least the information isn't in obvious spots. Two, there are still new people coming to FMS., which is always good of course.
anyways...
The question: How do I record sound using a microphone and then send it to the server?
The answer:
This isn't so tough, but my concern with the wording of this question is that the user thinks that perhaps it's possible to record the microphone client side and then save it on the server.
If by chance that is the case, then it isn't really possible. The best you can do in that area with just flash is to buffer a lot and then have the flash player "upload" it to the server. But in reality, it's not saving it anywhere in hard memory and is deleted if you close the flash player. The reason you might want to do something like this is if you are concerned that the user's bandwidth is much lower than they may need to stream the audio up to the server. So you buffer it on the client side (usually if it's under 30 seconds of audio you should be ok) and then flush the buffer when it reaches the limit.
So, how about some code then:
I won't cover making a net connection to the server and all that because I've talked about that in the past and there really are lots of examples of it (every FMS app needs to connect to the server..)
Once a connection has been made to the server, let's call a function called getMic()
Assuming the netConnection object is "nc", netstream to publish the mic is "ns" and the microphone object is "mic"
//this function will get the microphone object and set some parameters for it
function getMic(){
//first we need a netstream object to connect the mic to
ns = new NetStream(nc);
//set a small buffer
ns.setBufferTime(2);
//we need the microphone object now, get the default mic by passing in nothing in the parantheses
mic = Microphone.get();
//set the quality of the microphone, this can be set to 5, 8, 11, 22, or 44
mic.setRate(22);
//attach the microphone object to the netstream
ns.attachAudio(mic);
//and publish it to the server by passing in the file name and record command. If you want a live stream, then just pass in "LIVE" instead of "RECORD"
ns.publish("myMicrophone", "RECORD");
}
and that's it really. There are a few other options for the microphone which can be seen here on the livedocs for FMS.
Oh good, an easy one :). Got a question asker here asking how it would be to tell a user why they were rejected from connecting to the application.
The question: How do I tell a user why their connection request was rejected?
The answer:
So, the deal is that you have an application with a bit of security on it. Which is of course always a good idea because you never know when a malicious user is going to come along and create some huge FLV files or something on your server.
For example, say you stopped users if they didn't pass in a username when connecting to the server. On the server side you might write something like this:
application.onConnect = function(clientObj, userName){
//no userName value passed in? or an empty string?
if(userName == undefined || userName == ""){
application.rejectConnection(clientObj);
}else{
//looks good, they have passed something in
application.acceptConnection(clientObj);
}
}
Now, that isn't so robust and is relatively easy to get around.. but makes for a simple example on how to accept or reject a connection based on certain circumstances.
In the above case the user will get rejected and you can handle that event on the client side with the onReject event that gets passed back to the netConnection object, but you don't know why you were rejected. In our coding, we only have one reason why somebody would get rejected so it's easy to tell, but what if there were a bunch of options? Like maybe, the user is a banned user, or their password was wrong, or it's too early etc.
To pass back some information you would create an object that can hold the error message and pass that in the rejectConnection method. Something like this:
var errorObj = new Object();
//pass back a message of what is wrong
errorObj.msg = "Password is wrong";
//or even just pass back a predetermined code number that you think of
errorObj.code = 1;
application.rejectConnection(clientObj, errorObj);
Then, on the client side you could catch that like so:
nc.onStatus = function(info){
var code = info.code;
if(code == "NetConnection.Connect.Reject"){
//trace out the string message that was set
trace(info.application.msg);
//trace out the preset code that that was set
trace(info.application.code);
}
}
So, based on the information that you can get out of the information object in the onStatus event, you can now tell why you were rejected and incorporate that into the application by maybe retrying to a different server, or showing the password screen again or letting the user know they are banned, or whatever :)
Streaming video from FMS is probably one of the most common uses of the software. Here is a common question that I've seen:
The question: I want to serve multiple FLV files from FMS2. Can this be done in a simple way?
The answer:
A bit of background just in case.
There are two ways to stream FLV files at the moment. You can serve them from a web server (and there are a couple of ways to do this) or you can serve them from an FLV streaming server which in our case is Flash Media Server 2.0.4. Currently there are two other pieces of software out there that can stream FLV files. Red 5, which is an open source option, and Wowza which is a commercial product that works somewhat like FMS.
The difference between serving the files progressively (web server) and streaming is mainly that the file doesn't get cached on the client's computer and in theory is served faster to the client. There is a lot more information on the internet on this, so that's all I'll cover for now.
So, the idea is that we are going to use Flash and Flash Media Server to stream an FLV or multiple FLV files to our clients.
First up, let's get FMS ready to stream a file.
When installing FMS you will get a directory called "applications". It usually resides in the installation directory of FMS, but you can put it anywhere, and in fact are encouraged to move it elsewhere. But this isn't a chat on security or performance so I'll stay away from that for the time being.
In the applications directory, let's make a folder called "videostreaming". This is necessary to have clients connect up to the server itself and also a place to put our video files. Now it's important to note that you can put your videos in a central location, or multiple locations and specify those locations as virtual folders for FMS. That lets you keep videos in certain places on your server and access them from different applications. Handy.
So, we have the folder in the applications directory "videostreaming". In there, let's make a directory called "myvideos" and in there create another folder called "streams".
So:
applications-|
--------------videostreaming-|
--------------------------------myvideos-|
--------------------------------------------streams
In there, we put our video file. For this example we'll use the video file name of "video1.flv".
We have now setup FMS, let's move to Flash to build the client side.
To do this the most simple way I won't be covering controls for the video. Just how to start playing the FLV file.
Open up a new file in Flash and select the first frame and open up the actions panel.
We start off by creating a net connection to the server and then we'll watch to see when we connect up. Once connected up we will create a stream object and then play the FLV file. Playing the FLV file and showing it actually requires we make a video object, so we'll do that after the actionscript.
//create a netConnection object
var nc = new NetConnection();
//keep an eye on the status events, we need to know when we have connected up
nc.onStatus = function(info){
if(info.code == "NetConnection.Connect.Success"){
createStreamObject();
}
}
//this function is called once we have connected up to the server
function createStreamObject(){
//this is the netStream object that plays the video file
ns = new NetStream(nc);
//attach the video stream to the video object on the stage
vidObject.attachVideo(ns);
//play the video file that we put in the directory for the application
ns.play("video1");
}
//connect up
nc.connect("rtmp://MYSERVERIP/videostreaming/myvideos");
As you can see above, we are connecting to a server with the application name of "videostreaming" and the instance name is "myvideos". We put that in because that is the folder hierarchy that we created on Flash Media Server.
All that is left is to create a new layer in the timeline and make a new video object from the library panel menu. Place that on that layer on the stage and call the instance name "vidObject".
That's it! Run the file and you should have a video playing on the stage.
If it doesn't work, you need to find out if you are even connecting up to the server. That would require opening up the FMS admin panel and seeing if there are connections being made, and if there are then double check the filename and mistyping.
That is the most simplistic way to stream an FLV file. There is also the option to use the FLVPlayer component, that's a pretty good option too I think.
This info is a couple of days old but that won't stop me from mentioning that the Flash Media Encoder from Adobe has shipped out to the world. I talked about this a bit in a past post. Now it's out of beta it seems. I wonder what they timed this for?..
You can go get that here if you have FMS2.0.4 installed on a machine somewhere or have at least access to one.
Unfortunately for me it has never worked, but I have seen others have no problems. So go check it out!
This is a tough one, I've not tried what I'm about to suggest, but I think it would work. If I get some time, I'll give it a shot though.
The question: How could you create a time delay (say 5 minutes) on a live stream so that an administrator/editor could stop a broadcast if an event needed censoring?
The answer:
You can't really, not with a live stream. If you wanted to create a slight delay you could just set a really high buffer so that the stream wouldn't start right away for the end user. But other than that it would be a matter of recording the stream as you are publishing it live and then playing that recorded stream.
This would be a bit tough because what if the stream was only at 3 minutes? How would you know how long the stream is? If the stream hasn't finished recording, I don't think you can actually get a duration on it, meaning that you couldn't seek to a point 5 minutes before the end of it to start playing. This being that the end isn't really the end, it's the live point of the stream.
I've never tried, but that's what I would do I think. Just publish from the client, play it server side and record and then try to play the recording stream. I'm pretty sure you can play an FLV as it's being recorded.
I've got an email here with quite a few questions about FMS, so I'm going to cover the related ones bunched in a separate posts just to make it easier to read over later.
These are all great questions and come from a person who is not already working on Flash Media Server and Flash, which I like to hear from because it helps me get out of my box a bit. By a box, I mean that since I'm so used to FMS, I don't really think about some of the worries that others might have if they have never touched the software because I know that those aren't the difficult issues. Anyways, on with the show then:
The question: First, how difficult is it to administer FMS if our IT folks have little or no training in ActionScript?
AND
How easy is it to learn?
These are related questions I think, so lets see if I can cover them a bit here.
The answers:
To administer Flash Media Server, little or no Actionscript experience is needed I think. Now, I could be wrong in what "administering" means, but I have the impression that this covers install, settings changing and keeping an eye on applications and instances of those applications.
So to do that, all you really need is experience installing software and then stopping and starting services when you make changes to the settings. For the settings, it's all written out in XML and can be viewed with a common text file reader like notepad if you use Windows. THere are about 6 settings files in all and are full of comments on what each setting does, so it's not too easy to get lost there. Although I have found that some are a bit cryptic, those are the ones you don't really need to mess with. The Adobe techs have done a pretty good job there.
The only area that you need actionscript experience and knowledge is actually creating the applications. Both the client and server side coding is in actionscript. So I suppose in a way, if you had actionscript knowledge, it might help you administer the application if you could understand why a certain application is sucking up all the resources of the server or something because then you would be able to look at the files and see the problem. I'm not sure if that falls under administration tasks though.
The next part is whether FMS is easy to learn. Now that's a bit of an interesting question in itself, but I feel the answer should be yes. In reality, you don't need much knowledge at all to run applications on FMS and I think in the case of this person, they want to do lots of video streaming. Video streaming is simple really, I think there are free players out there that work with FMS, or even just the FLVcomponent in the Flash IDE works great. Place your videos on your server and you're just about done. So, in that respect, learning how to develop applications with FMS is not hard.
It will all depend on the application and how much functionality it has for whether or not the development learning curve and even administration difficulty will be.
So to sum that all up somehow, I feel that administering Flash Media Server really isn't that hard. Install it and for the most part just leave the default settings as they are. There are a couple of items to change, but the rest of the defaults work great for most apps. When it comes to actually using the technology for your own sites and apps, then the level of difficulty on learning to develop on it will be directly affected by the amount of functionality that your app has. If you already have a good knowledge of Actionscript, then developing shouldn't be too hard at all, you'll just need to understand how live apps work now and the things to think about when developing them.
Well, this is pretty good news I would say. Adobe has finally put out a standalone application that will stream vp6 flash video to Flash Media Server for your viewers. Not only that, you can record the video at the same time you are streaming it, which is always handy.
The application is called Flash Media Encoder, very aptly named I think, and it's free right now and will always be free if you have a valid license installed with your Flash Media Server install.
The bonus of this is that you can finally send video up by VP6 instead of the sorenson codec that the flash player has. We'll probably never see VP6 support for live streams in the flash player so this is going to be very nice to have.
It's in beta but it still works for the purposes. Details are here.
Flash Media Server 2 has a new update out, version 2.0.4. Another release comes out the door! I bet you're wondering what it fixes? I hope it deals with a lot of issues because as far as we and our clients are concerned the last stable version was 2.0.1.
Here is the link to the release notes so you can see what was fixed. The biggest one was definitely the license issue.. good to see other stuff getting fixed.
Two questions popped in yesterday so here we go.
The questions: Is it possible to record directly from the viewer's screen?
and
Can we record to swf format instead of FLV?
The answers:
I'm not quite sure I understand the exact problem here so this is the first thing that comes to mind to do what you want: You can record the screen with a screen capturing driver. Here's a nice free one. This can be recorded to FLV by FMS through your flash application. If you are looking to record certain actions, like from a whiteboard etc, then you can record the "event" to data in the FLV file, then make a custom player that will re-enact these events when the file is played back.
The only way you can save to an SWF is with a third party software like Camtasia. FMS can't do it, and you can't do it with just flash. You also have the option of recording to FLV and converting to SWF. I think there are a few bits of software out there that will do that.
Not the most positive of answers but those are the current limitations. Hope it helps :)
I'm trying to stay positive here and that we WILL see another version of Flash Media Server. Due to the complete lack of new material about FMS on Adobe's site nor at the huge MAX event in Las Vegas (and other Max events around the world), it's a bit tough.
But anyways, the product manager of Flash Media Server, Steve Wolkoff, has decided to let you post on his blog what you would like to see in the next version. So, go tell him. Let's pray that it doesn't take them as long as it did to get to FMS from FCS though..
I have to say though, we (FMS community) have sent tons of opinions and ideas to him, to have to again start from scratch and write them all down is a bit frustrating. I would hope that it wouldn't have been too much effort to say something like "this is what we have received so far," (and list them) "any votes for these items or anything else to add?". I think that would be a bit more helpful to the cause and shows initiative and respect towards all that have worked hard to see FMS grow and improve. Although I do appreciate the fact that he is now publicly asking. So once again, go hassle him :)
This is an easy but slightly obscure problem to fix, most probably wouldn't be aware of it unless coming across it themselves in the past.
The question: When I encode the video and save it on the server, then later playback the FLV I notice the "metadata" is missing (duration in particular)?
The answer:
Upgrade. One of the older versions of 1.5 was missing the duration value when creating FLV files.. I can't remember which one. Upgrading to the latest build of 1.5 (if you can find the upgrade files somewhere) or using FMS2 will get you the duration value in the FLV files.
On a related note, the first version of Sorenson Squeeze 4 also had messed up metadata, a lot of people were relying on Burak's FLV metadata injector actually. Something to keep in mind perhaps.
It just so happens that last week we had about 5 new people send in emails or comments of some sort asking if we do just consulting for Flash Media Server and/or Flash Communcation Server. Odd timing.. but to set the record straight:
Oh yes, in fact that is our speciality. I find at least 90% of my day is working with FMS and Flash with the other 10% going to server side coding with databases.
So if you were wondering before, now you know for sure. We live and breath FMS/FCS here, and consulting is just one aspect of the job :)
Need to get a hold of us? Contact us here:
http://www.solid-thinking.com or here: http://evo.solid-thinking.com, or talk to us live here at our live support.
I kinda wondered how they would even police this kind of thing a long time ago, but now it's official, you can use FMS2 for commerical projects for free!
There are a couple of restrictions on that usage. one being that you can't cluster them, or load balance them to create a huge network of dev FMS's. Makes sense, can't imagine somebody would bother doing that anyways. You only get 10 connections.
Anyways, this is great news!
Wow.. this is such an open ended question I'm not quite sure where to start. Fortunately, I was able to get a bit of background information on the project and can hopefully offer a bit of direction for it here.
The question: What is the best way to handle the connected clients on the server side?
The answer:
Well, to bring this into a scope that I can handle in one post I'll quickly go over the goals of this particular developer.
First up, the application is a type of chat application and some users will be in private chats with each other along with a lobby area I think. The main goal here is to be able to tell only the users that are connected up together in one "private room" that somebody has logged off.
Now, I'm guessing that this developer has set it up so that all users are sitting in one application. In other words, all users that are connected to the application, whether they are in a private chat or not, are connected to this one application. The idea here is to make sure that we only tell the right people that we have left this private chat.
So perhaps first we'll look at how we would usually tell all users that a particular user has logged off.
On the server side we would put a function in the onDisconnect method. This will fire on the server side whenever somebody logs off. If we were in a one room chat I would probably just use the method broadcastMsg() of the application object.
Something like this on the server side:
application.onDisconnect = function(clientObj){
application.broadcastMsg("userLoggedOff", clientObj.userName);
}
Something like this on the client side:
nc.userLoggedOff = function(userName){
myText.text += userName + " logged off";
}
That's not too hard. But this particular developer only wants to tell certain people.
Now, there are tons of ways to do this. The best way is to have these private chats in their own instances of an application. That way it is foolproof that you won't be letting anybody else know. So, in this case, everybody would connect up to a common instance of the application for the lobby, and if there were private chats, then those people would disconnect from the lobby and go connect up to the private chat.
Of course, there are times when you want the user to also be able to monitor the lobby. So in this case, just don't disconnect them from the lobby and go connect them up to another netConnection to another instance.
The problem with that is that you will now use up another netConnection. Some people don't like that. The next option is to split up chats with Shared Objects.
So, each chat would be it's own Shared Object and people would just subscribe to whatever Shared Objects that pertained to whatever chats. This isn't a bad idea, but if there are enough in one application it could start to bog down a bit by taking up memory.
But in this case, how would you tell only certain users that a user has left the chat? This is where I can start to answer the part on how to manage clients on the server side.
When a client hooks up to the server the onConnect() method runs. This is where you can do your "client management" stuff. I most always create a whole new class for this and name it UserManager or something understandable like that. In here I would do the following:
1. Create a users object that lives in the server memory. This will hold the client objects (everybody who connects up) and anything else I want to remember about them.
2. Create a shared object that will hold the exact same information. This is good for debugging in the admin panel later
3. Accept the connection after doing whatever security checks you need to do
4. Most likely at this point I will set a variable to what room they are in.
By setting a variable for the client as to what room they are in, I can then control who gets what message. There are 2 ways to do this too (at least)
First up is to save the name of the shared object that pertains to the room they are in. That way, when they log out of the application, we just grab that value and make a send() call on the Shared Object. Everybody who is subscribing to that Shared Object will receive that call and nobody else. Or you could just loop through all the clients in the application and if the user has the same room name in their room variable, then make a call() call on the client object.
Keep in mind that Shared Objects run on different threads in the application than the application itself. So it is most likely more efficient to use the Shared Object approach.
I hope that gives some insight on how to mess around with client objects on the server side and what options there are to talking to them based on what is happening inside the application.
Just in case you didn't know, FMS2.0.3 has been released and fixes a few items that may have been frustrating you. Unfortunately it doesn't seem to address a small problem that some people have been having with version 2.0.2 in that the server would incorrectly limit the amount of users that could connect up and say the license limit was reached before it was. Oh well.. I guess they couldn't reproduce it, so it doesn't exist.
At least they got rid of a couple of issues of crashing and memory sucking.
Just recently had an FMS connection hijacker so I thought I'd share a quick tip here.
There are a lot of times when I'll release something out to a bunch of users or even just plain publicly and I want to know where people are coming from. Now, you may be thinking at this point "Why would I want to know where they are coming from when it's my own app?", here goes an explanation :)
Well, with FMS applications it's very easy to actually just connect up to them by taking apart an original application with Actionscript Viewer or something, keeping the basic framework in place and putting your own graphics in or whatever. So essentially what somebody may do is steal connections on your server by hijacking your SWF. Or they may just copy the SWF from their cache and place it on their own site.
Now, if you were really good, you would already have lots of security in place (check out my security preso if you are interested in that area maybe) and don't need to do what I'm about to suggest. But also perhaps you want to see how far your apps make it in the wide world web. For example, I have a "Moving Words" application that was originally placed on this site (doesn't seem to be there anymore though... but I have a copy of it here) but has made it to other sites by people copying out the SWF and putting it on their own site! I don't really mind though, so it's fun watching it go places.
So for example, you have an app, people are using it where you put it, but some decide to either put it on their own site and pretend they made it or something, or more malicious users will decompile the SWF and really change it to make it their own. The first group isn't so bad I think, it's the second group that really makes me shake my head.. anyways, this is how you catch them.
At the top of your main.asc file on the server side, put this in:
application.allowDebug = true;
This will allow you to "debug" your applications. The reason we need this is so we can view shared objects that are on the server in that particular application in the administration panel.
Next up is the creation of the shared object on the server side:
application.onAppStart = function(){
this.usersID = 1;
this.usersSO = SharedObject.get("users", false);
}
We are creating a usersID value to give to every user that connects up a unique ID for every user (useful later) and also creating the Shared Object that is non permanent. You can make it permanent if you want I suppose..
Now, when a user connects up:
application.onConnect = function(clientObj){
clientObj.uniqueUserID = this.usersID;
clientObj.connectStartTime = new Date();
//set the shared object
this.usersSO.setProperty("user"+ this.usersID, clientObj);
this.usersID++;
}
We set some values here to let us know what the client's unique ID is and when they connected to the application. Then we place the client object itself in a slot in the shared object. Once we have done this, we can then go to the administration panel and just click on the shared objects tab, click on the shared object and all of our users with all their info will show up. The key one we want in this instance is the "referrer" value. This will give you the URL where the user is coming from! That's it. Quite useful I have found, just thought I'd share.
Make sure to delete the entry from the Shared Object when they disconnect though:
application.onDisconnect = function(clientObj){
this.usersSO.setProperty("user"+ clientObj.uniqueUserID, null);
}
2 questions for the price of one! Well, one of the answers is simple enough and it came in the same email so...
The questions: Can FMS be used to communicate with a SQL server and serve xml data to a client?
Is it possible for it to serve graphic images such as jpeg or pngs? What methods would accomplish this?
The answer:
We'll start with the talking to databases from Flash Media Server 2 I think. Up until FMS2 you had to use remoting to talk to a database. Now this isn't too bad but it did require a technology that you weren't necessarily going to use anywhere else. Not too attractive to an application architecture manager. One more link in the chain of activities that the application needs to do.
One of the greatest additions in my mind that was added to FMS2 is the fact that you can now talk to any server side page (asp, php, cgi, cfm, jsp etc etc). Of course with that comes the ability to now read in XML from any server out there, it all works exactly the same as the Flash XML object and loadVars object.
There are tons of examples out on the internet on how to do this so I'll skip the example here, but needless to say that if you have used XML or LoadVars on the client side, you can now do that on the server side too.
For the second question of being able to serve up images like jpgs and gifs, no, unfortunately FMS doesn't have this ability. There was somebody who managed to send over the pixel by pixel information through Central (a now dead technology) but it was quite slow. Interestingly enough though was that it was possible. Perhaps Apollo will offer some abilities like that?
Here's a good one that I've actually answered quite well in one of my presentations that are online.
The question: How do you use FMS2.0 to detect which version of Flash and then what FLV file to play depending on users connection
speed?
The answer:
To start off, there are 2 things that need to be done about this, first you need to figure out the bandwidth of the user. You can find out how to do that from this article on Adobe's site from Stefan Richter of Flashcomguru.
Next up is the key to getting the right FLV to a user with minimal setup and future maintenance. Use virtual keys. Rather than explain it in detail again in this post, here is a link to the presentation and you can follow the links to the presentation files that have an example on how to use virtual keys with FMS2.
I will quickly note though what you will be looking for in the preso and the files. You need to do the following:
1. Set the virtual stream directories and keys for each type of user you think you'll have. This is done in the XML setup files for FMS2.
2. Figure out the bandwidth of the client, once you know that you set the virtual key for the client
3. Then just play the FLV file and FMS2 will figure on which FLV file it should play based on the virtual key of the user.
Also now with FMS2, you can detect the users flash version and automatically set the users virtual key, but in this case we need to also check bandwidth. This means we have to manually set the key. But keep in mind it is possible to have FMS do everything for you if all you are trying to do is test the flash player version.
It's that easy thanks to the new functionality in FMS2. I hope that helps.
This one is a very good question and actually comes up quite often. I've seen it on forums and mailing lists. It gets answered but I guess people don't want to search. So it makes a good quick tutorial here on this site with all the rest of them :)
The question: Is it possible to insert or overwrite into the middle of an audio stream?
The answer:
Yes. You have to do this server side though.
The theory:
What you need to do is make a copy of the FLV up to the spot you want to insert your new piece in. Then you play the new piece and append it to the original. Then you take the remainder of the FLV and append it to the new FLV you are creating. This is really hokey and actually requires you take the complete time that both FLV files have. If you have a 5 minute FLV and you want to add in a short 20 second clip to the middle of it, this process will take 5 mins and 20 seconds.
So you take stream A, the original stream you want to add something into (all of this is server side)
oldStream = Stream.get("A");
Grab the piece you want to add in
smallClip = Stream.get("B");
Make a new stream to record into
newStream = Stream.get("newFile");
Make the new stream record the old file
newStream.play("oldFile");
newStream.record("record");
Then you need to monitor it with an interval of something short like every 100 milliseconds. When it reaches the time of whatever you want the new clip to go into then stop playing the old stream and put in the new one:
newStream.play(false);
newStream.play("smallClip");
** side note **
You can also at this point tell the server to stop recording too, and then use the append value in the record method to add onto the current FLV.
newStream.record(false)
newStream.play("smallClip");
newStream.record("append");
** end side note **
Watch the onStatus and see when it ends, you should get a "NetStream.Play.Stop" event, when you get that, then just play the other clip again, starting from the point where you finished off:
newStream.play("oldFile", 25); //25 is the seconds time you want the clip to start from.
When it finishes playing again then just stop recording and you should have a stream that has another stream in it. Delete the old one if you want I suppose.
So you can see it's a crappy tedious process, but yes, it can be done :)
Even though the majority of the fixes are for the edge/origin configuration there are other fixes that are quite important. Most prominently in there is the fact that up until now server side connections to other apps were counting against the license.. Anyways, go get it there's lots of good fixes.
Link to the what's been updated page
In case you're wondering, this has been in response to some of the larger sites out there taking advantage of FMS. When the big boys find the bugs, Adobe listens :)
I had to laugh at this question when it came in.
The question: How do I stop that annoying sound that occurs when I make a connection to FMS?
The answer:
I'm assuming you mean the administration panel that came with FCS 1.0 and 1.5. Yes, I agree, that sound was very annoying. There isn't much you can do about that, I really recommend you upgrade to FMS2 and use the new administration panel. There are no sounds in that thing and it works so much better.
So, you have on choice really = Turn your speakers off. Which I fully realize is not realistic. Sorry, no solution at the moment. I think the source for that admin panel was somewhere, but I can't recall where at the moment. At least then you could open up the FLA and just delete the code where it tells the SWF to play a sound on connecting up to the server.
A good question, unfortunately no good answer :(
The question: How can I playback more than one recorded streams in synchronization?
The answer:
This is definitely something that has been requested a billion times to the FMS team. Hopefully they are working hard on getting this going. To put it in a short sentence, "you can't". It sucks..
But what you can do is try to start playing them both at the same time with a low buffer. Like .5 of a second or something. Then when they are playing, up the buffer a bit to keep things in line. While the videos are playing, you also can keep a watch on the time that the videos are at and if the difference get's too high, just pause one and let the other catch up.
This requires quite a bit of coding and calculation because you have to figure out how much is buffered, how long it took to buffer, the difference in times of the videos, if the videos are staggered that will add even more trouble.
It's not that it can't be done, progressively it would be reasonably easy, just preload lots :) Streaming is a bit hard as you have to always buffer. On the flip side, using seek() to get to a point in the stream is good because you don't need to preload that part of the video to start playing it.
So, in conclusion, it can be done I guess, but it's your best calculations that are going to run it. This kind of feature is not built into FMS.
Another FMS guru question :) Getting quite a few of these, sorry I've been a bit slow to respond.
Anyways...
The question: What's with client.ping(), and how do I use it?
The answer:
Well, I guess to start off, the question is in reality a bit more advanced than what I've wrote above, but more or less it's "what the heck do I do with ping() and why doesn't work as I expect for what I want to do".
So, the first thing I will start off with is what ping() is all about. Ping in the normal network world is used to find a node on a network and how long it takes to get there and back. These packets are sent at high priority so there is less delay etc. I'm not going into too much detail on this of course, but what I can say is that FMS's client.ping() on the server side is just about the same.
What is happening behind the scenes when you call ping() on the client is the server is sending out some packets to the client at a high priority. Higher than all the other data that could be going back and forth. If it gets a response, true comes back. Not quite the same as the "normal" ping that we all know and love, but more or less you are knocking on the door and seeing if somebody answers. ping() doesn't really care how long that takes.
So, the next part of this question is "what would you use this for?". Well, a lot of people want to use it to see if a client is alive on the server. Why would you use ping for that? Well, supposedly it's the fastest way to tell. You're probably wondering "compared to what?".
Which leads us to the next question, "why would you want to know if somebody was connected up to the server if the client object still exists?"
Aha! now that is the key question here I think. In FCS1.0 and 1.5 (throughout all the updates too) there was the problem of "ghost clients". These clients would sit in the application objects that the server had yet to figure out they are gone. There are a few reasons for this of course, there could be a stay-alive going on here, where a router or something is just keeping the connection there. There is also the problem with IE in where even if you close the window, the connection to the server stays open. You can even still be sending your video and audio to the application if you didn't close it first and just closed the browser window!! Imagine that! I heard a story about how one guy's connection stayed up for over an hour with his vid and aud being broadcasted to a chat. I'm sure there are other instances of this.. It gets solved by closing ALL of the browser windows you have open of IE. Odd bug.. not sure who to blame, I guess Microsoft.
There was also the problem in where if you were doing nothing on the application, the app would disconnect you, although you'd still be there.. it's a really weird problem and it sucked, so you had to make your own "stay-alive" code to keep users connected when there was no data going back and forth in the application. Some people used ping() in this instance.
So, what does this mean to a developer of FMS apps? Well, you need to know if users are actually there and if they are going to stay there when nothing is going on. In FMS2, I've actually yet to see the problem of the user getting disconnected when nothing is going on in the app. This is a good thing :) Nice to see it fixed. There are less instances of ghost users, but they are there, especially in busier applications.
What do you do? Do you use ping() to see if they are there? My answer is to suggest "no". The reason is that ping() can return true even when the client is no longer connected. The router or something in the middle actually returns that the client is there (I don't actually know exactly what is happening here, I do know that ping() will return true even though the client isn't there).
So, this makes ping() a bit crappy. My suggestion to solve not only the worry to make sure clients stay alive in the app, and also to check if they are there is to call a function in the SWF file.
This is reasonably simple because all you need to do is create a function on the netConnection object.
myNC = new NetConnection();
myNC.checkForOnline = function(){
return "yes, I'm still here";
}
Then on the server side you just call that on all clients every 30 seconds or so (this will depend on your app of course). If the call returns an error, or nothing, or the wrong string then you know that either the client is not there or is a rogue user that has connected up to your application. The good side effect here is that you are adding a bit of security to your application. Security is always good :) Once you have discovered that the call failed or returned no string or the wrong string, you disconnect them and delete the client object.
That's about it. All about ping() and why it's not really that beneficial to use it :)
The new licensing scheme got you confused? Need to know what's up, get the 411? Look no further then because here it all is in laymans terms.
First off, with this new update to version 2.0.1 there is a new license scheme.
In case you are wondering what the old one was (the one that was introduced upon the release of FMS2.0) it was 150 max connections with unlimited BW. This caused an uproar around the world and Adobe changed their minds :)
So, the new licensing scheme and how it works. The brand new licensing manager programmed inside of FMS is setup to handle connection/bandwidth profiles now.
What are profiles and what does that mean to you?
Currently there are three profiles that come with the install of FMS2. Once you have installed the server, you can check in "licenses" directory in the install directory and you'll see the following profile files:
150.pro
1000-40.pro
2500-25.pro
These are used when you tell FMS what profile you want to use (I'll talk about this farther down). Each profile has different settings in it. Like, 150.pro is the original 150 connections and unlimited bandwidth. 1000-40.pro is 1000 connections and 40Mbps, and to finish it off 2500-25.pro is (you guessed it) 2500 connections and 25Mbps (which is exactly what FCS1.5 Pro had).
So what does this mean to you? Well, the first thing off is that upgrading to FMS2 from FCS1.5 is a logical choice. With the original of only 150 connections and unlimited BW, if you had apps that required more connections (which was very highly likely), you would actually have to go out and buy more licenses just to run what you were originally running..
Anyways, you can only have one profile in service at one time, but in turn, you can switch profiles whenever you want. This means that say for example this week you have a video seminar that you want to get out to a limited amount of people. In this case you are most likely to need a lot of BW, but not so many connections. For that you might change to the 150.pro profile. On the flip side, say next week you have a huge chat conference that you want to get on. For this, you would switch it over to the 2500-25.pro profile.
As you can see, you can match up your server to your apps now. This gives a bit more leverage of what you have bought in comparison to FCS1.5, and far more over that original licensing scheme that was thought up.
What does this mean for the future?
Well, thanks to this line of thinking, it's now possible for Adobe to create profiles based on perhaps a request. If somebody says they don't need 1000 connections, but need more than 40Mbps. Perhaps at that time if there was enough demand, Adobe would put out a new profile that was 500 Connections and 50Mbps or something like that (I'm not doing the math.. but you get the picture I think).
So now that we all understand what is going on and why, how do we go about setting the server up for this? At the time of this writing, the information is not available except on the mailing list from figgyleaf, Flashcomm.
If you have done a clean install, you will find in your install directory a directory called "conf". Inside there is a file called fms.ini. This is a special file that sets all kinds of things, and one of those things is the license profile. If you have upgraded without uninstalling and deleting the files in the install directory, then this file will not get overwritten on the install and you have to add the tags in yourself.
So, inside the fms.ini file there is going to be an entry like this:
SERVER.ACTIVE_PROFILE =
This is where you want to set the above profiles, like for example the 2500-25.pro license setting would look like this:
SERVER.ACTIVE_PROFILE = 2500-25.pro
That's about it. If you do change this value, make sure to restart the server.
Now if you have done an update over a previous install, you'll need to add that line, along with one more in the server.xml file.
It's in the Root/Server tag and looks like this:
<ActiveProfile>${SERVER.ACTIVE_PROFILE}</ActiveProfile>
That may look funny at first, but it is just accessing the variables in the fms.ini file. You could in turn just forget the fms.ini file and write this:
<ActiveProfile>2500-25.pro</ActiveProfile>
It's the same thing.
That's about actually. If anybody has any questions, feel free to stick them in the comments and I'll do my best to answer them.
On a final note, pricing information is available here, you can also buy from reseller Uvault here, and upgrade purchase here, and here is the link to the details on this update (which is free of course to the current customers of FMS2)
Yes, at long last the updater to the Flash Media Server 2.0 licensing nightmare is out along with a whole bunch of fixes to some bugs that made it through the QA team in the first release round.
We're up to FMS 2.0.1 now. I hope they get another updater with all those remaining known issues fixed up.
So here's an interesting question that to most intermediate to advanced people in FMS would consider quite easy, but taking myself back to my younger days in programming I too would have scratched my head.
So here's the Q: How do I access a shared object on the server side that was created on the client side?
Answer: Any remote shared object that is created on the client side can be accessed just the same on the server side. Meaning that it doesn't matter which side you create it on, you can still access it from the other side.
There is one gotcha that I have to mention because this catches so many.
When creating the SO on the client and server side remember to keep your persistance value the same. Which by the way you are only just creating a pointer to the shared object on the server. You aren't actually recreating the SO when you make another reference on the server or client side after creating it on the other.
A quick example to make it all clear.
On the client side you would do it like this (nc is the netConnection object already connected up by the way):
var mySO = new SharedObject.getRemote("SO_name_goes_here", nc.uri, false);
As you can see above with the final "false" value, I've created a non persistant Shared Object, meaning that it gets deleted when nobody is connected to it. A persistant SO gets saved as a file on the server in the application directory.
Now, the gotcha is that on the server side, some will do this:
var mySS_SO = SharedObject.get("SO_name_goes_here", true);
As you can see above, I've written "true" for the persistance value. Even though the SO name is the same as the client side one, because the persistance value is different the SO is completely different. It would have to be written like this to make the server side get the same SO as the client side:
var mySS_SO = SharedObject.get("SO_name_goes_here", false);
So with the above code, I can access the data in the shared object from the server or client side. Both can take advantage of the send() method and of course onSync(). Handy stuff I think.
I hope that helps somebody :)
I think this almost calls for a quick tute on the pros and cons for managing SO's on the client and/or server side... hmm..
Just wanted to note that we have released a basic lobby/private chat application for a budget friendly price.
http://www.solid-thinking.com/applications/basic_chat/basicprivatechat.html
What you can do with it:
- Text/Audio/Video chat
- Lobby chat with all in the lobby
- Invite another user to a private chat
- Accept or deny an invite (other user will be notified)
- Have a private chat with another user, again text/audio/video functionality
- change your text color
- automatic link creation for url's
- study with it, the code is well thought out and provides a strong framework for future customization
This is not a resellable application at the license fee we are advertising, nor is there any support. More information is available on the page:
http://www.solid-thinking.com/applications/basic_chat/basicprivatechat.html
I thought this would be a great second question for the infamous FMS Guru :)
Question:
Is there any static variable type available in server side ? so that I can change that variable globally.
Answer:
Yes. With FMS2 you can actually set variables in the application.xml file. Now if you set these variables in this file and put the application.xml file in the application directory, the variables you set will be available to instances of that application only. Not any others.
If you don't put an application.xml file in the application directory of the application that you are running, then FMS will default to the level higher which would be the conf directory for the virtualhost you are running and look in there. That's where we are going to set our variable.
So, open up the application.xml file in some text editor and jump down to the tag
<JSEngine>
In there we are going to add a couple of new tags:
<ApplicationObject>
Inside there:
<config>
And in there we are going to add a super user tag and put my name in it:
superUser
Graeme Bull
So it looks like this:
<JSEngine>
<ApplicationObject>
<config>
<superUser>Graeme Bull</superUser>
</config>
</ApplicationObject>
</JSEngine>
Now, save the file, restart the server and make a main.asc file because we are now going to trace this value out:
application.onAppStart = function(){
trace("The Super User is: " + application.config.superUser);
}
Now when you start up the application you should see the following trace:
The Super User is: Graeme Bull
That's it :)
Got a question here for the FMS Guru on "How do I use the file object on the server side with FMS2?"
So here's an answer :)
The file object on the server is actually quite powerful. Up until FMS2.0 there was no way to get a list of files, or write or read files directly from FCS. A lot of people wanted to be able to do this to get a list of FLV files, or MP3 files or something on the server that FCS was on. Most would use remoting and take advantage of PHP or Coldfusion to read a list and pass it back as an array perhaps. A pain.. that's for sure.
With the new file object API it's now possible to do quite a few things including getting lists of files, reading files and writing to them.
For an answer to the question, we are going to look at an example of writing a "login log" text file for every user that logs into a particular application.
First off we need to connect up to an application on FMS. So here is some basic client side code:
//create the netconnection object
var nc:NetConnection = new NetConnection();
//for the time being, stick in the onStatus
nc.onStatus = function(info){
trace(info.code);
}
//connect up and pass in the username
nc.connect("rtmp:/file_object", "Graeme");
)
Now that is pretty simple, we're going to connect up to an application called "file_object" and pass in the username "Graeme".
On to the server side:
//setup the function that gets called when the client connects up
application.onConnect = function(clientObj, userName){
//we're getting the client object and the userName that is passed in
//make sure that the userName value exists, we're going to use it for the filename
if(userName != undefined){
//accept the connection for now
application.acceptConnection(clientObj);
//create the file object here
var fileObj = new File(userName + ".txt");
//check to see if the file actually exists already
if(fileObj.exists){
//if so, then open the file with the mode "text" for text file, and "append" because we are going to add to it
fileObj.open("text", "append")
}else{
//if not, then create it with the mode "create"
fileObj.open("text", "create");
}
//here is where we write in the text file
fileObj.writeln(userName + " logged in on " + new Date());
//and close up the file
fileObj.close();
}else{
//no username, so reject them
application.rejectConnection(clientObj);
}
}
Now you save that code in your main.asc file, put it in the application folder and connect up. On the connect you should now see a brand new text file in the application directory with the user's username as the file name, and when they logged in. Log in more than once with the same user and it will add another line.
This method can be used for all kinds of things I think. Logging users in, logging views of a video etc etc.
I hope this helps understand one small part of the file object on the server side of FMS2.0.
I was just wandering over MXNA and it occured to me that there are a few guru's out there that field questions for Flash and Coldfusion etc, but how about Flash Media Server (formerly Flash Communication Server).
So, I'd like to maybe take on some questions as a self-proclaimed FMS2.0 Guru :D
If you have any questions about FMS2.0 or 1.5 for that matter, please feel free to send them off in the comments or email me at fmsguru [at] solid-thinking.com. I'll post answers here on my blog for all to view as soon as I can answer them.
Along with the checkers game that we put up the other day, we've decided to stick up our multiplayer chess game that we made with FMS2.0 and Flash 8 (3D graphics are done in Swift3D v4.5, with photoshop) for people to play for free when bored :)
You can now go in the "challenge lobby", wait for somebody to join up and then challenge them to a game. This is a bit better than before with the requirement of sending somebody a link to join the room.
We've decided to stick up our multiplayer checkers game that we made with FMS2.0 and Flash 8 (3D graphics are done in Swift3D v4.5, with photoshop) for people to play for free when bored :)
Like lunch hour perhaps?
We should have a couple more games coming up soon, I'll post them as we get them going.
Just wanted to quickly note a new resource from a smart FMS guy named Darren (Daz). He runs fczone.com (Flash Media Server Fun) where he's gone and posted a whole bunch of free stuff.
Like Stefan of flashcomguru, I've got my eyes on the video guestmap ;)
Here is my presentation I did at MAX Hong Kong 2005 on Testing for Security Holes in Flash and Flash Media Server 2.0. This is the second in a pair of sessions I did at all three MAX conferences in Asia this year, here is the other presentation (Best Practices & Architecture for Flash & Flash Media Server 2.0).
This one too has streamed video with captions and syncronized slides and once again I have to thank Captionate 2.0 for the excellent functionality to get captions and cue points embedded in an FLV file that just fits in the seminar app. This time I took advantage of the importing of the captions text file and formatting that is in Captionate 2.0.. I can't believe I didn't use this before. I had actually copy and pasted in every line last time.. it took far too long. With this importing stuff, it parses out the file into bite size lines and then all you have to do is press the "add caption" button and it adds in the line that you want to add in the file as it plays along.
Truly simple and efficient.. I can't rave enough.
Anyways, the presentation is a bit drab and dry.. it's security centric so what more can you ask for right? But there are quite a few points in there worth listening to I think if you are an intermediate FMS developer or budding FCS/FMS developer looking for tips and concepts on making your apps a bit more safe for the "real world".
Anyways, here is the link to the presentation files again, just in case.
Again, any comments are very appreciated (I only got one on the last one.. I hope the preso was useful to some..), and any questions should be answered as soon as I can, so freely post any and all :)
I've finally managed to get the video I took of my session on Best Practices & Architecture for Flash & Flash Media Server 2.0 that I did at MAX Korea 2005. I did have two other versions, one from Singapore and one from Hong Kong, but the Korea one seemed best because we had over an hour for our sessions, whereas the others were one hour or less. So there is more content in this one.
Th