merge.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. var childProcess = require('child_process');
  3. var fs = require('fs');
  4. var path = require('path');
  5. var os = require('os');
  6. var subtitle = require('../subtitle');
  7. /**
  8. * Merges the subtitle and video files into a Matroska Multimedia Container.
  9. * @param {Object} config
  10. * @param {string} rtmpInputPath
  11. * @param {string} filePath
  12. * @param {function(Error)} done
  13. */
  14. module.exports = function(config, rtmpInputPath, filePath, done) {
  15. var format = subtitle.formats[config.format] ? config.format : 'ass';
  16. var subtitlePath = filePath + '.' + format;
  17. var videoPath = filePath + path.extname(rtmpInputPath);
  18. childProcess.exec(_command() + ' ' +
  19. '-o "' + filePath + '.mkv" ' +
  20. '"' + videoPath + '" ' +
  21. '"' + subtitlePath + '"', {
  22. maxBuffer: Infinity
  23. }, function(err) {
  24. if (err) return done(err);
  25. _unlink(videoPath, subtitlePath, function(err) {
  26. if (err) _unlinkTimeout(videoPath, subtitlePath, 5000);
  27. done();
  28. });
  29. });
  30. };
  31. /**
  32. * Determines the command for the operating system.
  33. * @private
  34. * @returns {string}
  35. */
  36. function _command() {
  37. if (os.platform() !== 'win32') return 'mkvmerge';
  38. return path.join(__dirname, '../../bin/mkvmerge.exe');
  39. }
  40. /**
  41. * Unlinks the video and subtitle.
  42. * @private
  43. * @param {string} videoPath
  44. * @param {string} subtitlePath
  45. * @param {function(Error)} done
  46. */
  47. function _unlink(videoPath, subtitlePath, done) {
  48. fs.unlink(videoPath, function(err) {
  49. if (err) return done(err);
  50. fs.unlink(subtitlePath, done);
  51. });
  52. }
  53. /**
  54. * Attempts to unlink the video and subtitle with a timeout between each try.
  55. * @private
  56. * @param {string} videoPath
  57. * @param {string} subtitlePath
  58. * @param {function(Error)} done
  59. */
  60. function _unlinkTimeout(videoPath, subtitlePath, timeout) {
  61. console.log('Trying to unlink...' + Date.now());
  62. setTimeout(function() {
  63. _unlink(videoPath, subtitlePath, function(err) {
  64. if (err) _unlinkTimeout(videoPath, subtitlePath, timeout);
  65. });
  66. }, timeout);
  67. }