title: Xsplit Broadcaster Custom Script Editing
body: <p>First off, I'd like to apologize if I misuse any terms. I just learned Javascript, and it's very basic knowledge. I'm hoping to get better at it. I have been trying to figure out how to have some text from a .json file load into a script. I am using Xsplit, a broadcasting program, which has the option to load text from a file. I am an esports streaming director and producer, and I use a special program that creates two files (XML and JSON) with values for the tournaments I produce. The script that is used to load the code is here:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>/*
      This loads text from [FILEPATH] in between [DELIMITER_1] and [DELIMITER_2].
      If [DELIMITER_1] and [DELIMITER_2] is not found, Title shows the whole text.
      An optional [UPDATEINTERVAL] in milliseconds may also be set to auto-update.
      The script will check the local file for any changes in text every [UPDATEINTERVAL] milliseconds
      which will automatically update the text within the stage.
      Setting it to 0 or lower disables auto-update.  
  */
  
  /**
   * @name FILEPATH
   * @label File Path
   * @type file
   * @filters "Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"
   * @description The path of the file from where the script will extract text
   */
  var FILEPATH = "C:\\Stream Control\\streamcontrol.xml";
  
  /**
   * @name DELIMETER_1
   * @label Delimeter 1
   * @type text
   * @description The text, which when found signals the start of extracting text. If not found, script will show the whole text.
   */
  var DELIMETER_1 = "&lt;pName1&gt;";
  
  /**
   * @name DELIMETER_2
   * @label Delimeter 2
   * @type text
   * @description The text, which when found signals the end of extracting text. If not found, script will show the whole text.
   */
  var DELIMETER_2 = "&lt;/pName1&gt;";
  
  /**
   * @name UPDATEINTERVAL
   * @label Update Interval
   * @type int
   * @positiveOnly true
   * @description Optional. If set, the script will check the local file for any changes in text every X seconds, which will automatically update the text within the stage.
   */
  var UPDATEINTERVAL = 1;
  
  /**
   * @name LINEBREAK_BEHAVIOR
   * @label Behavior on Line Breaks
   * @type select
   * @options Preserve Line Breaks||Ignore Line Breaks||Replace
   * @description Preserve Line Breaks = Line breaks will be preserved, and text will be wrapped to the next line||Ignore Line Breaks = Line breaks will simply be omitted, and without spacing. Text will be displayed on single line||Replace = Replace line breaks with a specific character or set of characters
   */
  var LINEBREAK_BEHAVIOR = "Replace";
  
  /**
   * @name REPLACE_WITH
   * @label Replace Line Break With
   * @type text
   * @description The text to replace line breaks with, if Replace is selected as line break behavior
   */
  var REPLACE_WITH = " ";
  
  /*Do not modify anything below*/
  
  /**
   * @name XJS_URL
   * @description XJS FRAMEWORK URL LOCATION
  */
  var XJS_URL = "http://cdn2.xsplit.com/xjs/download/1.4.1/xjs.min.js?source"; 
  
  function loadScript(url, callback)
  {
      // Adding the script tag to the head
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = url;    
  
      // Then bind the event to the callback function.
      // There are several events for cross browser compatibility.
      script.onreadystatechange = callback;
      script.onload = callback;
  
      // Fire the loading
      head.appendChild(script);
  }
  
  var XJS;
  
  var oldResponse;
  
  function processText(response)
  {    
      
      var responseCleaned;
  
      if (LINEBREAK_BEHAVIOR == "Ignore Line Breaks")
      {
          responseCleaned = response.replace(/(\r\n|\n|\r)/gm,"");
      }
      else if (LINEBREAK_BEHAVIOR == "Replace")
      {
          responseCleaned = response.replace(/(\r\n|\n|\r)/gm, REPLACE_WITH);
      }
      else
      {
          responseCleaned = response.replace(/(\r\n|\n|\r)/gm,"&lt;br&gt;");
      }
  
      if (DELIMETER_1 != "" &amp;&amp; DELIMETER_2 != "")
      {
          var responseCleanedLength = responseCleaned.length;
          var indexOfDelim1 = responseCleaned.indexOf(DELIMETER_1) &gt; -1 ? (responseCleaned.indexOf(DELIMETER_1) + DELIMETER_1.length) : 0;
          var substringResponseCleaned = responseCleaned.substring(indexOfDelim1);
          var substringResponseCleanedLength = substringResponseCleaned.length;
  
          var initialIndexOfDelim2 = substringResponseCleaned.indexOf(DELIMETER_2) &gt; -1 ? substringResponseCleaned.indexOf(DELIMETER_2) : responseCleanedLength;
          var indexOfDelim2 = responseCleanedLength;
          if (initialIndexOfDelim2 != responseCleanedLength)
          {
              indexOfDelim2 = initialIndexOfDelim2 + (responseCleanedLength - substringResponseCleanedLength);
          }
  
          if (indexOfDelim2 &lt;= indexOfDelim1)
              indexOfDelim2 = responseCleaned.length - 1;
          responseCleaned = responseCleaned.substring(indexOfDelim1, indexOfDelim2);
      }
      
      if(oldResponse!=responseCleaned)
      {
          SetText(responseCleaned, "Local File: " + FILEPATH);
      }
      oldResponse=responseCleaned;
      if (UPDATEINTERVAL &gt; 0)
      {
          smlTitleTimeouts = setTimeout(function() { GetTextFromRemote(); }, UPDATEINTERVAL*1000);
      }     
  
  }
  
  function GetTextFromRemote(){
      var response;
  
      XJS.IO.getFileContent(FILEPATH).then(function(base64Content) {
          try {
              response = decodeURIComponent(escape(window.atob(base64Content)));
              processText(response);
          } catch(err) {
              return new Promise(function(resolve, reject) {
                  reject("ERROR: " + err.stack);
            });
          }        
      }).catch(function(err) {
          XJS.IO.getFileContent(FILEPATH).then(function(base64Content) {
              response = window.atob(base64Content);
              processText(response); 
          });
      });                      
       
  }
  
  if (smlTitleTimeouts &amp;&amp; smlTitleTimeouts != null)
      {clearTimeout(smlTitleTimeouts);}
  
  SetText("", "Local File: " + FILEPATH);
  
  var loadScriptCallback = function() {           
      XJS = require('xjs');
      XJS.ready()
      .then(function() { 
          GetTextFromRemote()
      })
  };
  
  
  loadScript(XJS_URL, loadScriptCallback);    </code></pre>
  </div>
  </div>
  </p>
  
  <p>As you can see, that loads the code from the XML file, and fetches the values I need from between the two Delimiters that are defined by the user. It also auto-updates the text every second to check for changes. Another less useful feature is it loads the entire file if I don't define the Delimiters, which is annoying for me since I don't use some of the values (such as when someone doesn't have a Twitter or a sponsor tag). What I would like to do, is fetch the array that is found in the JSON file instead of the XML file (so DELIMITER_1 can be one value, and DELIMITER_2 can be another value). I spent some time learning VERY basic Javascript, and managed to come up with this:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var streamcontrol = { 
      "pName1": "TwilightStorm",
      "pName2": "MannyFresh",
      "pScore1": "0",
      "pScore2": "0",
      "pSponsor1": "Kern County eSports",
      "pSponsor2": "Knova Gaming",
      "pSponsorTag1": "KCeS",
      "pSponsorTag2": "KVA",
      "scoreboardHeader": "Casuals",
      "timestamp": "1496028540"
  }; 
  
  var x = " "
  
  SetText("[color=#ffd200]" + "[b]" + streamcontrol.pSponsorTag1 + "[/b]" + "[/color]" + x + streamcontrol.pName1)</code></pre>
  </div>
  </div>
  </p>
  
  <p>Which gives me this:</p>
  
  <p><a href="https://i.stack.imgur.com/GTQxF.png" rel="nofollow noreferrer">Player With Sponsor Tag</a></p>
  
  <p>So my question is this: How can I get Xsplit to load streamcontrol.json, fetch the value defined by the user, then output it in the format I have in the SetText command while still keeping the auto-update function? I would also like to add a fadeOut and fadeIn command every time I update the values.</p>
  
  <p>Thanks in advance! I'm hoping to learn a lot from this. </p>