Kaynağa Gözat

Add ASS support.

Roel van Uden 9 yıl önce
ebeveyn
işleme
7c6535b41a
2 değiştirilmiş dosya ile 93 ekleme ve 0 silme
  1. 92 0
      src/subtitle/formats/ass.js
  2. 1 0
      src/subtitle/formats/index.js

+ 92 - 0
src/subtitle/formats/ass.js

@@ -0,0 +1,92 @@
+'use strict';
+var xml2js = require('xml2js');
+
+/**
+ * Converts an input buffer to a SubStation Alpha subtitle.
+ * @param {Buffer|string} input
+ * @param {function(Error, string=)} done
+ */
+module.exports = function(input, done) {
+  if (typeof buffer !== 'string') input = input.toString();
+  xml2js.parseString(input, {
+    explicitArray: false,
+    explicitRoot: false
+  }, function(err, xml) {
+    if (err) return done(err);
+    try {
+      done(undefined, _script(xml) + '\n' +
+        _style(xml.styles) + '\n' +
+        _event(xml.events));
+    } catch(err) {
+      done(err);
+    }
+  });
+};
+
+/**
+ * Converts the event block.
+ * @param {Object} events
+ * @returns {string}
+ */
+function _event(events) {
+  var format = 'Layer,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text';
+  var items = [].concat(events.event).map(function(style) {
+      return _values(style.$, 'Dialogue: 0,{start},{end},{style},{name},' +
+      '{margin_l},{margin_r},{margin_v},{effect},{text}');
+    });
+  return '[Events]\n' +
+    'Format: ' + format + '\n' +
+    items.join('\n') + '\n';
+}
+
+/**
+ * Converts the script block.
+ * @param {Object} script
+ * @returns {string}
+ */
+function _script(script) {
+  return _values(script.$,
+    '[Script Info]\n' +
+    'Title: {title}\n' +
+    'ScriptType: v4.00+\n' +
+    'WrapStyle: {wrap_style}\n' +
+    'PlayResX: {play_res_x}}\n' +
+    'PlayResY: {play_res_y}\n' +
+    'Subtitle ID: {id}\n' +
+    'Language: {lang_string}\n' +
+    'Created: {created}\n');
+}
+
+/**
+ * Converts the style block.
+ * @param {Object} styles
+ * @returns {string}
+ */
+function _style(styles) {
+  var format = 'Name,Fontname,Fontsize,PrimaryColour,SecondaryColour,' +
+    'OutlineColour,BackColour,Bold,Italic,Underline,StrikeOut,ScaleX,' +
+    'ScaleY,Spacing,Angle,BorderStyle,Outline,Shadow,Alignment,' +
+    'MarginL,MarginR,MarginV,Encoding';
+  var items = [].concat(styles.style).map(function(style) {
+    return _values(style.$, 'Style: {name},{font_name},{font_size}, ' +
+    '{primary_colour},{secondary_colour},{outline_colour}, ' +
+    '{back_colour},{bold},{italic},{underline},{strikeout},{scale_x}, ' +
+    '{scale_y},{spacing},{angle},{border_style},{outline},{shadow},' +
+    '{alignment},{margin_l},{margin_r},{margin_v},{encoding}');
+  });
+  return '[V4+ Styles]\n' +
+    'Format: ' + format + '\n' +
+    items.join('\n') + '\n';
+}
+
+/**
+ * Fills a predetermined format with the values from the attributes.
+ * @param {Object.<string, *>} attributes
+ * @param {string} value
+ * @returns {string}
+ */
+function _values(attributes, format) {
+  return format.replace(/{([^}]+)}/g, function(match, key) {
+    return attributes[key] || '';
+  });
+}

+ 1 - 0
src/subtitle/formats/index.js

@@ -1,3 +1,4 @@
 module.exports = {
+  ass: require('./ass'),
   srt: require('./srt')
 };