2013-01-07 1 views
3

저는 Node.js를 처음 사용하며, live.video를 캡처하고 rtmp를 통해 Adobe Media Server로 보내는데 사용되는 FFMPEG 인스턴스를 child.spawn을 사용하여 시작하는 방법을 알아 냈습니다.라이브 캡처 소스에서 활발하게 스트리밍하는 Node.js FFMPEG 자식 프로세스를 닫으려면 어떻게해야합니까?

Node.js와 함께 FFMPEG를 사용하는 모든 예는 시간이 제한된 샘플이므로, FFMPEG가 변환되는 파일의 끝에 도달하면 하위 프로세스가 닫힙니다.

이 경우 "파일 끝"이 없습니다.

나는 인스턴스화하는 경우 :

var ffmpeg = child.spawn('ffmpeg.exe', [args]); 

는 라이브 피드를 생성합니다.

나는 즉시로 자식 프로세스를 종료 시도 :

setTimeout(function() { 
     ffmpeg.stdin.resume(); 
     ffmpeg.stdin.write('insert command to echo q to close FFMPEG'); 
     ffmpeg.stdin.end(); 
    }); 

을하지만, 작동하지 않습니다. 내 RTM 피드가 내 테스트 상자에 계속 표시됩니다.

Node.js의 stdin을 통해 FFMPEG에 종료 명령을 전달할 수있는 방법이 있습니까?

미리 감사드립니다.

답변

0

당신은 단순히 kill 그것을 할 수 있습니다.

ffmpeg.kill(SIGHUB) 

아니면 제가 예를 이해한다면 당신이 원하는 다른 죽 신호가 http://en.wikipedia.org/wiki/Unix_signal


를 참조 정확하게, 당신은 스트림을 포함 FFMPEG하기 위해 노드 프로세스의 모든 인수를 전달합니다. ffmeg.end()을 작동 시키려면 노드 프로세스에서 직접 스트리밍해야합니다. 나는 ffmpeg가 카메라에서 지속적으로 데이터를 수신 할 때 멈추지 않는다고 생각합니다.

+0

들어오는 스트림을 읽고이를 ffmpeg child_process에 직접 전달하는 대신 Adobe Media Server로 전달하는 일종의 중개 기능이 있어야한다고 말하고 있습니까? 그렇다면 중간 스트림을 종료 할 수 있다고 생각합니다. 그러나 24/7의 소스 프로세스를 그대로 두지 않습니까? – RickZ

+0

사실 저는 귀하의 정확한 요구 사항을 알지 못해 정답을 진술하기가 조금 어렵습니다. 왜'.kill'을 사용하여 chlid 프로세스를 끝내지 않습니까? – topek

+0

방금 ​​시도했습니다. 'SIGHUP'이 Windows에서 지원되지 않는 것 같기 때문에 'SIGTERM'을 사용하여 종료되었습니다. 확실히 스트림을 끝내는 데 효과적이었습니다. 최종 목표는 궁극적으로 mp4 파일뿐만 아니라 다양한 비트 속도로 몇 가지 다른 스트림을 제공하기위한 것이므로 mp4가 잘린 지 여부를 확인해야합니다. 도움 주셔서 감사합니다. – RickZ

0

다음 코드는 child_process.fork() 메소드를 사용하여 모듈로 내 주요 app.js에 의해로드됩니다

var spawn = require('child_process').spawn; 

    var ffmpeg = spawn('C:\\Program Files (x86)\\ffmpeg\\bin\\ffmpeg.exe', ['-y', '-threads', '-0', '-re', '-rtbufsize', '204800000', '-probesize', '4096', '-vsync', '2', '-async', '30', '-f', 'dshow', '-s', '320x240', '-i', 'video=Integrated Webcam:audio=Microphone Array (IDT High Defi', '-c:a', 'libvo_aacenc', '-ab', '48000', '-ar', '22050', '-ac', '2', '-c:v', 'libx264', '-s', '400x300', '-g', '96', '-x264opts', 'bitrate=1200', '-preset', 'ultrafast', '-profile:v', 'baseline', '-pix_fmt', 'yuv420p', '-aspect', '4:3', '-f', 'flv', 'rtmp://server']); 

    setTimeout(function() { 
     ffmpeg.stderr.on('data', function() { 
      ffmpeg.stdin.setEncoding('utf8'); 
      ffmpeg.stdin.write('q'); 
      process.exit(); 
     }); 
    }, 10000); 

