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.
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.
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 :)
hmph, it happens almost every time.. You mess with something new, can't figure it out, ask somebody or at somewhere and 5 minutes later.. you've figured it out.
Anyhow, just in case this helps somebody else:
Quick tip on making sure that there are no window controls in your Apollo application.
First thing is to edit your application XML file in the rootContent tag to have the following:
systemChrome="none" transparent="true" visible="true"
Then, and this is key and where I messed up, make sure that your Application tag is not set to mx:ApolloApplication but is instead just set to the normal mx:Application. You then must place in some buttons that will close/minimize the application.
The close function must call this:
stage.window.close();
The minimize function must call this:
stage.window.minimize();
That's it!
Here's a screen shot of mine:

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 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.
I recently put together an article for the Adobe Developer Center and it has finally gone live today. It's about making a live radio application using Flash Media Server and your collection of MP3 files. You'll be streaming MP3 files from Flash Media Server to listeners with some interesting control over them.
Here's a link to it if you're interested in learning what it's all about.
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.
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.
A rather interesting question today on metadata for FLV files recorded live with FMS.
The question: Is it possible to add metadata to a live video stream?
The answer:
Unfortunately, no. Neither FCS or FMS allow you to add metadata to a stream as you are recording it.
But, I think I get where this person is coming from and what they may want to do. Most of the time you would use the metadata to add in certain information like the length of the stream, size, subject etc. When you play an FLV you can get that metaData when the player first starts playing the video. FMS already adds in some info like the length and size but you can't add in your own personal info, which is what I am assuming the writer of this question would like to do.
In this case, I recommend using the NetStream's send() method. This will allow you to "embed" a call to a function that you set later in the player for the FLV file.
So, for example, when you start publishing:
myNS.publish("someRecording", "record);
Then make a send() call on it:
myNS.send("onMyMetaData", "This is a really cool video");
What this will do is call a function on the NetStream in the player when you set it. So you are setting it here in the first second or so. Before the player plays this video, create the function to handle that:
myNS.onMyMetaData = function(msg){
trace("myMetaData: " + msg);
}
and play it:
myNS.play("someRecording");
and you should see the data you "embedded" into the FLV file. This will work whether you play the video progressively or streaming with FMS.
Hope that helps a bit.
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?
Got a question today that is pretty common to hear when people want to know how FMS compares to other technologies out there.
The question: Is it possible to split live videos on the server for different bandwidths?
The answer:
Well, unfortunately no. The best you can do is to limit the amount of bandwidth that the client can use and the flash player will throttle the video/audio appropriately. Remember video then audio gets throttled (in that order). Data is always sent. In other words text chats will always work, whereas video maybe choppy or almost stopped and audio may cut out or be non existant.
Take a look at the client.setBandwidthLimit() method on the server side for more info on what I'm talking about.
You can also try using the NetStream.receiveVideo() method to bring down the FPS.. but I've heard this doesn't work quite that well. Might be worth a try depending on what you are doing though.
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.
Ah yes, another fine question that I would like to answer almost right away from getting the email.
The question: Is it possible to create a podcast using FMS 2?
The answer:
Yes and no. You can't do it with anything Adobe has given out or is selling, it can't be done out of the box. Adobe did mention quite some time back they were going to release an application that allowed you to convert FLV to MP3 but unfortunately nothing has been released and no matter how many people ask about it, there is no response. We can probably just assume the idea got kicked to the curb..
So, what is the alternative? Well if you check out a post over on my good friend Stefan's site: http://www.flashcomguru.com/index.cfm/2006/5/26/flv2mp3, it looks like somebody has found a piece of software that will convert FLV files to MP3. It's windows only though.
I've yet to use it, so can't attest to how good/bad it may be, but supposedly it works :) Perhaps give that a shot if you need?
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 :)
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 :)
So here we are with another question about FMS that can hopefully be answered below :)
The question: How do I test the server after a fresh install of FMS2?
The answer:
OK, so you've installed the server, whether it's windows or linux it doesn't really matter at this point, and you want to see if it's working. The first step is to find your way to the applications directory. If you installed by default, then this will be in the install directory. As a best practice though, I recommend moving it to a different drive than the boot drive, as it's not much different than a web server in a way that you will be placing lots of files in there and also making video/audio and data files that could potentially take up a lot of space.
So, the server is installed, the service is running and you can login to the admin console that comes with it. You're in the applications directory, so go ahead and create a directory called "myfirstapp". Notice that I have kept the application name all lowercase. If you're on a Windows server it doesn't matter, but for linux it's important which case you have the letters in when you try to connect up to it from a SWF. It's just easier and a better practice to keep it all lowercase.
Anyways, you've created the application folder in the applications directory. This now allows you to connect up to the server to this specific application. You'll do this with the following script in an FLA.
We'll do this in AS2 because it's also a good practice. Copy and paste if you want:
//create the net connection object
var nc:NetConnection = new NetConnection();
//set up the onStatus information object so we can see what is happening
nc.onStatus = function(info){
//trace the code object in the information object that is passed into the onStatus event
trace(info.code);
}
//connect up to the server. Put in your own IP address for your server in place of the IP number below. Or the domain name of the server
nc.connect("rtmp://111.111.111.111/myfirstapp/first_instance");
If all is well, the trace should return back in the output panel in flash that there was success.
If not, and this is the part that isn't documented so well in some places, then you need to debug what is happening. The first place to start is the onStatus event. If you get back that the connection was rejected, the first place to look is the application name that you put in the connect method. If that application does not exist on the server, as you created in the applications directory, then the server will automatically reject the connection. If it just fails then there are a couple of other items to look at. The first would be to make sure that the port is open that the server is trying to connect up on.
FMS by default uses port 1935. You can set it up to use any port really, but it's best to use port 80 (works out of the box with no web server on the same machine) and port 443 because a lot of firewalls won't block this port either so it has a high rate of success for connection. If you are sure the service is running, don't have the port blocked on the server or client side, then the next step would be to force the flash player to connect up over a specific port to see if it works. something like this:
nc.connect("rtmp://111.111.111.111:1935/myfirstapp/first_instance");
As you can see, I added :1935 on the end of the IP number. Just put in the port that you want to connect up on and are sure the server is listening on.
Now, on a quick side note that was also sent in the email, there is a way to create instances for applications from the admin panel. This is especially useful if you have code that needs to run on the server side before anybody connects up. Perhaps an initialization piece or a timer of some sorts. If you don't have an ASC files in the application directory, you might find this feature a bit useless and it may seem like it does nothing. It's doing something, but all it's doing is starting an instance of an application and running it. There aren't any connections to it and no code is running. By connecting up from an SWF file, you are doing the same thing really and the server will automatically create that instance for you. There aren't too many reasons why you would want to create an instance of an application before anybody connects up to it, but there are a few I guess.
That's about it for now I think. Hopefully that answers the question on how to figure out if the server is working as it should or not :)
My goodness.. I've got quite a few questions backed up at the moment due to being away in Auz there for the webdu2006 conference and then just a major influx in work.. but just want to get this first one out there before I get to some others.
So here's the Q: What logging options are available via Flash Media Server 2?
Well, what a nice new can of worms we have open here.
The answer: With FMS2 we can now log to standard format log files. In fact they have now broken out of the FLV format that you had to use a Flash SWF file to view for FCS1.5, to a txt file format that can be opened in any text editor and log analyzer.
The logging options are many and varied and to be honest, straight out of the box, FMS2 has pretty much most of what you need to be logged setup already.
But the question remains of what options an administrator has.
Well, to start off, how about a quick link to the livedocs just in case you want more info than what I will be putting here.
Now, there are quite a few types of log files and they are, by default, all sitting in the logs directory in the install directory. This can be fine for smaller sites that have the logs files written over often and they don't get big at all, but larger sites and setups with larger log files should move this off to a different drive than C (which is the default install drive if you have installed it there, talking about Windows in this case).
To change that up, just wander into the FMS.ini file and go to the bottom and you'll see a setting to set where you want log files to be created. Make sure to reset the server though for the changes to take place.
So, now we have some different types of log files:
access - Used to log access (client connections) to the server and stream activity, the setting for this file can be found in the logger.xml file in the conf directory up top in the access tag
application - logs info on what's happening in application instances, good for debugging actually
admin - Keeps track of the administration and logs messages here about errors etc with the server
core - more error logging here and stuff that is going on with the server
edge - logs about the server if it is an edge server
master - logs about the server if it is a master server (for an edge)
To a developer/administrator of the server, I'd have to say the application and access log files are the most interesting.
That's a bit of background on what is happening behind the scenes with logging, there are tons of things that can be changed for the access logs, and that full list can be seen in the logger.xml file or even online for descriptions (no use me just copying and pasting it all here) in the livedocs, here's the link just in case.
Hope this helps a bit :)
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..
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.
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 :)
Here's something I've just discovered about Premiere Pro 1.5 and something I knew about AE6.5 for a while.
This is definitely one of the areas that I think MM could have improved on with ALL of their products.
Changing the language might not seem useful to some but in the case that you usually use on language, but speak more than one, and happen to be in an environment that requires the one that you don't have set then this is how you change up the languages.
For Premiere Pro 1.5 it's a bit tougher than AE6.5 but it's easy to do and works fine.
First off you need to mess with your registry. When you buy the software, you have most likely chosen a language at purchase. This is common. The cool thing about Adobe is that they add in all the other languages with the software, just in case. So open up your registry with regedit or whatever you generally use, go into the HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Premiere Pro\1.5
In there, you will find a key called "Language". Change that to one of the languages that you will see in the directory of Premiere 1.5.
I have the following choices (I can't imagine they will be different for anybody else):
de_DE
en_US
fr_FR
it_IT
ja_JP
I'm sure I don't have to explain what languages those are. Just pick one of those and change the language key.
Close up regedit now, you're done there.
Next you need to copy some plug-ins from your default install. This is in the plug-ins directory. Copy the language that is installed already. For example, I have the Japanese version installed, which means that I have a "Common" directory and a "ja_JP" directory. I copied the ja_JP directory and renamed it "en_US". This will allow Premiere to load up all your plugins you have.
Now just open up Premiere and it should be the new language you have selected.
For AE, all you have to do is go into the languages directory of the install directory for AE and copy out the shortcut they have been so nice to add. Put it on your desktop or whatever and you now have the option of starting AE in another language.
I knew about the AE one a while back, but the premiere one is new to me today. The reason I wanted to change this is because sometimes I work straight with our clients on video work. The Japanese interface is a bit odd to them, and I thought it might be better if I could show it in English. Plus if I do any tutes on Premiere like I'm thinking of doing, it will now be in the right language for the audience I plan to address.
So, hopefully that helps somebody out there :)
*** A quick update***
It seems that Adobe thought it would be a great idea to make the fonts in some parts of the UI dependent on the language in Premiere, so some areas don't support 2 bytes characters. Like the Effect Controls panel, and some areas of the preferences areas.. This is odd.. I wonder why they did this instead of making it work with any language. The effects panel is fine, and parts of the prefs are fine, timeline, and other windows don't have a problem. bleh.. well if you aren't using 2 byte chars, it will probably work great switching between languages.
*** Disclaimer ***
Just to quickly note too, that I assume no responsibility if this messes up your computer in any way whatsoever. So do it at your own risk. Works fine for me though.
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.
The video is Flash 8 streamed from FMS2 with the captions put in for the whole video with Captionate 2.0. I've got to say that this app rules! It's a serious pain to get all the captions (took me 4 hours for 1 hour of video to type them all out), but once you have them, Captionate just makes it easy to embed in the FLV file and in turn integrate into the our Flash application.
Anyways, I have one more video I want to get up, Testing for Security Holes in Flash and Flash Media Server which I have captured but just need to edit. The one I am using is from the Hong Kong MAX conference. It shouldn't take me too much longer, but I am doing it only in my spare time.. which I'm lacking more and more of lately. Either way, I expect to have it up next week at the latest.
Here is the link again to the presentation files just in case.
And the session details:
Best Practices for Development and Architecture for Flash Media Server
Not to be outdone by Jesse ( just kidding :D ) I've put up my notes/source files/preso and an online video presentation of what I talked about at MXDU. I had actually been thinking of doing this originally and wanted the original preso from MXDU but forgot to turn on my camera when the presentation started... So here is the "after" version :) and now I have a new app that will allow me to create these easily.
It's by far not a full version of the original presentation, being only 25 minutes long, but some of my thoughts on using video for the web and concentrating those efforts for flash are in there synced with the preso and some notes.
It's possible to go back and forth through the slides if you want, but it will sync up to the video upon change.
I hope this is useful to somebody out there. It's not for the pro's in video out there, but if you are just starting out it will probably help.
The online video version of Flash Video Capering
Here are all the related links:
The files (4.5MB DL with the ppt, flv, xml, fla, swf)
Microsoft presentation used for the "test case"
The spoof tutorial (which coincides with what I talked about in the presentation)
I got quite a few questions on how I made that MM video banner spoof and finally put some time aside to make an article on it that flashstreamworks.com has been so generous to host. It turned out to be 7 pages though... so you'll most likely need a cup of coffee or something if you are going to sit down and read it. Please let me know your thoughts on the article if you have 'em :)
You can check it out here.
OK, here it is then. How to delete an FLV file off of a Flash Communication Server without using server side code at all. Just client side. This came up in the last Peldi's coding cafe a few hours ago. Peldi was showing all how to build a video recording app and had an FLV deleting function that he said must be on the server. When he asked everyone why they think it should be on the server, they all responded that the only way to delete an FLV is to do it with server side code. I responded that you can do it client side.. and hence, a tutorial on how to delete it client side because nobody believed me :)
Here's the link to the recorded tutorial, it's about 2mb and about 3 to 4 mins I think.
I didn't want to tune it too much to the veteran crowd and hope that the description in there helps others a bit less experienced in FCS apps. It's not a huge app, tiny really.. but it works :D If the explanation seems a bit redundant to you, just fast forward to near the end.
In the end... the theory is that when there is nothing in an flv file, it doesn't get created. That's why this method works.
Last night I received an email from a fellow developer that was really in a pickle (when a fellow dev guy says he's about to cry like a 12 year old girl...) about a bug with the video object in Flash. I tried to explain to him what it was before that on the flashcom figgyleaf list but I wasn't getting my point across quite as well as I would have liked to I guess.
So due to the circumstances he was in, I couldn't stand by and watch him get fired or something from work and immediately cooked up a quick tute to help him solve his problem.
The bug is with the video object only in the flash player 7. I wrote a past post on this here. If you test this with FP6 it will work fine. My fix entails that you attach the video object to the stage each time you want to attach the cam to it so that it will reset and show the video properly each and every time, this will only be required if somebody else had been using that video object before you.
The only thing is (in this example) in the av presence component the buttons are above the video on the stage but when you attach the video by AS, they end up below the video so you have to find a way around that, maybe by placing them below the video object or placing them on a level above the video with AS. I haven't covered that part..
Keep in mind that this is not a component fix (fyi, in the tute I am using v1 components, and only because it is an easy example), it is the fix for all video objects.
I'm actually quite surprised that other developers haven't either noticed or said anything, and a bit more surprised that MM won't recognize that this is a bug in the FP7.
Here's the video tutorial. It's about 5 mins.
If it has helped you (or not maybe), please let me know in the comments.