node_fission_server.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //
  2. // Created by Chen Mingliang on 20/7/16.
  3. // illuspas[a]msn.com
  4. // Copyright (c) 2020 Nodemedia. All rights reserved.
  5. //
  6. const Logger = require('./node_core_logger');
  7. const NodeFissionSession = require('./node_fission_session');
  8. const context = require('./node_core_ctx');
  9. const { getFFmpegVersion, getFFmpegUrl } = require('./node_core_utils');
  10. const fs = require('fs');
  11. const _ = require('lodash');
  12. const mkdirp = require('mkdirp');
  13. class NodeFissionServer {
  14. constructor(config) {
  15. this.config = config;
  16. this.fissionSessions = new Map();
  17. }
  18. async run() {
  19. try {
  20. mkdirp.sync(this.config.http.mediaroot);
  21. fs.accessSync(this.config.http.mediaroot, fs.constants.W_OK);
  22. } catch (error) {
  23. Logger.error(`Node Media Fission Server startup failed. MediaRoot:${this.config.http.mediaroot} cannot be written.`);
  24. return;
  25. }
  26. try {
  27. fs.accessSync(this.config.fission.ffmpeg, fs.constants.X_OK);
  28. } catch (error) {
  29. Logger.error(`Node Media Fission Server startup failed. ffmpeg:${this.config.fission.ffmpeg} cannot be executed.`);
  30. return;
  31. }
  32. let version = await getFFmpegVersion(this.config.fission.ffmpeg);
  33. if (version === '' || parseInt(version.split('.')[0]) < 4) {
  34. Logger.error(`Node Media Fission Server startup failed. ffmpeg requires version 4.0.0 above`);
  35. Logger.error('Download the latest ffmpeg static program:', getFFmpegUrl());
  36. return;
  37. }
  38. context.nodeEvent.on('postPublish', this.onPostPublish.bind(this));
  39. context.nodeEvent.on('donePublish', this.onDonePublish.bind(this));
  40. Logger.log(`Node Media Fission Server started, MediaRoot: ${this.config.http.mediaroot}, ffmpeg version: ${version}`);
  41. }
  42. onPostPublish(id, streamPath, args) {
  43. let regRes = /\/(.*)\/(.*)/gi.exec(streamPath);
  44. let [app, name] = _.slice(regRes, 1);
  45. for (let task of this.config.fission.tasks) {
  46. regRes = /(.*)\/(.*)/gi.exec(task.rule);
  47. let [ruleApp, ruleName] = _.slice(regRes, 1);
  48. if ((app === ruleApp || ruleApp === "*") && (name === ruleName || ruleName === "*")) {
  49. let s = context.sessions.get(id);
  50. if (s.isLocal && name.split('_')[1]) {
  51. continue;
  52. }
  53. let conf = task;
  54. conf.ffmpeg = this.config.fission.ffmpeg;
  55. conf.mediaroot = this.config.http.mediaroot;
  56. conf.rtmpPort = this.config.rtmp.port;
  57. conf.streamPath = streamPath;
  58. conf.streamApp = app;
  59. conf.streamName = name;
  60. conf.args = args;
  61. let session = new NodeFissionSession(conf);
  62. this.fissionSessions.set(id, session);
  63. session.on('end', () => {
  64. this.fissionSessions.delete(id);
  65. });
  66. session.run();
  67. }
  68. }
  69. }
  70. onDonePublish(id, streamPath, args) {
  71. let session = this.fissionSessions.get(id);
  72. if (session) {
  73. session.end();
  74. }
  75. }
  76. }
  77. module.exports = NodeFissionServer;