이 훨씬 덜 복잡 내가 그것을 만드는 것보다했다. 기본 app.js는 제공되는 기본 HTML 페이지이며 socket.io를 사용하여 이벤트와 해당 데이터를 수신합니다. 이 경우 'true'이벤트는 FFMPEG의 실시간 캡처 세션을 시작한 module.js 파일을로드하고이를 RTMP 서버에 제공하고 10 초 동안 FFMPEG를 정상적으로 종료합니다.

내 다음 작업은 현재의 시간 초과 테스트 방법과 달리 웹 인터페이스에서 트리거 된 이벤트를 통해 시스템을 종료하는 것입니다.

Windows에서 태스크 관리자를 보면 FFMPEG 프로세스가 2 차 노드 프로세스와 마찬가지로 종료됩니다.

이유는 내가 찾은 node-ffmpeg 모듈이 캡처 입력을 통해 라이브 스트리밍을 지원하지 않았기 때문입니다. 주로 기존 콘텐츠를 코드 변환하는 것으로 나타납니다. 이것의 최종 결과는 이상적으로 FFMPEG를 시작하고 중지 할 수있는 웹 기반 인터페이스가 될 것입니다. 우리의 유스 케이스는 Adobe Flash Media Live Encoder를 표준 MP4 파일을 저장할 수 없기 때문에 Adobe Media Server의 소스로 대체 할 것입니다.다음 무엇

0

더 많거나 적은 발사와 라이브 FFMPEG 세션을 닫는 문제에 대한 최종 솔루션을 사용하여 Node.js를 수 있습니다 :

이 코드가 "module.js"파일에 캡슐화되어
var  spawn = require('child_process').spawn 
, fs = require('fs'); 


    function ffmpeg(cmd, opts, callback) { 
    var p; 
    //console.log(callback()); 
    if(p == undefined) { 
     var p = spawn(cmd, opts); 

     p.stderr.on('data', function(data) { 
      /*p.stdin.setEncoding('utf8'); 
       p.stdin.write('q'); 
       process.exit() 
      */ 
      fs.readFile(__dirname + '/server-state.json', function(error, data) { 
       if(error) { 
         console.log(error); 
        } else { 
         content = JSON.parse(data); 
         console.log(content['State']); 

         if(content['State'] == 'false') { 
          p.stdin.setEncoding('utf8'); 
          p.stdin.write('q'); 
          process.exit() 
         } 
        } 
      }); 

     }); 

     return p; 
    } 

} 

    ffmpeg_var = ffmpeg('C:\\Program Files (x86)\\ffmpeg\\bin\\ffmpeg.exe', ['-y', '-threads', '-0', '-re', '-rtbufsize', '204800000', '-probesize', '4096', '-vsync', '2', '-async', '30', '-f', 'dshow', '-s', '320x240', '-i', 'video=Integrated Webcam:audio=Microphone Array (IDT High Defi', '-c:a', 'libvo_aacenc', '-ab', '48000', '-ar', '22050', '-ac', '2', '-c:v', 'libx264', '-s', '400x300', '-g', '96', '-x264opts', 'bitrate=1200', '-preset', 'ultrafast', '-profile:v', 'baseline', '-pix_fmt', 'yuv420p', '-aspect', '4:3', '-f', 'mp4', __dirname + '/IntegrityTest.mp4'], function() { 


    }); 

즉 루트 application.js 파일의 child_process.fork()를 통해 인스턴스화됩니다. '상태'가 저장된 텍스트 파일을 읽습니다. 이 상태는 루트 어플리케이션의 쓰기/읽기 메소드를 통해 토글됩니다. on ('data') 이벤트에서 파일을 읽은 다음 상태가 false로 변경된 것을 감지하면 stdin에 'q'명령을 작성하여 FFMPEG를 종료합니다.

데이터베이스를 사용하여 대규모로 구현하는 경우를 제외하고는 코드를 작성하는 좀 더 우아한 방법에 대한 의견을 제시하는 것 이상입니다.

0

파일이 ffmpeg로 스트리밍 된 후 EOF를 보내야합니다. 그런 다음 ffmpeg가 올바르게 완료되고 종료됩니다.

관련 문제