Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FFMPEG streams still prematurely closing on Windows #63

Closed
bryceroethel opened this issue Feb 27, 2021 · 7 comments
Closed

FFMPEG streams still prematurely closing on Windows #63

bryceroethel opened this issue Feb 27, 2021 · 7 comments

Comments

@bryceroethel
Copy link

Issue:

FFMPEG streams still prematurely closing on Windows.

Steps to reproduce:

Created an opus stream, which instantly closes after initialization. I have made no changes to my code, except for jumping from prism-media 1.2.4 to 1.2.7.

Further details:

  • Operating System: Windows 10 build 20H2
  • Node.js version: 14.15.0
  • Commit I'm using: 1.2.7 (361cb91)
  • FFMPEG version: 4.3.1 (Using ffmpeg-static version 4.2.7)
@amishshah
Copy link
Owner

Can you give a code sample? How prematurely are we talking here?

@bryceroethel
Copy link
Author

It closes almost immediately after stream initialization.
I'm having issues as a dependency that I use that interfaces with prism-media, here is the snippet (With some irrelevant code left out, and comments to make it slightly easier to understand. Keep in mind this is also a TypeScript file):

import { opus as Opus, FFmpeg } from "prism-media";

/* ... Some code here ... */

const transcoder = new FFmpeg(
    args: FFMPEGargs // Some args defined in irrelevant code. Args are correct, I've validated this by running prism media 1.2.4
});

const inputStream = ytdl(url, options); // This creates an input stream with ytdl-core using variables defined in irrelevant code
const output = inputStream.pipe(transcoder);
if (options && !options.opusEncoded) {
    for (const event of evn) {
        inputStream.on(event, (...args) => output.emit(event, ...args));
    }
    inputStream.on("error", () => transcoder.destroy());
    output.on("close", () => transcoder.destroy());
    return output;
};

const opus = new Opus.Encoder({
    rate: 48000,
    channels: 2,
    frameSize: 960
});

const outputStream = output.pipe(opus);

for (const event of evn) {
    inputStream.on(event, (...args) => outputStream.emit(event, ...args));
}

outputStream.on("close", () => {
    transcoder.destroy();
    opus.destroy();
});

return outputStream;

There may be some parts I left out, I can't say I'm super familiar with prism-media itself, I just found it originated from here when trying to find the problem. I also want to mention when I run the exact same code on Debian, it runs with no issues, except for it crashing when multiple effects are set using the -af flag. No issues are found on Windows or Debian when running 1.2.4.

@amishshah
Copy link
Owner

Could you try this:

import { pipeline } from 'stream';

const transcoder = new FFmpeg(
    args: FFMPEGargs // Some args defined in irrelevant code. Args are correct, I've validated this by running prism media 1.2.4
});

const input = ytdl(url, options);

if (options && !options.opusEncoded) {
  return pipeline(input, transcoder);
} else {
  const opus = new Opus.Encoder({
      rate: 48000,
      channels: 2,
      frameSize: 960
  });
  return pipeline(input, transcoder, opus);
}

pipeline looks like it is ideal for your use-case. If this doesn't work, could you also share the arguments that you're passing to FFmpeg?

@bryceroethel
Copy link
Author

bryceroethel commented Mar 7, 2021

Sorry I haven't responded. The arguments I'm passing through are dynamically created, but I do check them before passing them through to make sure they work. Normally, they are just simple arguments such as -af bass=g=10. I'll try pipeline, however it still seems odd that the old code is broken from updating prism-media when, from what I can tell, there have been no syntax changes, and that I only encounter this issue on windows.

@amishshah
Copy link
Owner

amishshah commented Mar 13, 2021

Hi @BR88C. I've released v1.2.8 today. I think the issue was due to enabling shell when spawning FFmpeg. For me, FFmpeg didn't work on Windows for more complex inputs without this option. I'm not sure why FFmpeg has now broken for you on Windows, but to bridge the gap until I can get a better understanding of why it isn't working for you, you can just disable shell now:

const ffmpeg = new prism.FFmpeg({ args, shell: false });

Hope this helps, let me know if it fixes your issue!

Edit: I still highly recommend using pipeline even if this does fix your issue. Pipeline ensures proper clean-up of the streams after they end, and it results in shorter code.

@bryceroethel
Copy link
Author

Thanks, it works like a charm now! I also implemented pipeline, thanks for the tip on that.

@amishshah
Copy link
Owner

No problem, glad to hear! I'll close this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants