Flash Template, with external file input

Hi there!
I’ve been using flash Templates for a while now and I’m very happy with it! We launch our CG through bitfocus Companion app and it’s really nice just out of the box!
Trying to get more complicated CG, I’ve been working on a Template wich takes Text from an external file.
Everything works inside Animate but when calling It into Caspar it returns a “PARAMETER_MISSING: 402 CG ERROR”.

The code from animate is this:

import flash.net.URLLoader;
import flash.events.Event;
import flash.net.URLRequest;

var myTextLoader:URLLoader = new URLLoader();

myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
myTextLoader.load(new URLRequest(“Titular.txt”));

function onLoaded(e:Event):void
{
_ l3Title.text = e.target.data;_
_ addChild(l3Title);_
}

As I said, the flash works perfect, but Caspar seems to miss something…

That is an error of the server, that does not get a parameter to the template. Is this code only a snippet of a larger code? Is it in a separate ActionScript file? It could be, that Caspar does not consider this as a valid template. Do you run TemplateGenerator from Animate?

That code is on the actions layer to load the content on the first frame. As I would do for a normal Animate project.
Then I buid using templateGenerator without errors, but when loading to Caspar is when I get the error.
Should I script on a separate file?
I’m really new to Caspar Scripting! Am I missing some tutorials?

Have you tried commenting out the code and see, if you still have the same error?

(What is this underscore shit about? There is the button </> to format code). I think it would make sense to have the i3Title dynamic textfield already on the stage, it could mess up everything when you add it later.

Sorry for t’he formatting, was my first code paste so i didn’t know and just messed up with the italics.

Tried to coment t’he code and worked the animation but no text appears.

What do you mean with having the dynamic text already on stage?

You add the field to the stage, do you? I guess this kills the code.

I think I don’t get It.
The field is on a text object from the stage.
The problem is that the Exporter doesn’t return any error to guess what’s happening.
If there’s a proper way to get a variable from an external file, or some documentation where I can search…
Thanks in advance!

What is the idea behind the line:
addChild(l3Title);
if the field is already on the stage?

That is sometimes the case, that the template can be compiled without a problem, but does not work in CasparCG Is there any other information displayed in the log, after you play the template? Sometimes there is an ActionScript error logged, that helps a bit.

Ok, you where right,
addChild(l3Title)
was useless. I took it from another project of mine and didn’t remember what it did…
Then I looked to the Caspar logs and found this:

flash-player[cg20.fth.1080p6000|1920x1080] [error]        <invoke name="OnError" returntype="xml"><arguments><string>@Runtime error on template &quot;file://C:\Users\LPE\Desktop\TESTING\casparcg-server-2.2.0\template\CHYRONS\CP_TITULAR_TEST.ft@1@Error #2032@</string></arguments></invoke>

So I’m still lost. But thanks for your time!

But there is more on this error line. There must be at least an error number, that you can google…

In the line I read this error:

A fast search on google throws me back to an entry on this forum:

Reading a live text file - FileStream

As it seems to be an error related to Flash URLLoader.

Any alternative for reading a file?

I quickly compared your code to one of my templates, were I also used the URLLoader. There is no error in the code. So, the only thing I can see is, that the template does not find the data file. Are you sure, that “Titular.txt” is in Caspar’s template folder? It’s there were the code expect it to be.

By the way: Have you see the DATA commands, that allow to send data sets to Caspar asynchronously? Could probably be a better way to achieve what you are trying to do.

Damn!
You were totally right!
The txt file was located on the template folder (so Adobe Animate found could find it)
But when placed on templates folder directly it worked flawless!

Lots of thanks!

Xavi

I made something similar, but it’s refresh live. For first frame my code is:

import flash.net.URLLoader;
import flash.events.Event;
import flash.net.URLRequest;
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
myTextLoader.load(new URLRequest("D:/Scoreboard/Output/Clock.txt"));
function onLoaded(e:Event):void
{
l3clock.text = e.target.data;
}

and for second frame code is:

gotoAndPlay(1)

It’s work pretty good and refresh and milliseconds too (with a little bit latency)

How I can make a few more fields? With more variables or same code for every field in different frame?

That is a pretty funny way to do it. Have you considered using the Advanced Flash Template workflow? That would make it also possible to to a in and out animation without loosing the auto refresh feature. The refreshing could be implemented using a timer, instead if the gotoAndPlay loop trick.

Thank you! Yes, the timer is very smart solution. No latency.
I will try and Advanced Flash Template.

It’s me again.
I’m trying to do same but with multiple .TXT files.
No errors but data doesn’t loaded.
I’m sure this is a stupid mistake.

