!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/usr/local/lib/node_modules/homebridge-camera-ui/server/services/   drwxr-xr-x
Free 13.33 GB of 57.97 GB (22.99%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     streams.service.js (5.02 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
'use-strict';

const Config = require('../../services/config/config.start');

const child_process = require('child_process');
const logger = require('../../services/logger/logger.service');
const lowdb = require('./lowdb.service');
const readline = require('readline');
const sessions = require('../../services/sessions/sessions.service');

const database = () => lowdb.database().then((database_) => database_.get('settings'));

const config = new Config();
const streams = {};

class Streams {
  async init(socket) {
    logger.debug('Initializing camera streams', false, '[Streams]');

    this.io = socket.io;

    const Settings = await database();
    const cameraSettings = await Settings.get('cameras').value();

    for (const camera of config.cameras) {
      const setting = cameraSettings.find((cam) => cam && cam.name === camera.name);

      let audio = setting.audio;
      let cameraHeight = camera.videoConfig.maxHeight || 720;
      let cameraWidth = camera.videoConfig.maxWidth || 1280;
      let rate = (camera.videoConfig.maxFPS || 20) < 20 ? 20 : camera.videoConfig.maxFPS || 20;
      let source = camera.videoConfig.source;
      let videoProcessor = config.options.videoProcessor;
      let videoSize = setting.resolution || `${cameraWidth}x${cameraHeight}`;

      const options = {
        name: camera.name,
        source: source,
        ffmpegPath: videoProcessor,
        ffmpegOptions: {
          '-s': videoSize,
          '-b:v': '299k',
          '-r': rate,
          '-bf': 0,
          '-preset:v': 'ultrafast',
          '-threads': '1',
          '-loglevel': 'quiet',
        },
      };

      if (audio) {
        options.ffmpegOptions = {
          ...options.ffmpegOptions,
          '-codec:a': 'mp2',
          '-ar': '44100',
          '-ac': '1',
          '-b:a': '128k',
        };
      }

      streams[camera.name] = options;
    }
  }

  getStream(cameraName) {
    return streams[cameraName];
  }

  getStreams() {
    return streams;
  }

  startStream(cameraName) {
    if (streams[cameraName]) {
      if (!streams[cameraName].stream) {
        const allowStream = sessions.requestSession(cameraName);

        if (allowStream) {
          const additionalFlags = [];

          if (streams[cameraName].ffmpegOptions) {
            for (const key of Object.keys(streams[cameraName].ffmpegOptions)) {
              additionalFlags.push(key, streams[cameraName].ffmpegOptions[key]);
            }
          }

          const spawnOptions = [
            ...streams[cameraName].source.split(' '),
            '-f',
            'mpegts',
            '-codec:v',
            'mpeg1video',
            ...additionalFlags,
            '-',
          ];

          logger.debug(
            `Stream command: ${streams[cameraName].ffmpegPath} ${spawnOptions.toString().replace(/,/g, ' ')}`,
            cameraName,
            '[Streams]'
          );

          streams[cameraName].stream = child_process.spawn(streams[cameraName].ffmpegPath, spawnOptions, {
            env: process.env,
          });

          streams[cameraName].stream.stdout.on('data', (data) => {
            this.io.to(`stream/${cameraName}`).emit(cameraName, data);
          });

          const stderr = readline.createInterface({
            input: streams[cameraName].stream.stderr,
            terminal: false,
          });

          stderr.on('line', (line) => {
            if (/\[(panic|fatal|error)]/.test(line)) {
              logger.error(line, cameraName, '[Streams]');
            } else {
              logger.debug(line, cameraName, '[Streams]');
            }
          });

          streams[cameraName].stream.on('exit', (code, signal) => {
            if (code === 1) {
              logger.error(`RTSP stream exited with error! (${signal})`, cameraName, '[Streams]');
            } else {
              logger.debug('Stream Exit (expected)', cameraName, '[Streams]');
            }

            streams[cameraName].stream = false;
            sessions.closeSession(cameraName);
          });
        } else {
          logger.error(
            `Not allowed to start stream for ${cameraName}. Session limit exceeded!`,
            cameraName,
            '[Streams]'
          );
        }
      }
    } else {
      logger.error(`Can not find ${cameraName} to start stream!`, cameraName, '[Streams]');
    }
  }

  stopStream(cameraName) {
    if (streams[cameraName]) {
      if (streams[cameraName].stream) {
        logger.debug('Stopping stream..', cameraName, '[Streams]');
        streams[cameraName].stream.kill();
      }
    } else {
      logger.error(`Can not find ${cameraName} to stop stream!`, cameraName, '[Streams]');
    }
  }

  stopStreams() {
    for (const cameraName of Object.keys(streams)) {
      this.stopStream(cameraName);
    }
  }

  setStreamOptions(cameraName, options) {
    for (const [key, value] of Object.entries(options)) streams[cameraName].ffmpegOptions[key] = value;
  }

  delStreamOptions(cameraName, options) {
    for (const property of options) delete streams[cameraName].ffmpegOptions[property];
  }
}

module.exports = new Streams();

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0516 ]--