App-MHFS

 view release on metacpan or  search on metacpan

share/public_html/static/hls.js  view on Meta::CPAN

  0xac: 0xf9, // lowercase u, grave accent
  0xad: 0xdb, // uppercase U, circumflex
  0xae: 0xab, // left-pointing double angle quotation mark
  0xaf: 0xbb, // right-pointing double angle quotation mark
  // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
  // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
  0xb0: 0xc3, // Uppercase A, tilde
  0xb1: 0xe3, // Lowercase a, tilde
  0xb2: 0xcd, // Uppercase I, acute accent
  0xb3: 0xcc, // Uppercase I, grave accent
  0xb4: 0xec, // Lowercase i, grave accent
  0xb5: 0xd2, // Uppercase O, grave accent
  0xb6: 0xf2, // Lowercase o, grave accent
  0xb7: 0xd5, // Uppercase O, tilde
  0xb8: 0xf5, // Lowercase o, tilde
  0xb9: 0x7b, // Open curly brace
  0xba: 0x7d, // Closing curly brace
  0xbb: 0x5c, // Backslash
  0xbc: 0x5e, // Caret
  0xbd: 0x5f, // Underscore
  0xbe: 0x7c, // Pipe (vertical line)
  0xbf: 0x223c, // Tilde operator
  0xc0: 0xc4, // Uppercase A, umlaut
  0xc1: 0xe4, // Lowercase A, umlaut
  0xc2: 0xd6, // Uppercase O, umlaut
  0xc3: 0xf6, // Lowercase o, umlaut
  0xc4: 0xdf, // Esszett (sharp S)
  0xc5: 0xa5, // Yen symbol
  0xc6: 0xa4, // Generic currency sign
  0xc7: 0x2503, // Box drawings heavy vertical
  0xc8: 0xc5, // Uppercase A, ring
  0xc9: 0xe5, // Lowercase A, ring
  0xca: 0xd8, // Uppercase O, stroke
  0xcb: 0xf8, // Lowercase o, strok
  0xcc: 0x250f, // Box drawings heavy down and right
  0xcd: 0x2513, // Box drawings heavy down and left
  0xce: 0x2517, // Box drawings heavy up and right
  0xcf: 0x251b // Box drawings heavy up and left
};

/**
 * Utils
 */
var getCharForByte = function getCharForByte(byte) {
  var charCode = byte;
  if (specialCea608CharsCodes.hasOwnProperty(byte)) {
    charCode = specialCea608CharsCodes[byte];
  }

  return String.fromCharCode(charCode);
};

var NR_ROWS = 15,
    NR_COLS = 100;
// Tables to look up row from PAC data
var rowsLowCh1 = { 0x11: 1, 0x12: 3, 0x15: 5, 0x16: 7, 0x17: 9, 0x10: 11, 0x13: 12, 0x14: 14 };
var rowsHighCh1 = { 0x11: 2, 0x12: 4, 0x15: 6, 0x16: 8, 0x17: 10, 0x13: 13, 0x14: 15 };
var rowsLowCh2 = { 0x19: 1, 0x1A: 3, 0x1D: 5, 0x1E: 7, 0x1F: 9, 0x18: 11, 0x1B: 12, 0x1C: 14 };
var rowsHighCh2 = { 0x19: 2, 0x1A: 4, 0x1D: 6, 0x1E: 8, 0x1F: 10, 0x1B: 13, 0x1C: 15 };

var backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent'];

/**
 * Simple logger class to be able to write with time-stamps and filter on level.
 */
var cea_608_parser_logger = {
  verboseFilter: { 'DATA': 3, 'DEBUG': 3, 'INFO': 2, 'WARNING': 2, 'TEXT': 1, 'ERROR': 0 },
  time: null,
  verboseLevel: 0, // Only write errors
  setTime: function setTime(newTime) {
    this.time = newTime;
  },
  log: function log(severity, msg) {
    var minLevel = this.verboseFilter[severity];
    if (this.verboseLevel >= minLevel) {
      // console.log(this.time + ' [' + severity + '] ' + msg);
    }
  }
};

