<commit_before>///<reference path="../typings/main.d.ts" />
///<reference path="../rpos.d.ts" />
import fs = require("fs");
import util = require("util");
import SoapService = require('../lib/SoapService');
import { Utils }  from '../lib/utils';
import url = require('url');
import { Server } from 'http';
import Camera = require('../lib/camera');
import { v4l2ctl } from '../lib/v4l2ctl';
import { exec } from 'child_process';
import PTZService = require('./ptz_service');
var utils = Utils.utils;

class MediaService extends SoapService {
  media_service: any;
  camera: Camera;
  ptz_service: PTZService;
  ffmpeg_process: any = null;
  ffmpeg_responses: any[] = [];

  constructor(config: rposConfig, server: Server, camera: Camera, ptz_service: PTZService) {
    super(config, server);
    this.media_service = require('./stubs/media_service.js').MediaService;

    this.camera = camera;
    this.ptz_service = ptz_service;
    this.serviceOptions = {
      path: '/onvif/media_service',
      services: this.media_service,
      xml: fs.readFileSync('./wsdl/media_service.wsdl', 'utf8'),
      wsdlPath: 'wsdl/media_service.wsdl',
      onReady: function() {
        utils.log.info('media_service started');
      }
    };
    
    this.extendService();
  }

  starting() {
    var listeners = this.webserver.listeners('request').slice();
    this.webserver.removeAllListeners('request');
    this.webserver.addListener('request', (request, response, next) => {
      utils.log.debug('web request received : %s', request.url);

      var uri = url.parse(request.url, true);
      var action = uri.pathname;
      if (action == '/web/snapshot.jpg') {
        if (this.ffmpeg_process != null) {
          utils.log.info("ffmpeg - already running");
          this.ffmpeg_responses.push(response);
        } else {
          var cmd = 'ffmpeg -fflags nobuffer -probesize 256 -rtsp_transport tcp -i rtsp://127.0.0.1:8554/h264 -vframes 1  -r 1 -s 640x360 -y /dev/shm/snapshot.jpg';
          var options = { timeout: 15000 };
          utils.log.info("ffmpeg - starting");
          this.ffmpeg_responses.push(response);
          this.ffmpeg_process = exec(cmd,options,(error,stdout,stderr) => {
            // callback
            utils.log.info("ffmpeg - finished");
            if (error) {
              utils.log.warn('ffmpeg exec error: %s',error);
            }
            this.ffmpeg_responses.forEach( (response) => { this.deliver_jpg(response); } );
            this.ffmpeg_process = null;
          });
        }
      } else {
        for (var i = 0, len = listeners.length; i < len; i++) {
          listeners[i].call(this, request, response, next);
        }
      }
    });
  }

  deliver_jpg(response: any){
    try {
      var img = fs.readFileSync('/dev/shm/snapshot.jpg');
      response.writeHead(200, { 'Content-Type': 'image/jpg' });
      response.end(img, 'binary');
    } catch (err) {
      utils.log.debug("Error opening snapshot : %s", err);<commit_msg>Use the correct RTSP Port and RTSPName for the ffmpeg loopback The loopback is used to extract a JPEG image from the video stream<commit_after>///<reference path="../typings/main.d.ts" />
///<reference path="../rpos.d.ts" />
import fs = require("fs");
import util = require("util");
import SoapService = require('../lib/SoapService');
import { Utils }  from '../lib/utils';
import url = require('url');
import { Server } from 'http';
import Camera = require('../lib/camera');
import { v4l2ctl } from '../lib/v4l2ctl';
import { exec } from 'child_process';
import PTZService = require('./ptz_service');
var utils = Utils.utils;

class MediaService extends SoapService {
  media_service: any;
  camera: Camera;
  ptz_service: PTZService;
  ffmpeg_process: any = null;
  ffmpeg_responses: any[] = [];

  constructor(config: rposConfig, server: Server, camera: Camera, ptz_service: PTZService) {
    super(config, server);
    this.media_service = require('./stubs/media_service.js').MediaService;

    this.camera = camera;
    this.ptz_service = ptz_service;
    this.serviceOptions = {
      path: '/onvif/media_service',
      services: this.media_service,
      xml: fs.readFileSync('./wsdl/media_service.wsdl', 'utf8'),
      wsdlPath: 'wsdl/media_service.wsdl',
      onReady: function() {
        utils.log.info('media_service started');
      }
    };
    
    this.extendService();
  }

  starting() {
    var listeners = this.webserver.listeners('request').slice();
    this.webserver.removeAllListeners('request');
    this.webserver.addListener('request', (request, response, next) => {
      utils.log.debug('web request received : %s', request.url);

      var uri = url.parse(request.url, true);
      var action = uri.pathname;
      if (action == '/web/snapshot.jpg') {
        if (this.ffmpeg_process != null) {
          utils.log.info("ffmpeg - already running");
          this.ffmpeg_responses.push(response);
        } else {
          var cmd = `ffmpeg -fflags nobuffer -probesize 256 -rtsp_transport tcp -i rtsp://127.0.0.1:${this.config.RTSPPort}/${this.config.RTSPName} -vframes 1  -r 1 -s 640x360 -y /dev/shm/snapshot.jpg`;
          var options = { timeout: 15000 };
          utils.log.info("ffmpeg - starting");
          this.ffmpeg_responses.push(response);
          this.ffmpeg_process = exec(cmd,options,(error,stdout,stderr) => {
            // callback
            utils.log.info("ffmpeg - finished");
            if (error) {
              utils.log.warn('ffmpeg exec error: %s',error);
            }
            this.ffmpeg_responses.forEach( (response) => { this.deliver_jpg(response); } );
            this.ffmpeg_process = null;
          });
        }
      } else {
        for (var i = 0, len = listeners.length; i < len; i++) {
          listeners[i].call(this, request, response, next);
        }
      }
    });
  }

  deliver_jpg(response: any){
    try {
      var img = fs.readFileSync('/dev/shm/snapshot.jpg');
      response.writeHead(200, { 'Content-Type': 'image/jpg' });
      response.end(img, 'binary');
    } catch (err) {
      utils.log.debug("Error opening snapshot : %s", err);
{'fraction_non_alphanumeric': 0.15681149950996406, 'fraction_numerical': 0.011270826527278666, 'mean_word_length': 2.7244525547445257, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5598234', 'n_tokens_mistral': 2006, 'n_tokens_neox': 1957, 'n_words': 408}