node.js ffmpeg 동적 전환 입력 소스 흐름 (프로세스를 닫지 않음)

19255 단어 ffmpeg
node.js 자체는 ffmpeg를 봉인했지만 동적으로 입력원을 바꾸는 방법을 해결하지 못했다. ffmpeg는 같은 프로세스에서 하나의 입력원만 받아들일 수 있기 때문에 이 입력원은 파일 경로일 수도 있고 읽을 수 있는 흐름 데이터일 수도 있다.처음의 생각은 하나의 프로세스를 여는 방법으로
const spawn = require('child_process').spawn

우리는 명령을 조작해서 지난번 조작을 끊임없이 끝내고 명령을 다시 조작합니다. 그러나 서버로 유도하면 서버가 데이터를 다시 받아들여야 한다는 것을 발견할 수 있습니다. 또한 작업이 빈번하면 열린 하위 프로세스를 닫는 것이 번거롭습니다. 프로세스 명령으로 ffmpeg를 조정할 때 fmpeg도 하나의 프로세스이기 때문에 명령을 실행하면 두 개의 프로세스를 추가로 열었다고 하고 프로세스를 닫는 것은 번거롭습니다.
const Ffmpegs = require('fluent-ffmpeg')

나중에 노드를 발견했어요.js 자체는 봉인된 ffmpeg입니다.용법은 아래와 같다.
	playsure = new Ffmpegs()
    playsure.input('E://KuGou//08.mp3')
    playsure.inputOption('-re')
    playsure.outputOptions([
      '-rtsp_transport',
          'tcp',
          '-f',
          'rtsp'
   ])
    playsure.output('rtsp://47.103.130.92:554')
    playsure.run()
    playsure.on('end', () => {
      console.log(' end')
    })

특정 서버로 스트리밍합니다.우리는 한 프레임 한 프레임의 밀기를 지정했고 tcp 방식으로 rtsp 흐름을 밀었습니다.이렇게 하면 추류 효과도 실현되지만 입력원을 다시 지정할 때 허용되지 않습니다. 먼저 끝내기 전의 ffmpeg가 ffmpeg 입력원을 지정해야 합니다. 그러면 연결을 한 번 끊고 서버에서 데이터를 다시 받아야 합니다.나중에 파이프로 전송할 생각을 했는데 입력단의 데이터만 바꾸고 파이프의 출력단을 ffmpeg의 입력단에 놓고 파이프를 닫지 않으면 입력원의 전환을 실현할 수 있기 때문에 다방면으로 검색을 했는데 node에서 발견되었다.js에는
var fs = require('fs')
var rs = fs.createReadStream('E://KuGou//08.mp3', { highWaterMark: 4608 })
var ws = fs.createWriteStream('E://KuGou//')
fs.pipe(ws)

이 두 데이터 흐름은 파이프 조작을 하고 이중 작업 흐름도 있으며 읽기와 쓰기 기능이 있지만 동시에 읽기와 쓰기 조작을 연구해 내지 못했다.분명히 우리가 ffmpeg를 조작하는 데 필요한 것은 읽을 수 있고 쓸 수 있는 파이프이며, 닫을 수 없다.나중에 우리가 원래 tcp 프로토콜을 사용했는데 tcp의 socket도 파이프 역할을 할 수 있고 데이터를 나누어 주는 데도 사용된다는 것을 알게 되었다.그래서 나는 tcp 클라이언트와 서버 수신단이 전문적으로 socket으로 파이프를 충당한다고 썼다.
server:
var net = require('net')
var  TcpServer = net.createServer()
    TcpServer.listen(3000, function () {
      console.log('tcp_server listening 3000')
    })
   
    TcpServer.on('connection', (Socket) => {

	      if (trsocket) {
	       var playsure1 = new Ffmpegs()
	        playsure1.input(Socket)
	        playsure1.inputOption('-re')
	        playsure1.outputOptions([
	          '-rtsp_transport',
	          'tcp',
	          '-f',
	          'rtsp'
	        ])
	        playsure1.pipe('rtsp://47.103.130.92:554')
	      }

      Socket.on('data', (data) => {
        console.log(' :')

        // console.log('read data ', data)
      })
        .on('close', () => {
          console.log('close server')
        })
        .on('error', (error) => {
          console.log('error :' + error)
        })
    })

client
var options = {
  host: '127.0.0.1',
  port: 3000
}
var Tcpclient = new net.Socket()
 	Tcpclient.connect(options, () => {
 	var playsure = new Ffmpegs()
     var rs = fs.ReadStream('E://KuGou//08.mp3')
        rs.pipe(Tcpclient)
      console.log(' :')
    })

이것은 tcp 전송을 실현할 수 있지만, 노래가 끝나면, socket도 자동으로 연결을 끊는다.어이가 없다아니면 서버가 자발적으로 끊어진 거야?나중에 ffmpeg 전송이 끝난 신호를 찾아봤는데 자동으로 연결이 끊어지는 거예요.그래서 나는 그것의 설정을 바꾸었다
playsure1.pipe('rtsp://47.103.130.92:554', { end: false, autoClose: false })// 

ffmpeg의 출력을 설정했습니다.그러나 소켓이 끊어지는 것을 발견하고 입력단과 관련되어 입력단을 변경하는 것이 아닌가 생각했다
rs.pipe(Tcpclient, { end: false, autoClose: false })

네, 계속 연결이 돼서 거의 성공한 것 같아요.그러나 내가 입력 파일을 조작하러 갔을 때 안 되고 입력 원본을 바꿀 수 없다는 것을 발견했다. (방법이 틀릴 수도 있고 뒤에 직접 파일을 바꾸지 않았다.) 우리가 입력 원본을 제어하고 수시로 멈추는 등 조작을 해야 하기 때문에 입력 전송 속도에 대한 요구가 있어야 한다.ffmpeg 자체가 출력 형식을 설정할 수 있다는 생각에 아예 클라이언트에서 ffmpeg를 만들어서 전송 속도와 형식을 제어하는 클라이언트의 코드 변경은 다음과 같다.
	var Tcpclient = null
    Tcpclient = new net.Socket()
   var playsure = new Ffmpegs()
    Tcpclient.connect(options, () => {
      playsure.input('E://KuGou//08.mp3')
      playsure.inputOption('-re')
      playsure.outputOptions([
        '-rtsp_transport',
        'tcp',
        '-f',
        'mp3'
      ])
      playsure.output(Tcpclient, { end: false, autoClose: false })
      playsure.run()

현재 socket이 끊어지지 않기 때문에 입력 원본의 데이터를 변경할 수 있습니다. 클라이언트 안의 ffmpeg는 데이터 형식을 제어하는 데 사용됩니다. 현재 연결된 socket만 기록하고 그 안에만 데이터를 전송하면 됩니다.client의 ffmpeg 우리는 임의로 끊고 socket에 전송된 데이터를 전환하여 동적 전환 ffmpeg의 입력 데이터를 실현할 수 있습니다. ffmpeg 전송이 끝나면 end 신호를 보냅니다.
 playsure.on('end', () => {
       console.log(' ')
      })

ffmpeg를 node에서 닫습니다.js에서 나는 kill () 를 사용하여 끝냈지만, ffmpeg가 끝낸 것은 끝이었다. 바로 오류가 발생했다
Error: ffmpeg was killed with signal SIGKILL

아직 그것에 대해 연구를 진행하지 않았습니다. 저는 직접 그것을 try로 떨어뜨렸습니다. 상관하지 않았습니다. 다음에 다시 호출할 때도 문제가 없습니다.

좋은 웹페이지 즐겨찾기