var numArrayToHexArray = function numArrayToHexArray(numArray) {
  var hexArray = [];
  for (var j = 0; j < numArray.length; j++) {
    hexArray.push(numArray[j].toString(16));
  }

  return hexArray;
};

var PenState = function () {
  function PenState(foreground, underline, italics, background, flash) {
    cea_608_parser__classCallCheck(this, PenState);

    this.foreground = foreground || 'white';
    this.underline = underline || false;
    this.italics = italics || false;
    this.background = background || 'black';
    this.flash = flash || false;
  }

  PenState.prototype.reset = function reset() {
    this.foreground = 'white';
    this.underline = false;
    this.italics = false;
    this.background = 'black';
    this.flash = false;
  };

  PenState.prototype.setStyles = function setStyles(styles) {
    var attribs = ['foreground', 'underline', 'italics', 'background', 'flash'];
    for (var i = 0; i < attribs.length; i++) {
      var style = attribs[i];
      if (styles.hasOwnProperty(style)) {
        this[style] = styles[style];
      }
    }
  };

  PenState.prototype.isDefault = function isDefault() {
    return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash;
  };

  PenState.prototype.equals = function equals(other) {
    return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash;
  };

  PenState.prototype.copy = function copy(newPenState) {
    this.foreground = newPenState.foreground;
    this.underline = newPenState.underline;
    this.italics = newPenState.italics;
    this.background = newPenState.background;
    this.flash = newPenState.flash;
  };

  PenState.prototype.toString = function toString() {
    return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash;
  };

  return PenState;
}();

/**
 * Unicode character with styling and background.
 * @constructor
 */


var StyledUnicodeChar = function () {
  function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) {
    cea_608_parser__classCallCheck(this, StyledUnicodeChar);

    this.uchar = uchar || ' '; // unicode character
    this.penState = new PenState(foreground, underline, italics, background, flash);
  }

  StyledUnicodeChar.prototype.reset = function reset() {
    this.uchar = ' ';
    this.penState.reset();
  };

  StyledUnicodeChar.prototype.setChar = function setChar(uchar, newPenState) {
    this.uchar = uchar;
    this.penState.copy(newPenState);
  };

  StyledUnicodeChar.prototype.setPenState = function setPenState(newPenState) {
    this.penState.copy(newPenState);
  };

  StyledUnicodeChar.prototype.equals = function equals(other) {
    return this.uchar === other.uchar && this.penState.equals(other.penState);
  };

  StyledUnicodeChar.prototype.copy = function copy(newChar) {
    this.uchar = newChar.uchar;
    this.penState.copy(newChar.penState);
  };

  StyledUnicodeChar.prototype.isEmpty = function isEmpty() {
    return this.uchar === ' ' && this.penState.isDefault();
  };

  return StyledUnicodeChar;
}();

/**
 * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
 * @constructor
 */


