srt.ts 1.8 KB

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