> package
> {
> 	import flash.display.MovieClip;
> 	import flash.net.URLLoader;
> 	import flash.events.Event;
> 	import flash.events.TimerEvent;
> 	import flash.net.URLRequest;
> 	import flash.utils.Timer;
> 	import flash.geom.ColorTransform
> 	import fl.transitions.Tween;
>       import fl.transitions.easing.*;
>       import fl.transitions.TweenEvent;
> 	import se.svt.caspar.ICommunicationManager;
> 	import se.svt.caspar.IRegisteredDataSharer;
> 	import se.svt.caspar.template.CasparTemplate;
> 	
> 	public class SCOREBUG_STAT_BASKET extends CasparTemplate 
> 	
> {
> 		private var myLoader:URLLoader;
> 		private var myTimer:Timer; 
> 		
> 		private function timerListener (e:TimerEvent):void
> 		{
> 			myLoader = new URLLoader();
> 			myLoader.addEventListener(Event.COMPLETE, processURL);
> 		}
> 	
> 	
> {
> 		private const customParameterDescription:XML = 	
> 		<parameters>
> 	   		<parameter id="Hcolor" type="string" info="Color for Home Team" />
> 	   		<parameter id="Acolor" type="string" info="Color for Away Team" />
> 			<parameter id="Flogo" type="string" info="File URL for Logo" />
> 			<parameter id="Hlogo" type="string" info="File URL for Logo" />
> 			<parameter id="Alogo" type="string" info="File URL for Logo" />
> 		</parameters>;	
> 	
> 	override public function SetData(xmlData:XML):void 
> 		{
> 		   for each (var element:XML in xmlData.children())
> 		   {
> 			 			   
> 			 			  			  
> 			  if (element.@id == "Hcolor") 		
> 			  {
> 					var myColorTransform = new ColorTransform();
> 					myColorTransform.color = element.data.@value;;
> 					LOG.colorA.transform.colorTransform = myColorTransform;	
> 			  }
> 			  			  			  
> 			  if (element.@id == "Acolor") 		
> 			  {
> 					var myColorTransform1 = new ColorTransform();
> 					myColorTransform1.color = element.data.@value;;
> 					LOG.colorB.transform.colorTransform = myColorTransform1;	
> 			  }
> 			  if (element.@id == "Flogo") 		
> 			  {
> 				  LOG.LogoF.source = element.data.@value.toString();
> 			  }
> 			  if (element.@id == "Hlogo") 		
> 			  {
> 				  LOG.LogoA.source = element.data.@value.toString();
> 			  }
> 			  if (element.@id == "Alogo") 		
> 			  {
> 				  LOG.LogoB.source = element.data.@value.toString();
> 			  }
> 			  {
> 	var myTween:Tween = new Tween(LOG, "alpha", Strong.easeInOut, 0, 1, 2.5, true);
> 	}
> 			  }
> 		   super.SetData(xmlData);		
> 		  }
> 	  
> 	  	private function processURL (e:Event):void
> 		{
>   {
> 			var ShotClockFile:URLLoader = new URLLoader();
> 
> 				ShotClockFile.addEventListener(Event.COMPLETE, SConLoaded);
> 				ShotClockFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Clock.txt"));
> 
> 				function SConLoaded(e:Event):void
> 				{
> 				  var SClock = e.target.data;
> 				
> 						if (SClock > 5) 
> 					{	  
> 						TXT.ShotClock.text = SClock
> 						var colorYELL:ColorTransform = TXT.ShotClock.transform.colorTransform;
> 						colorYELL.color = 0xFFCC00;
> 						TXT.ShotClock.transform.colorTransform = colorYELL; 
> 					}
> 					else 
> 					{
> 						
> 						TXT.ShotClock.text = SClock
> 						var colorRED:ColorTransform = TXT.ShotClock.transform.colorTransform;
> 						colorRED.color = 0xFF0000;
> 						TXT.ShotClock.transform.colorTransform = colorRED;
> 					}
> 		
> 				}
> 			var GameClockFile:URLLoader = new URLLoader();
> 
> 				GameClockFile.addEventListener(Event.COMPLETE, GConLoaded);
> 				GameClockFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/SClock.txt"));
> 
> 				function GConLoaded(e:Event):void
> 				{
> 				  TXT.GameClock.text = e.target.data;
> 				}
> 			
> 			var HomeScoreFile:URLLoader = new URLLoader();
> 
> 				HomeScoreFile.addEventListener(Event.COMPLETE, HSonLoaded);
> 				HomeScoreFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Home_Score.txt"));
> 
> 				function HSonLoaded(e:Event):void
> 				{
> 				  TXT.HomeScore.text = e.target.data;
> 				}
> 			
> 			var AwayScoreFile:URLLoader = new URLLoader();
> 
> 				AwayScoreFile.addEventListener(Event.COMPLETE, ASonLoaded);
> 				AwayScoreFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Away_Score.txt"));
> 
> 				function ASonLoaded(e:Event):void
> 				{
> 				  TXT.AwayScore.text = e.target.data;
> 				}
> 			
> 			var AwayTeamFile:URLLoader = new URLLoader();
> 
> 				AwayTeamFile.addEventListener(Event.COMPLETE, ATonLoaded);
> 				AwayTeamFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Away_Name.txt"));
> 
> 				function ATonLoaded(e:Event):void
> 				{
> 				  TXT.AwayTeam.text = e.target.data;
> 				}
> 			
> 			var HomeTeamFile:URLLoader = new URLLoader();
> 
> 				HomeTeamFile.addEventListener(Event.COMPLETE, HTonLoaded);
> 				HomeTeamFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Home_Name.txt"));
> 
> 				function HTonLoaded(e:Event):void
> 				{
> 				  TXT.HomeTeam.text = e.target.data;
> 				}
> 				
> 			var PeriodFile:URLLoader = new URLLoader();
> 
> 				PeriodFile.addEventListener(Event.COMPLETE, PonLoaded);
> 				PeriodFile.load(new URLRequest("D:/Scoreboards/BasketScoreboard/Output/Period.txt"));
> 
> 				function PonLoaded(e:Event):void
> 				{
> 				  var Per = e.target.data;
> 							
> 			
> 				if (Per >= 1 && Per <= 4)
> 				{
> 					TXT.Period.text = (Per + "/4");
> 				}	
> 				else
> 				{
> 					TXT.Period.text ="OT";
> 				}
> 		}
> 	}
> }
> 		
> 	
> 			
> 
> 	override public function postInitialize():void
> 		{
> 			myTimer = new Timer(100);
> 			myTimer.addEventListener(TimerEvent.TIMER, timerListener);
> 			myTimer.start();
> 		}
> 	}
> 	}		
> }

Just by reading the code I think you missed the “load” call of the first file on the “timerListener” function, so it never triggers the Event.COMPLETE and never runs “processURL”.