functorial
functorial

Reputation: 338

Node.js child_process TypeError: Cannot read property '_writableState' of undefined

I am trying to wrap a piece of ffmpeg's functionality in a Node.js API, using the child_process library, but when I attempt to send any data to ffmpeg's stdin pipe, I get an error TypeError: Cannot read property '_writableState' of undefined.

import {spawn} from "child_process"

export default frames => {
    // Spawn ffmpeg process
    const ffmpeg = spawn("ffmpeg", ["-f", "image2pipe", "-i", "-", "output.mkv"])
    // Send frames to ffmpeg as stdin
    frames.forEach(ffmpeg.stdin.write)

    // Listen for output and errors
    return new Promise((resolve, reject) => {
        const chunks = []

        ffmpeg.stdout.on("data", chunks.push)
        ffmpeg.stderr.on("data", reject(data))
        ffmpeg.on("close", code =>
            resolve(Buffer.concat(chunks))
        )
    })
}

Error:

TypeError: Cannot read property '_writableState' of undefined
    at Writable.write (_stream_writable.js:270:20)
    at Array.forEach (<anonymous>)
    at exports.default (/home/fiendfan1/workspace/nodejs/declare/dist/app/common/encodeVideo.js:21:12)
    at _callee$ (/home/fiendfan1/workspace/nodejs/declare/dist/app/tests/video.js:34:84)
    at tryCatch (/home/fiendfan1/workspace/nodejs/declare/node_modules/regenerator-runtime/runtime.js:65:40)
    at Generator.invoke [as _invoke] (/home/fiendfan1/workspace/nodejs/declare/node_modules/regenerator-runtime/runtime.js:303:22)
    at Generator.prototype.(anonymous function) [as next] (/home/fiendfan1/workspace/nodejs/declare/node_modules/regenerator-runtime/runtime.js:117:21)
    at Generator.tryCatcher (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/util.js:16:23)
    at PromiseSpawn._promiseFulfilled (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/generators.js:97:49)
    at Promise._settlePromise (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/promise.js:574:26)
    at Promise._settlePromise0 (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues [as _onImmediate] (/home/fiendfan1/workspace/nodejs/declare/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:696:18)

Upvotes: 0

Views: 1989

Answers (1)

functorial
functorial

Reputation: 338

The problem here was the way I was sending input to the subprocess.

Instead of sending each image to ffmpeg seperately (ie. frames.forEach(ffmpeg.stdin.write)), you should create a Buffer of all input data to be sent to the process, and write that to its stdin. ffmpeg.stdin.end() should be called after to indicate end of input.

ffmpeg.stdin.write(Buffer.concat(frames))
ffmpeg.stdin.end()

Upvotes: 2

Related Questions