srt.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. var xml2js = require('xml2js');
  3. /**
  4. * Converts an input buffer to a SubRip subtitle.
  5. * @param {Buffer|string} input
  6. * @param {function(Error, string=)} done
  7. */
  8. module.exports = function(input, done) {
  9. if (typeof buffer !== 'string') input = input.toString();
  10. xml2js.parseString(input, {
  11. explicitArray: false,
  12. explicitRoot: false
  13. }, function(err, xml) {
  14. try {
  15. if (err) return done(err);
  16. done(undefined, xml.events.event.map(_event).join('\n'));
  17. } catch(err) {
  18. done(err);
  19. }
  20. });
  21. };
  22. /**
  23. * Converts an event.
  24. * @private
  25. * @param {Object} event
  26. * @param {number} index
  27. * @returns {string}
  28. */
  29. function _event(event, index) {
  30. var attributes = event.$;
  31. return (index + 1) + '\n' +
  32. _time(attributes.start) + ' --> ' + _time(attributes.end) + '\n' +
  33. _text(attributes.text) + '\n';
  34. }
  35. /**
  36. * Prefixes a value.
  37. * @private
  38. * @param {string} value
  39. * @param {number} length
  40. * @returns {string}
  41. */
  42. function _prefix(value, length) {
  43. while (value.length < length) value = '0' + value;
  44. return value;
  45. }
  46. /**
  47. * Suffixes a value.
  48. * @private
  49. * @param {string} value
  50. * @param {number} length
  51. * @returns {string}
  52. */
  53. function _suffix(value, length) {
  54. while (value.length < length) value = value + '0';
  55. return value;
  56. }
  57. /**
  58. * Formats a text value.
  59. * @private
  60. * @param {string} text
  61. * @returns {string}
  62. */
  63. function _text(text) {
  64. return text
  65. .replace(/{\\i1}/g, '<i>').replace(/{\\i0}/g, '</i>')
  66. .replace(/{\\b1}/g, '<b>').replace(/{\\b0}/g, '</b>')
  67. .replace(/{\\u1}/g, '<u>').replace(/{\\u0}/g, '</u>')
  68. .replace(/{[^}]+}/g, '')
  69. .replace(/(\s+)?\\n(\s+)?/ig, '\n')
  70. .trim();
  71. }
  72. /**
  73. * Formats a time stamp.
  74. * @private
  75. * @param {string} time
  76. * @returns {string}
  77. */
  78. function _time(time) {
  79. var all = time.match(/^([0-9]+):([0-9]+):([0-9]+)\.([0-9]+)$/);
  80. if (!all) throw new Error('Invalid time.');
  81. var hours = _prefix(all[1], 2);
  82. var minutes = _prefix(all[2], 2);
  83. var seconds = _prefix(all[3], 2);
  84. var milliseconds = _suffix(all[4], 3);
  85. return hours + ':' + minutes + ':' + seconds + ',' + milliseconds;
  86. }