var Row = function () {
  function Row() {
    cea_608_parser__classCallCheck(this, Row);

    this.chars = [];
    for (var i = 0; i < NR_COLS; i++) {
      this.chars.push(new StyledUnicodeChar());
    }

    this.pos = 0;
    this.currPenState = new PenState();
  }

  Row.prototype.equals = function equals(other) {
    var equal = true;
    for (var i = 0; i < NR_COLS; i++) {
      if (!this.chars[i].equals(other.chars[i])) {
        equal = false;
        break;
      }
    }
    return equal;

share/public_html/static/hls.js  view on Meta::CPAN


  CaptionScreen.prototype.insertChar = function insertChar(char) {
    var row = this.rows[this.currRow];
    row.insertChar(char);
  };

  CaptionScreen.prototype.setPen = function setPen(styles) {
    var row = this.rows[this.currRow];
    row.setPenStyles(styles);
  };

  CaptionScreen.prototype.moveCursor = function moveCursor(relPos) {
    var row = this.rows[this.currRow];
    row.moveCursor(relPos);
  };

  CaptionScreen.prototype.setCursor = function setCursor(absPos) {
    cea_608_parser_logger.log('INFO', 'setCursor: ' + absPos);
    var row = this.rows[this.currRow];
    row.setCursor(absPos);
  };

  CaptionScreen.prototype.setPAC = function setPAC(pacData) {
    cea_608_parser_logger.log('INFO', 'pacData = ' + JSON.stringify(pacData));
    var newRow = pacData.row - 1;
    if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) {
      newRow = this.nrRollUpRows - 1;
    }

    // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows
    if (this.nrRollUpRows && this.currRow !== newRow) {
      // clear all rows first
      for (var i = 0; i < NR_ROWS; i++) {
        this.rows[i].clear();
      }

      // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location
      // topRowIndex - the start of rows to copy (inclusive index)
      var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
      // We only copy if the last position was already shown.
      // We use the cueStartTime value to check this.
      var lastOutputScreen = this.lastOutputScreen;
      if (lastOutputScreen) {
        var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime;
        if (prevLineTime && prevLineTime < cea_608_parser_logger.time) {
          for (var _i = 0; _i < this.nrRollUpRows; _i++) {
            this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]);
          }
        }
      }
    }

    this.currRow = newRow;
    var row = this.rows[this.currRow];
    if (pacData.indent !== null) {
      var indent = pacData.indent;
      var prevPos = Math.max(indent - 1, 0);
      row.setCursor(pacData.indent);
      pacData.color = row.chars[prevPos].penState.foreground;
    }
    var styles = { foreground: pacData.color, underline: pacData.underline, italics: pacData.italics, background: 'black', flash: false };
    this.setPen(styles);
  };

  /**
     * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility).
     */


  CaptionScreen.prototype.setBkgData = function setBkgData(bkgData) {
    cea_608_parser_logger.log('INFO', 'bkgData = ' + JSON.stringify(bkgData));
    this.backSpace();
    this.setPen(bkgData);
    this.insertChar(0x20); // Space
  };

  CaptionScreen.prototype.setRollUpRows = function setRollUpRows(nrRows) {
    this.nrRollUpRows = nrRows;
  };

  CaptionScreen.prototype.rollUp = function rollUp() {
    if (this.nrRollUpRows === null) {
      cea_608_parser_logger.log('DEBUG', 'roll_up but nrRollUpRows not set yet');
      return; // Not properly setup
    }
    cea_608_parser_logger.log('TEXT', this.getDisplayText());
    var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
    var topRow = this.rows.splice(topRowIndex, 1)[0];
    topRow.clear();
    this.rows.splice(this.currRow, 0, topRow);
    cea_608_parser_logger.log('INFO', 'Rolling up');
    // logger.log('TEXT', this.get_display_text())
  };

  /**
    * Get all non-empty rows with as unicode text.
    */


  CaptionScreen.prototype.getDisplayText = function getDisplayText(asOneRow) {
    asOneRow = asOneRow || false;
    var displayText = [];
    var text = '';
    var rowNr = -1;
    for (var i = 0; i < NR_ROWS; i++) {
      var rowText = this.rows[i].getTextString();
      if (rowText) {
        rowNr = i + 1;
        if (asOneRow) {
          displayText.push('Row ' + rowNr + ': \'' + rowText + '\'');
        } else {
          displayText.push(rowText.trim());
        }
      }
    }
    if (displayText.length > 0) {
      if (asOneRow) {
        text = '[' + displayText.join(' | ') + ']';
      } else {
        text = displayText.join('\n');
      }
    }
    return text;
  };

  CaptionScreen.prototype.getTextAndFormat = function getTextAndFormat() {

share/public_html/static/hls.js  view on Meta::CPAN

    } else {
      pacIndex = byte - 0x40;
    }

    pacData.underline = (pacIndex & 1) === 1;
    if (pacIndex <= 0xd) {
      pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)];
    } else if (pacIndex <= 0xf) {
      pacData.italics = true;
      pacData.color = 'white';
    } else {
      pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4;
    }
    return pacData; // Note that row has zero offset. The spec uses 1.
  };

  /**
     * Parse characters.
     * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise.
     */


  Cea608Parser.prototype.parseChars = function parseChars(a, b) {
    var channelNr = null,
        charCodes = null,
        charCode1 = null;

    if (a >= 0x19) {
      channelNr = 2;
      charCode1 = a - 8;
    } else {
      channelNr = 1;
      charCode1 = a;
    }
    if (charCode1 >= 0x11 && charCode1 <= 0x13) {
      // Special character
      var oneCode = b;
      if (charCode1 === 0x11) {
        oneCode = b + 0x50;
      } else if (charCode1 === 0x12) {
        oneCode = b + 0x70;
      } else {
        oneCode = b + 0x90;
      }

      cea_608_parser_logger.log('INFO', 'Special char \'' + getCharForByte(oneCode) + '\' in channel ' + channelNr);
      charCodes = [oneCode];
    } else if (a >= 0x20 && a <= 0x7f) {
      charCodes = b === 0 ? [a] : [a, b];
    }
    if (charCodes) {
      var hexCodes = numArrayToHexArray(charCodes);
      cea_608_parser_logger.log('DEBUG', 'Char codes =  ' + hexCodes.join(','));
      this.lastCmdA = null;
      this.lastCmdB = null;
    }
    return charCodes;
  };

  /**
    * Parse extended background attributes as well as new foreground color black.
    * @returns{Boolean} Tells if background attributes are found
    */


  Cea608Parser.prototype.parseBackgroundAttributes = function parseBackgroundAttributes(a, b) {
    var bkgData = void 0,
        index = void 0,
        chNr = void 0,
        channel = void 0;

    var case1 = (a === 0x10 || a === 0x18) && b >= 0x20 && b <= 0x2f;
    var case2 = (a === 0x17 || a === 0x1f) && b >= 0x2d && b <= 0x2f;
    if (!(case1 || case2)) {
      return false;
    }

    bkgData = {};
    if (a === 0x10 || a === 0x18) {
      index = Math.floor((b - 0x20) / 2);
      bkgData.background = backgroundColors[index];
      if (b % 2 === 1) {
        bkgData.background = bkgData.background + '_semi';
      }
    } else if (b === 0x2d) {
      bkgData.background = 'transparent';
    } else {
      bkgData.foreground = 'black';
      if (b === 0x2f) {
        bkgData.underline = true;
      }
    }
    chNr = a < 0x18 ? 1 : 2;
    channel = this.channels[chNr - 1];
    channel.setBkgData(bkgData);
    this.lastCmdA = null;
    this.lastCmdB = null;
    return true;
  };

  /**
     * Reset state of parser and its channels.
     */


  Cea608Parser.prototype.reset = function reset() {
    for (var i = 0; i < this.channels.length; i++) {
      if (this.channels[i]) {
        this.channels[i].reset();
      }
    }
    this.lastCmdA = null;
    this.lastCmdB = null;
  };

  /**
     * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty.
     */


  Cea608Parser.prototype.cueSplitAtTime = function cueSplitAtTime(t) {
    for (var i = 0; i < this.channels.length; i++) {
      if (this.channels[i]) {
        this.channels[i].cueSplitAtTime(t);
      }
    }
  };

  return Cea608Parser;
}();

/* harmony default export */ var cea_608_parser = (Cea608Parser);
// CONCATENATED MODULE: ./src/utils/output-filter.js
function output_filter__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var OutputFilter = function () {
  function OutputFilter(timelineController, trackName) {
    output_filter__classCallCheck(this, OutputFilter);

    this.timelineController = timelineController;
    this.trackName = trackName;
    this.startTime = null;
    this.endTime = null;
    this.screen = null;
  }



( run in 0.523 second using v1.01-cache-2.11-cpan-f56aa216473 )