Issues with 'CG x-xx ADD' Command

I’ve got an issue with migrating from version 2.0.7 to 2.3.3. The following command CG 1-10 ADD 0 works perfectly in 2.0.7 but in 2.3.3 the same commands are actioned but errors are generated.

Running the command CG 1-10 ADD 0 “Client/TickerGraphicTemplate/TickerGraphicTemplate” 0\r\n
Causes the reply Sent message to 127.0.0.1:202 CG OK\r\n

But later in the log file i see *html[file://X:\CH-1-Server\templates/Client/TickerGraphicTemplate/TickerGraphicTemplate.html] 1024 576 50.000000 Log: Uncaught ReferenceError: update is not defined

then

Assertion Failed: destroyer->size() < 8 file:C:\Program Files (x86)\Jenkins\workspace\casparcg-server-dep\master\src\core\producer\frame_producer.cpp line:142

then

html[file://X:\CH-1-Server\templates/Client/TickerGraphicTemplate/TickerGraphicTemplate.html] Destroyed.

Followed by a response of Cannot call on empty frame_producer to the command CALL 1-10 animateOut (‘false’)

Any ideas why this might be? Has there been a change in the way that the command is used between the two versions? is it a possible bug in 2.3.3 - is anyone else able to validate my observations?

Yes - there is a change in the way the template functions are invoked.

In server 2.0.7 when you call the play process in the template it invokes javascript function play(usercontent: string). In later versions the server extracts the usercontent string from the CG command and calls the javascript update(usercontent :string) function, then (if autoplay is enabled for example) it calls the javascript play() function after the update function has run.

Uncaught reference error message suggests you may not have defined the javascript update function.

When I create a HTML template and want any server to be able to play it, I program for a possible invoke of play(usercontent: string), checking if the input parameter exists. If so, I invoke the update(usercontent :string). You sometimes need a global flag to track if play function has been called so that you can use the update() to set the user fields, then start the intro animate when play is called.

1 Like

@andyw - thanks for the supper quick reply! So the issue is with the templates themselves not in the way that they are being loaded into CasparCG?

I’m not a programmer but instead a humble broadcast engineering trying to update our machines (CasparCG and Bluefish Driver version), to a level that they will work with Singular. At the moment we have somewhere in the region of 40+ CasparCG channels running at any one time, so its going to take a while - and I need to support out legacy templates in the mean time - hence the question.

Hi Mark,

I’m also a broadcast engineer that has had to learn to write software …

Yes, I think it is likely to be the templates, but the good news is that they are unlikely to need many changes to get them ready for use with server 2.0.7 and server 2.3.3.

If you examine the javascript code of one the template that is giving you error reports there are four core functions that should be present - play(), update(), stop(), next().

If the update() function is missing in the template, just add it as a dummy process:

function update(myStr) {
}

This should stop the Log: Uncaught ReferenceError: update is not defined message. If it has cleared the error I can give you some more hints on how to adjust the code to work with server 2.0.7 and 2.3.3.

The other change that has happened between server editions is the newer versions can use two methods of sending the user parameters - wrapped in XML (as used in server 2.0.7), or wrapped in JSON. If you have to edit the set of templates it may be worth adding some code tweaks to allow for the two methods of sending the instance data to future proof the code. It often needs just 4 lines or thereabouts to acheive this.

Mark,
If your templates use only the play() and stop() functions, there may be a simple workaround that converts the templates to work with both version 2.0.7 and version 2.3.3. This involves testing the parameters passed with the javascript calls.

Below is the code for a simple html page that shows the sequence of function calls made to the template, including the values of the text passed. The page has a 50% transparent full screen box, with the text information displayed in white. If you run this on the two versions of server you should see differing orders of function calls to play and update. The template uses auto-scaling so it is channel resolution independent.

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>

<style type="text/css">
.bgnd {
   position:absolute; top:0vh; left:0vw; width:100vw; height:100vh;
   background-color: black; opacity:0.5;
}

.infotext {
   position:absolute; top:0vh; left:4vw;
   font-family: Arial, Helvetica, sans-serif;
   font-size: 3vh; color: white; line-height: 4.5vh;
}
</style>

<script type="text/javascript">
function escapeHtml(unsafe) {
   return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}

function report(myText) {
   let myOutput = document.getElementById("info");
   myOutput.innerHTML += escapeHtml(myText) + "<br>";
}

function play(myString) {
   if (myString === undefined) {
      report("play() - no parameter");
   }
   else if (myString === "") {
      report("play(\"\") - null string");
   }
   else {
      report("play(str) - str = \"" + myString +"\"");
   }
}

function update(myString) {
   if (myString === undefined) {
      report("update() - no parameter");
   }
   else if (myString === "") {
      report("update(\"\") - null string");
   }
   else {
      report("update(str) - str = \"" + myString + "\"");
   }
}

function stop() {
   report("stop(). Window will close in 5 seconds.");
   setTimeout( () => {
      if (window.caspar) window.remove();
      else window.close();
   }, 5000);
}

function next() {
   report("next()");
}

</script>

</head>
<body>
   <div id="bgBox" class="bgnd"></div>
   <div id="info" class="infotext"></div>
</body>
</html>
1 Like

Thanks - all makes sense but the project board have chosen not to update the templates - but instead, they’ve chosen to use Singular.