5

私は Node.js を初めて使用し、child.spawn を利用して、ライブ ビデオをキャプチャし、rtmp 経由で Adob​​e Media Server に送信するために使用されている 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();
    });

しかし、それはうまくいかないようです。テスト ボックスに rtmp フィードが引き続き表示されます。

Node.jsのstdinを介してFFMPEGにシャットダウンコマンドを渡す方法はありますか?

前もって感謝します!

リック

4

4 に答える 4

3

次のコードは、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 を正常にシャットダウンします。

私の次のタスクは、タイムアウトの現在のテスト方法とは対照的に、Web インターフェイスからトリガーされたイベントを介してシャットダウンすることです。

Windows のタスク マネージャーを見ると、セカンダリ ノード プロセスと同様に FFMPEG プロセスが閉じます。

この理由は、私が見つけた node-ffmpeg モジュールのどれも、キャプチャ入力を介したライブ ストリーミングをサポートしていなかったためです。主に既存のコンテンツのトランスコードを目的としているようです。この最終的な成果は、理想的には、FFMPEG を開始および停止できる Web ベースのインターフェイスになります。私たちのユース ケースでは、標準の mp4 ファイルを保存できないため、Adobe Media Server のソースとして Adob​​e Flash Media Live Encoder を置き換えます。

于 2013-01-10T15:50:20.753 に答える
0

以下は、Node.js を使用してライブ FFMPEG セッションを開始および終了する際の問題に対する、多かれ少なかれ最終的な解決策です。

    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() を介してインスタンス化される「module.js」ファイルにカプセル化されます。「状態」が格納されているテキスト ファイルを読み取ります。この状態は、ルート アプリケーションの書き込み/読み取りメソッドによって切り替えられます。on('data') イベントでは、ファイルを読み取り、状態が false に変化したことを検出すると、「q」コマンドを stdin に書き込んで FFMPEG をシャットダウンします。

大規模に実装する場合にデータベースを使用して改良する以外に、これをコーディングするよりエレガントな方法に関するフィードバックをお待ちしています。

于 2013-01-10T21:56:01.270 に答える
0

ファイルがffmpegにストリーミングされた後、EOFを送信する必要があります。その後、ffmpeg は終了し、正しくシャットダウンします

于 2013-06-01T17:28:20.890 に答える
0

あなたは単にそれを殺すことができます。

ffmpeg.kill(SIGHUB)

またはその他の kill シグナルについては、http://en.wikipedia.org/wiki/Unix_signalを参照してください。


あなたの例を正しく理解していれば、ストリームを含むノードプロセスのすべての引数をffmpegに渡します。動作させるにffmeg.end()は、ノード プロセスから直接ストリーミングする必要があります。ffmpeg は、カメラからのデータを連続して受信すると停止しないと思います。

于 2013-01-07T21:50:00.670 に答える