Thanks for your reply!
I have managed to get it working though not exactly what I wanted.
Reading your answer in this post: http://forums.adobe.com/message/3079910#3079910
I created two new application as per your instructions - app_1 & app_2 - both on the same servers - stream to app_1 and app_2 automatically relayed what was coming on app_1 - which is great and 50% answers my problem!
What I want to do is edit the existing !main application that I have, namely "live" and edit the main.asc in there which will then allow me to relay to app_2
Here is the current code in main.asc in "live" application
Where do I insert the code of app_1 in this code so that it allows app_2 to relay?
===================================================
/*
* application.onConnect:
* Implementation of the onConnect interface function (optional).
* it is invoked whenever a client connection request connection. Live app uses this
* function to authenticate the domain of connection and authorizes only
* for a subscriber request.
*/
application.onConnect = function( p_client, p_autoSenseBW )
{
// Check if pageUrl is from a domain we know.
// Check pageurl
// A request from Flash Media Encoder is not checked for authentication
if( (p_client.agent.indexOf("FME")==-1) && (p_client.agent.indexOf("FMLE")==-1))
{
// Authenticating HTML file's domain for the request :
// Don't call validate() when the request is from localhost
// or HTML Domains Authentication is off.
if ((p_client.ip != "127.0.0.1") && application.HTMLDomainsAuth
&& !this.validate( p_client.pageUrl, this.allowedHTMLDomains ) )
{
trace("Authentication failed for pageurl: " + p_client.pageUrl + ", rejecting connection from "+p_client.ip);
return false;
}
// Authenticating the SWF file's domain for the request :
// Don't call validate() when the request is from localhost
// or SWF Domains Authentication is off.
if ((p_client.ip != "127.0.0.1") && application.SWFDomainsAuth
&& !this.validate( p_client.referrer, this.allowedSWFDomains ) )
{
trace("Authentication failed for referrer: " + p_client.referrer + ", rejecting connection from "+p_client.ip);
return false;
}
// Logging
trace("Accepted a connection from IP:"+ p_client.ip
+ ", referrer: "+ p_client.referrer
+ ", pageurl: "+ p_client.pageUrl);
}else{
// Logging
trace("Adobe Flash Media Encoder connected from "+p_client.ip);
}
// As default, all clients are disabled to access raw audio and video and data bytes in a stream
// through the use of BitmapData.draw() and SoundMixer.computeSpectrum()., Please refer
// Stream Data Access doccumentations to know flash player version requirement to support this restriction
// Access permissions can be allowed for all by uncommenting the following statements
//p_client.audioSampleAccess = "/";
//p_client.videoSampleAccess = "/";
this.acceptConnection(p_client);
// A connection from Flash 8 & 9 FLV Playback component based client
// requires the following code.
if (p_autoSenseBW)
p_client.checkBandwidth();
else
p_client.call("onBWDone");
}
/*
* Client.prototype.getPageUrl
* Public API to return URL of the HTML page.
*
*/
Client.prototype.getPageUrl = function() {
return this.pageUrl;
}
/*
* Client.prototype.getReferrer
* Public API to return Domain URL of the client SWF file.
*
*/
Client.prototype.getReferrer = function() {
return this.referrer;
}
/*
* FCPublish :
* FME calls FCPublish with the name of the stream whenever a new stream
* is published. This notification can be used by server-side action script
* to maintain list of all streams or also to force FME to stop publishing.
* To stop publishing, call "onFCPublish" with an info object with status
* code set to "NetStream.Publish.BadName".
*/
Client.prototype.FCPublish = function( streamname )
{
// setup your stream and check if you want to allow this stream to be published
if ( true) // do some validation here
{ // this is optional.
this.call("onFCPublish", null, {code:"NetStream.Publish.Start", description:streamname});
}
else
{
this.call("onFCPublish", null, {code:"NetStream.Publish.BadName", description:streamname});
}
}
/*
* FCUnpublish :
* FME notifies server script when a stream is unpublished.
*/
Client.prototype.FCUnpublish = function( streamname )
{
// perform your clean up
this.call("onFCUnpublish", null, {code:"NetStream.Unpublish.Success", description:streamname});
}
/*
* releaseStream :
* When FME connection to FMS drops during a publishing session it will
* try and republish the stream when connection is restored. On certain
* occasions FMS will reject the new stream because server is still
* unaware of the connection drop, sometimes this can take a few minutes.
* FME calls "releaseStream" method with the stream name and this can be
* used to forcibly clear the stream.
*/
Client.prototype.releaseStream = function(streamname)
{
s = Stream.get(streamname);
s.play(false);
}
/*
* application.readValidDomains
* Function to read Allowed domain file
* Parameters:
* fileName:
* name of the file in the application directory
* which contains one valid domain name per line. This file can contain
* comments followed by a '#' as the very first charector in that line.
* a non-comment entry with a space is considered as an error case.
*
* returns
* an array in which each entry contains a domain name
* listed in the file.
*/
application.readValidDomains = function( fileName , domainsType )
{
var domainFile = new File(fileName);
var domainsArray = new Array();
var index = 0;
var lineCount = 0;
var tempLine;
domainFile.open("text", "read");
// Read the file line-by-line and fill the domainsArray
// with valid entries
while (domainFile.isOpen && ! domainFile.eof() )
{
tempLine = domainFile.readln();
lineCount++;
if( !tempLine || tempLine.indexOf("#") == 0)
{
continue;
}
tempLine = tempLine.trim();
if(tempLine.indexOf(" ")!=-1)
{
trace("undesired <space>, domain entry ignored. "+fileName+":"+(lineCount+1));
}
else
{
domainsArray[index] = tempLine.toLowerCase();
index++;
if(tempLine == "*")
{
switch (domainsType){
case "HTMLDomains":
trace ("Found wildcard (*) entry: disabling authentication for HTML file domains ") ;
application.HTMLDomainsAuth = false;
break;
case "SWFDomains":
trace ("Found wildcard (*) entry: disabling authentication for SWF file domains ") ;
this.SWFDomainsAuth = false;
break;
default:
// Do nothing
break;
}
}
}
} // End while
// Something is wrong! the domains file must be accessible.
if( !domainFile.isOpen){
trace("Error: could not open '"+fileName+"', rejecting all clients except localhost. ");
}
else
{
domainFile.close();
}
return domainsArray;
}
/**
* String.prototype.trim:
* Function to trim spaces in start an end of an input string.
* returns:
* a trimmed string without any leading & ending spaces.
*
*/
String.prototype.trim = function () {
return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
===================================================
Basically you can fit in my code anywhere in above "live" application code - i do not think it should conflict - something like below
NetConnection.prototype.connectTimer;
NetConnection.prototype.url;
NetConnection.prototype.onStatus = function( info )
{
trace ("##### nc: " + info.code + " #####");
if (info.code == "NetConnection.Connect.Failed" || info.code == "NetConnection.Connect.Closed")
{
if( this.connectTimer )
{
clearInterval(this.connectTimer);
this.connectTimer = null;
}
trace("setting up reconnect timer for " + this.url);
this.connectTimer = setInterval(reconnect,30000, this);
}else{
if(info.code == "NetConnection.Connect.Success" )
{
trace("************************** connection to " + this.url + " successful ");
if( this.connectTimer ){
clearInterval(this.connectTimer);
}
}
}
}
reconnect = function ( nc )
{
if(nc.connectTimer)
{
clearInterval(nc.connectTimer);
nc.connectTimer = null;
}
nc.connect(nc.url);
}
application.onAppStart = function()
{
nc = new NetConnection();
nc.url = "rtmp://localhost/app_2";
nc.connect(nc.url);
}
application.onPublish = function(client, stream)
{
trace("##### Publish: " + stream.name + " #####");
client.ns = new NetStream(nc);
client.ns.onStatus = function( info )
{
trace("ns: " + info.code);
if ( info.code == "NetStream.Publish.Start")
{
client.ns.attach(stream);
}
}
if (client.ns)
{
client.ns.publish(stream.name);
}
return true;
}
application.onUnpublish = function(client, stream)
{
trace("##### Unpublish: " + stream.name + " #####");
client.ns.attach(false);
client.ns.publish(false);
}
/*
* application.onConnect:
* Implementation of the onConnect interface function (optional).
* it is invoked whenever a client connection request connection. Live app uses this
* function to authenticate the domain of connection and authorizes only
* for a subscriber request.
*/
application.onConnect = function( p_client, p_autoSenseBW )
{
// Check if pageUrl is from a domain we know.
// Check pageurl
// A request from Flash Media Encoder is not checked for authentication
if( (p_client.agent.indexOf("FME")==-1) && (p_client.agent.indexOf("FMLE")==-1))
{
// Authenticating HTML file's domain for the request :
// Don't call validate() when the request is from localhost
// or HTML Domains Authentication is off.
if ((p_client.ip != "127.0.0.1") && application.HTMLDomainsAuth
&& !this.validate( p_client.pageUrl, this.allowedHTMLDomains ) )
{
trace("Authentication failed for pageurl: " + p_client.pageUrl + ", rejecting connection from "+p_client.ip);
return false;
}
// Authenticating the SWF file's domain for the request :
// Don't call validate() when the request is from localhost
// or SWF Domains Authentication is off.
if ((p_client.ip != "127.0.0.1") && application.SWFDomainsAuth
&& !this.validate( p_client.referrer, this.allowedSWFDomains ) )
{
trace("Authentication failed for referrer: " + p_client.referrer + ", rejecting connection from "+p_client.ip);
return false;
}
// Logging
trace("Accepted a connection from IP:"+ p_client.ip
+ ", referrer: "+ p_client.referrer
+ ", pageurl: "+ p_client.pageUrl);
}else{
// Logging
trace("Adobe Flash Media Encoder connected from "+p_client.ip);
}
// As default, all clients are disabled to access raw audio and video and data bytes in a stream
// through the use of BitmapData.draw() and SoundMixer.computeSpectrum()., Please refer
// Stream Data Access doccumentations to know flash player version requirement to support this restriction
// Access permissions can be allowed for all by uncommenting the following statements
//p_client.audioSampleAccess = "/";
//p_client.videoSampleAccess = "/";
this.acceptConnection(p_client);
// A connection from Flash 8 & 9 FLV Playback component based client
// requires the following code.
if (p_autoSenseBW)
p_client.checkBandwidth();
else
p_client.call("onBWDone");
}
/*
* Client.prototype.getPageUrl
* Public API to return URL of the HTML page.
*
*/
Client.prototype.getPageUrl = function() {
return this.pageUrl;
}
/*
* Client.prototype.getReferrer
* Public API to return Domain URL of the client SWF file.
*
*/
Client.prototype.getReferrer = function() {
return this.referrer;
}
/*
* FCPublish :
* FME calls FCPublish with the name of the stream whenever a new stream
* is published. This notification can be used by server-side action script
* to maintain list of all streams or also to force FME to stop publishing.
* To stop publishing, call "onFCPublish" with an info object with status
* code set to "NetStream.Publish.BadName".
*/
Client.prototype.FCPublish = function( streamname )
{
// setup your stream and check if you want to allow this stream to be published
if ( true) // do some validation here
{ // this is optional.
this.call("onFCPublish", null, {code:"NetStream.Publish.Start", description:streamname});
}
else
{
this.call("onFCPublish", null, {code:"NetStream.Publish.BadName", description:streamname});
}
}
/*
* FCUnpublish :
* FME notifies server script when a stream is unpublished.
*/
Client.prototype.FCUnpublish = function( streamname )
{
// perform your clean up
this.call("onFCUnpublish", null, {code:"NetStream.Unpublish.Success", description:streamname});
}
/*
* releaseStream :
* When FME connection to FMS drops during a publishing session it will
* try and republish the stream when connection is restored. On certain
* occasions FMS will reject the new stream because server is still
* unaware of the connection drop, sometimes this can take a few minutes.
* FME calls "releaseStream" method with the stream name and this can be
* used to forcibly clear the stream.
*/
Client.prototype.releaseStream = function(streamname)
{
s = Stream.get(streamname);
s.play(false);
}
/*
* application.readValidDomains
* Function to read Allowed domain file
* Parameters:
* fileName:
* name of the file in the application directory
* which contains one valid domain name per line. This file can contain
* comments followed by a '#' as the very first charector in that line.
* a non-comment entry with a space is considered as an error case.
*
* returns
* an array in which each entry contains a domain name
* listed in the file.
*/
application.readValidDomains = function( fileName , domainsType )
{
var domainFile = new File(fileName);
var domainsArray = new Array();
var index = 0;
var lineCount = 0;
var tempLine;
domainFile.open("text", "read");
// Read the file line-by-line and fill the domainsArray
// with valid entries
while (domainFile.isOpen && ! domainFile.eof() )
{
tempLine = domainFile.readln();
lineCount++;
if( !tempLine || tempLine.indexOf("#") == 0)
{
continue;
}
tempLine = tempLine.trim();
if(tempLine.indexOf(" ")!=-1)
{
trace("undesired <space>, domain entry ignored. "+fileName+":"+(lineCount+1));
}
else
{
domainsArray[index] = tempLine.toLowerCase();
index++;
if(tempLine == "*")
{
switch (domainsType){
case "HTMLDomains":
trace ("Found wildcard (*) entry: disabling authentication for HTML file domains ") ;
application.HTMLDomainsAuth = false;
break;
case "SWFDomains":
trace ("Found wildcard (*) entry: disabling authentication for SWF file domains ") ;
this.SWFDomainsAuth = false;
break;
default:
// Do nothing
break;
}
}
}
} // End while
// Something is wrong! the domains file must be accessible.
if( !domainFile.isOpen){
trace("Error: could not open '"+fileName+"', rejecting all clients except localhost. ");
}
else
{
domainFile.close();
}
return domainsArray;
}
/**
* String.prototype.trim:
* Function to trim spaces in start an end of an input string.
* returns:
* a trimmed string without any leading & ending spaces.
*
*/
String.prototype.trim = function () {
return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
===================================================
Try it out and see if its working - if you run into issues LMK