Copy link to clipboard
Copied
We have a bunch of mp3 files on our server and we'd like to serve only particular sections of particular files to users. For example, hello.mp3 might be four minutes long, but when user 1 tries to play it, he should only be able to play the section from 0:30 to 1:00, whereas user 2 should be able to play the whole thing.
I'm coming from a background using Wowza Media Server, where this is fairly easy to achieve: http://fmsguru.com/showtutorial.cfm?tutorialID=78.
Wowza doesn't require any change to the player (it doesn't call any special methods), so I'm looking for the same here.
I've been fiddling around with the main.asc file and the "Server-Side ActionScript" API to try and achieve something similar. In particular I've found the Stream.play method, which seems relevant. But I can't figure out how to attach a handler to a "play" event; all the examples I've seen only attach to Application.onConnect, which doesn't seem to include a connection to a particular file, which I need in order to determine the section that can be played.
So I'd like to do something along the lines of this (this is completely made up and doesn't follow any of the APIs; it's just an illustration of what I'm trying to achieve):
application.onConnect = function(client) {
client.onPlay = function(stream) { // Client.onPlay doesn't exist; what should I do here?
var section = getStreamSection(client, stream);
stream.play(section.start, section.end);
};
};
var getStreamSection = function(client, stream) {
return { start: 30, end: 60 }; // Return value is based on the user's credentials and the file they're trying to stream
};
Copy link to clipboard
Copied
The stream.play function needs to be used as follows :
myStream.play(streamName, [startTime, length, reset, remoteConnection, virtualKey])
You can find more details about the function here : http://livedocs.adobe.com/flashmediaserver/3.0/hpdocs/flashmediaserver_SSLR.pdf
Hope this helps.
Thanks,
Apurva
Copy link to clipboard
Copied
Sorry, I'm aware of the function's signature but I still have no idea how to fit it into the situation I've described.
Copy link to clipboard
Copied
Can anyone help? I still have no idea how to write an asc plugin to allow a user to play only a section of a track, and no more. The documentation doesn't seem to be helpful at all for this problem.
Copy link to clipboard
Copied
In order to this you would have to make some change to your client because you if i am not wrong you need VOD playback for each client - not live. When you play using Server-side - it becomes available as live stream and not as VOD stream. So client needs to issue appropriate play command from using NetStream.play method and passing correct parameters. However this does not mean you have to different client code for each client subscriber. Below is my workflow suggestion for you:
I hope above workflow explanation helps you to get started.
Copy link to clipboard
Copied
Hi. Thanks for your answer; I feel like I'm getting a little closer to understanding what's going on.
As I understand your answer though, the solution would be unsatisfactory as it trusts the client to use the correct values when calling NetStream.play. The client could simply ignore these values and play the whole file, and the server would have no way of stopping it, so this would not be adequate security. This is why I've been looking at Stream.play on the server; this is the only method I've found that seems to have anything to do with returning a section of a track from the server. I still can't see any way to integrate Stream.play into the workflow you've described.
Are you able to assist further?
Thanks.
Copy link to clipboard
Copied
When I was answering your query - that's the thing which came to my mind about the security but i ruled that out because you can turn on SWF Verification so that no one can modify your client. Anyone who wants to maniplulate server send values would have to modify the client and the moment someone modifies the client - the modified client would not be able to connect to FMS at all at first place. Does that answer your query from security standpoint - let me know.
Copy link to clipboard
Copied
No, we do not really consider SWF verification to be adequate security given how easy it is to bypass with tools such as RTMPDump. Relying on the client not to request data it shouldn't isn't good enough.
Copy link to clipboard
Copied
If you think that's the case you can use Authorization plug-in and intercept play commands from client and see if they are in valid range. If someone tries to access beyond range you can disconnect the client.
Copy link to clipboard
Copied
Is there any documentation that would help us figure out how to do this?
Copy link to clipboard
Copied
You can find the documentation for Plug-ins here:
http://help.adobe.com/en_US/flashmediaserver/plugin_apiref/index.html
Basically you need to concentrate on E_PLAY event and two fields F_STREAM_LENGTH & F_STREAM_POSITION. I am pasting below some code which you need to paste in your sample Auth Plug-in which you can find in : <installdir>/samples/plug-ins. You would have paste below code in case E_PLAY section in MyFmsAuthorizeEvent::authorize() function and compile it. You would basically get AuthModule.dll which you need to place in modules/auth and restart FMS.
// Set the Stream to be played back only for 10 seconds starting from 10 th second
// Stream will play from 10th Second to 20th Second
float fValue;
char buf[1024];
if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_LENGTH, fValue))
{
float fLength = fValue; // in seconds
sprintf(buf,"Original Stream length value passed from player %f\n",fLength);
m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
fLength=10.0;
sprintf(buf,"Modifying Stream length value passed from player %f\n",fLength);
m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
setFloatField(m_pAev,IFmsAuthEvent::F_STREAM_LENGTH,fLength);
}
if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_POSITION, fValue))
{
float iPosition = fValue; // in seconds
sprintf(buf,"Original Stream Position value passed from player %f\n",iPosition);
m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
iPosition=10.0;
sprintf(buf,"Modifying Stream length value passed from player %f\n",iPosition);
m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
setFloatField(m_pAev,IFmsAuthEvent::F_STREAM_POSITION,iPosition);
}