merge.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. 'use strict';
  2. import childProcess = require('child_process');
  3. import fs = require('fs');
  4. import path = require('path');
  5. import os = require('os');
  6. import subtitle from '../subtitle/index';
  7. /**
  8. * Merges the subtitle and video files into a Matroska Multimedia Container.
  9. */
  10. export default function(config: IConfig, isSubtitled: boolean, rtmpInputPath: string, filePath: string, streamMode: string, done: (err: Error) => void) {
  11. var subtitlePath = filePath + '.' + (subtitle.formats[config.format] ? config.format : 'ass');
  12. var videoPath = filePath;
  13. if (streamMode == "RTMP")
  14. {
  15. videoPath += path.extname(rtmpInputPath);
  16. }
  17. else
  18. {
  19. videoPath += ".mp4";
  20. }
  21. childProcess.exec(command() + ' ' +
  22. '-o "' + filePath + '.mkv" ' +
  23. '"' + videoPath + '" ' +
  24. (isSubtitled ? '"' + subtitlePath + '"' : ''), {
  25. maxBuffer: Infinity
  26. }, err => {
  27. if (err) return done(err);
  28. unlink(videoPath, subtitlePath, err => {
  29. if (err) unlinkTimeout(videoPath, subtitlePath, 5000);
  30. done(null);
  31. });
  32. });
  33. }
  34. /**
  35. * Determines the command for the operating system.
  36. */
  37. function command(): string {
  38. if (os.platform() !== 'win32') return 'mkvmerge';
  39. return '"' + path.join(__dirname, '../../bin/mkvmerge.exe') + '"';
  40. }
  41. /**
  42. * Unlinks the video and subtitle.
  43. * @private
  44. */
  45. function unlink(videoPath: string, subtitlePath: string, done: (err: Error) => void) {
  46. fs.unlink(videoPath, err => {
  47. if (err) return done(err);
  48. fs.unlink(subtitlePath, done);
  49. });
  50. }
  51. /**
  52. * Attempts to unlink the video and subtitle with a timeout between each try.
  53. */
  54. function unlinkTimeout(videoPath: string, subtitlePath: string, timeout: number) {
  55. setTimeout(() => {
  56. unlink(videoPath, subtitlePath, err => {
  57. if (err) unlinkTimeout(videoPath, subtitlePath, timeout);
  58. });
  59. }, timeout);
  60. }