How to check if image file exist before loading it into UIoader

template
flash

#1

Hello, is there a way to check if Image file exists before loading it into UIloader with Actionscript (Adobe Animate)?

The thing is that I need to display image and if that image does not exist, the whole templates does not play. I’ve looked through AS3 classes that check if file exists (file.exists), but nothing seems to work. Is it even possible to do this using only Actionscript? Or am I missing something?

I am using the following code to display image and just want a solution for a situation when Image does not exist.

package
{
	import flash.display.MovieClip;
	import se.svt.caspar.ICommunicationManager;
	import se.svt.caspar.IRegisteredDataSharer;
	import se.svt.caspar.template.CasparTemplate;
      
	public class Intro extends CasparTemplate
	{
		private const customParameterDescription:XML = 	
		<parameters>
	   		<parameter id="logo1" type="string" info="File URL" /> 		
		</parameters>;
		
		override public function SetData(xmlData:XML):void 
		{			
		   for each (var element:XML in xmlData.children())
		   {
			  if (element.@id == "logo1") 		
			  {
				  logo1.source = element.data.@value.toString();
			  }
		   }
		   super.SetData(xmlData);		
		}
	}
}

#2
var tmp_file:File = File.documentsDirectory.resolvePath('my_file.txt');

if (tmp_file.exists) {
    // File exists
} else {
    // File doesn't exist
}

#3

I used your code, but it didn’t run after I imported File class. I found that I have to switch to AIR runtime and that worked, it generated the template, but nothing is shown when I play the template due to errors. I suppose it’s because of AIR runtime.

I added the code so that it runs and does nothing just to check if it works and does not interfere, but it seems it does interfere.

package
{
import flash.display.MovieClip;
import se.svt.caspar.ICommunicationManager;
import se.svt.caspar.IRegisteredDataSharer;
import se.svt.caspar.template.CasparTemplate;

import flash.filesystem.File;

public class Third extends CasparTemplate
{
private const customParameterDescription:XML =


;

  override public function SetData(xmlData:XML):void 
  {			
     for each (var element:XML in xmlData.children())
     {
  		if (element.@id == "logo") 		
  		{
  			  
  			var tmp_file:File = File.documentsDirectory.resolvePath('my_file.txt');
  			
  			if (tmp_file.exists) {
  				// File exists
  			} else {
  				// File doesn't exist
  			}
  			
  			Logo.source = element.data.@value.toString();					
  		}
  	 
     }
     super.SetData(xmlData);		
  }

}
}

This is what CasparCG writes after playing the template:

[2019-10-14 18:22:39.245] [8480] [error] flash-player[cg20.fth.1080p2500|1920x1080] [error] @Add@1@VerifyError: Error #1014@
[2019-10-14 18:22:39.258] [8480] [error] flash-player[cg20.fth.1080p2500|1920x1080] [error] @Play@1@ReferenceError: No template queued on layer 1@

Any help?


#4

I simly use a try catch block. See here for details. You can set a boolean variable in the catch block to know in your code, if the image has loaded or not.


#5

Hi,
I have the same issue, I’m working for live streaming motocross races and have al lot of images to load, like 100~200 riders photos

I’m using the same command : image.source="image_path"

I tried the try~catch method without any luck
as far I understand flash player just ignore the absence of the file without errors and ignore the catch block

but in casparcg the absence of the file generate the removeTemplate command

[2019-10-15 10:41:21.618] [1336] [error] flash-player[cg20.fth.576p2500|1024x576] [error] <invoke name="OnError" returntype="xml"><arguments><string>@Runtime error on template &quot;file://C:\Program Files\CasparCG Server 2.0.7\templates_RAM\\TESTER.ft@1@Error #2036@</string></arguments></invoke>

[2019-10-15 10:41:21.643] [1336] [debug] flash-player[cg20.fth.576p2500|1024x576] [activity] <invoke name="OnActivity" returntype="xml"><arguments><string>Command finished @RemoveTemplate@1@</string></arguments></invoke>

There is any way to tell CasaparCG Server to ignore this kind of error?
[like the flash player standalone]

thanks


#6

But if it ignores the try catch, then something is wrong with that part of the code.

What is "image_path"? If it should be a variable name, it should not have the quotation marks.

Try this line: try{Image.source = image_path;} catch(error:Error){}
That works for me.


#7

works for you (didikunz) either in caspar server or flash standalone player?

yes, the path is without quotation marks
actually is edited from xml data [real time from time keepers]
like this:
Rider1.FaceSource.source = "Images/Face/" + Current_xml.results.result[pilot_position].@additional8 + "_" + Current_xml.results.result[pilot_position].@no + "_" + Current_xml.results.result[pilot_position].@lastname + ".png";

works fine if the file exists, doesn’t run at all if the file doesn’t exist

I tried :

                try
                {
                	Rider2.xfirstname.text = " try block "; 
                	Rider2.FaceSource.source = "test_image_1.jpg";
                }
                catch (err:Error) 
                {
                	Rider2.xlastname.text = " catch block "; 
                }

borrowing the text fields for debug purposes
but if I remove the test_image_1.jpg the “catch block” text doesn’t show up


#8

I’d just use GreenSock ImageLoader class. It handles errors and scaling way better than UILoader.


#9

The filename needs to be a fully qualified file URL. So the file D:\Bilder\Sarah_24.JPG should be given as file:///D:/Bilder/Sarah_24.JPG otherwise it will not work.

Because no error is risen, when you remove that block.


#10

Exactly the same problem as Andrea has. It seems that the filepath is passed into the casparCG despite the Try-catch block. So when the Try part is initiated, it doesn’t matter what the results are, because the path is loaded either way ant the whole template crashes. Does it work for you didi, how?

I also tested it with Server 2.0.7 and 2.1.0. Same problem for me.

Template works when file exists.

try {
title1.text = " Try block ";
Logo.source = “file:///D:/-CasparCG Server/templates/DELA.PNG”;

} catch (err:Error) {
title2.text = " Error ";
}

I assume we need to check if file exists before assigning it to UIloader. Any ideas?


#11

You are right, I tested it, and found the same, as you. Sorry for saying something wrong. The code needs to be:

package
{
	import flash.display.MovieClip;
	import flash.events.IOErrorEvent;
	import se.svt.caspar.template.CasparTemplate;

	public class UILoader_Test extends CasparTemplate
	{
		private function loaderIOErrorHandler(errorEvent:IOErrorEvent):void
		{
			title2.text = " Error ";
		}
		
		override public function postInitialize():void
		{
			Logo.addEventListener(IOErrorEvent.IO_ERROR, loaderIOErrorHandler);
			
			title1.text = " Try to load ";
			Logo.source = "file:///D:/-CasparCG Server/templates/DELA.PNG";
		}

		override public function Play():void
		{
		}

		override public function Stop():void
		{
			removeTemplate();
		}

		override public function SetData(xmlData:XML):void 
		{		
			//super.SetData(xmlData);		
		}
	}
}

Because the ioError happens asynchronous, we need to catch the event. But you could leave the loaderIOErrorHandler function empty, to just prevent the template from crashing. By the way: the code, that loads the file into the UILoader can also be somewhere else (like in the SetData() function). Because the addEventListener is called inside postInitialize(), that is called before anything else, the code would still work.

You find a zip file with my test template here.


#12

Thank you! It works. Now everything runs beautifully!


#13

Thank you very much didikunz, works fine
fantastic!