Nodejs couldn't find the ffmpeg module for some reason - node.js

I need to display the live streaming vidoe(rtsp) on a website(http, vue framework) with nodejs and vue framework.
I've looked it up a lot and got the basic logic of what they are and how it works.
So I'm planning on to convert rtsp to hls with nodejs using socket.io and display it on a web.(let me know if there's more efficient way way to do it)
The thing is, for some reason, when I try to develop it in my backend(nodejs), node just keep sends me an error that FFMpeg module wasn't found. It's been over a week.. please help.
Btw, all works with ffmpeg cmd(window powerShell).
How I set up(ffmpeg):
downloaded ffmpeg from https://ffmpeg.org/
added to system path: C:\Users\Marie\Desktop\ffmpeg-4.3.1-2020-11-19-full_build\bin\
tested with window powerShell and converted rstp to m3u8:
ffmpeg -i 'rtsp://ip.ip.ip/media/video1' -hls_time 3 -hls_wrap 10 'C:\Users\Marie\Desktop\tmp\hls/streaming.m3u8'
below is a screen shot of no. 3 result
how I set up(nodejs)
npm i ffmpeg fluent-ffmpeg rtsp-ffmpeg
I've just copied and pasted the example working code and changed rtsp link to mine. e.g: (https://www.npmjs.com/package/rtsp-ffmpeg)
=> didn't work out, error says can't find ffmpeg module
set up path manually e.g.) ffmpeg.setFfmpegPath(path)
=> didn't work out. error says can't find ffmpeg module
...
I've seriously tried almost everything like delete, re-install ffmpeg, changed path, added path manyally, .. Please help....
Edited:
package.json
{
"name": "streaming",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"ffmpeg": "0.0.4",
"fluent-ffmpeg": "^2.1.2",
"jsmpeg": "^1.0.0",
"node-media-server": "^2.2.4",
"node-onvif": "^0.1.7",
"node-rtsp-stream": "0.0.9",
"rtsp-ffmpeg": "0.0.15",
"socket.io": "^3.0.4",
"ws": "^7.4.1"
}
}
app.js
const Stream = require('node-rtsp-stream')
// let path = 'C:/Users/Marie/Desktop/ffmpeg-4.3.1-2020-11-19-full_build/bin/ffmpeg.exe'
// let path = 'C:/Users/Marie/Desktop/ffmpeg-4.3.1-2020-11-19-full_build/bin/'
let path = 'C:/Users/Marie/Desktop/ffmpeg-4.3.1-2020-11-19-full_build/bin'
const ffmpeg = require('fluent-ffmpeg')
ffmpeg.setFfmpegPath(path)
stream = new Stream({
name: 'name',
streamUrl: 'rtsp://ip.ip.ip.ip/media/video1',
wsPort: 9999,
ffmpegOptions: { // options ffmpeg flags
'-stats': '', // an option with no neccessary value uses a blank string
'-r': 30 // options with required values specify the value after the key
}
})
Error: spawn ffmpeg ENOENT
app.js (for another test)
const app = require( 'express' )(),
server = require( 'http' ).Server( app ),
io = require( 'socket.io' )( server ),
rtsp = require( 'rtsp-ffmpeg' )
process.env.FFMPEG_PATH = 'C:/Users/Marie/Desktop/ffmpeg-4.3.1-2020-11-19-full_build/bin/ffmpeg.exe'
// console.log( rtsp.FFMpeg )
server.listen( 6147 )
var uri = 'rtsp://ip.ip.ip.ip/media/video1',
stream = new rtsp.FFMpeg( { input: uri } )
io.on( 'connection', function ( socket )
{
var pipeStream = function ( data )
{
socket.emit( 'data', data.toString( 'base64' ) )
}
stream.on( 'data', pipeStream )
socket.on( 'disconnect', function ()
{
stream.removeListener( 'data', pipeStream )
} )
} )
app.get( '/', function ( req, res )
{
res.sendFile( __dirname + '/index.html' )
} )
error:
FMpeg executable wasn't found. Install this package and check FFMpeg.cmd property
nodejs version = 10.16.3

Turns out, this library doesn't work properly in windows. Changed to rtsp-ffmpeg and I got it work.
related git issue: https://github.com/kyriesent/node-rtsp-stream/issues/28
You have to add ffmepg.exe in your project folder to trigger ffmpeg in nodejs. This library can find the path properly in Linux/Unix. Also, many of other functions from this library doesn't work properly (maybe on windows only) so I do not suggest it to anyone who needs to develop it on window, web, and nodejs based environment.
The one I've got it work:
https://www.npmjs.com/package/rtsp-ffmpeg

Related

Cannot find module 'node:url' when executing typescript from webstorm

I have written this small typescript hello world example
import axios from 'axios';
import { wrapper } from 'axios-cookiejar-support';
import { CookieJar } from 'tough-cookie';
const jar = new CookieJar();
const client = wrapper(axios.create({ jar }));
client.get('https://example.com');
when I run this from webstorm i get the following error
/usr/bin/node /usr/local/lib/node_modules/ts-node/dist/bin.js /home/nayana/WebstormProjects/hello-world/hello.ts
Error: Cannot find module 'node:url'
anyone have idea on how to resolve this?
I already tried npm install node:url and url
i have isolated the error to this line
const client = wrapper(axios.create({ jar }));
The issue maybe is related to the node version.
The axios-cookiejar-support requires a specific node version ("node": ">=14.18.0 <15.0.0 || >=16.0.0").
Check node --version and package-lock.json.
Sample:
"node_modules/axios-cookiejar-support": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-4.0.3.tgz",
"integrity": "sha512-fMQc0mPR1CikWZEwVC6Av+sD4cJuV2eo06HFA+DfhY54uRcO43ILGxaq7YAMTiM0V0SdJCV4NhE1bOsQYlfSkg==",
"dependencies": {
"http-cookie-agent": "^4.0.2"
},
"engines": {
"node": ">=14.18.0 <15.0.0 || >=16.0.0"
},
"peerDependencies": {
"axios": ">=0.20.0",
"tough-cookie": ">=4.0.0"
}
},
You might need to install a later version of node.js.
I was running 14.17.6 and after installing 16.17.0 with nvm then I was able to run the project.
If you have nvm installed you can install a specific version of node e.g.
nvm install 16.17.0
make sure the types array in your tsconfig.json file contains "node"
{
"compilerOptions": {
"types": [
// ... your other types
"node"
],
// ... your other settings
},
}
The only thing you need to do, if you didn't install typescript is to change in the vite.config.js file, the import line like this:
import { fileURLToPath, URL } from 'node:url'
To:
import { fileURLToPath, URL } from 'url'

Trouble converting nodejs application to .exe file using pkg

I am trying to convert my NodeJS application to executable. But my application has following codes into it
global.appRoot = path.resolve(__dirname + "/");
let environment = require(appRoot+"/helper/environment.js");
let config = require(path.join(global.appRoot + "/helper/config.js")).get(process.env.NODE_ENV);
statement that is causing an issue. I tried to add some scripts in the package.json, but still I'm getting a warning meassage.
package.json:
"bin": {
"execute": "./app.js"
},
"pkg": {
"scripts": ["**/*/helper/environment.js","**/*/modules/routes.js","**/*/helper/config.js"]
}
Could anyone suggest me what I'm doing wrong? And how to create an executable?

How to set Webpack 5 in Next.js to use a WASM library compiled for Node.js?

Context
I developed a library called wasmetric-crypto in Rust using wasm-bindgen and wasm-pack.
On the other hand, I developed a web app with Next.js 12.1 and installed locally via npm wasmetric-crypto.
I compiled wasmetric-crypto to the Node.js target because I’d like to use this library into the API Routes of my web app and a dependency of this library (rand crate) imports the module crypto from Node.js.
Problem
In the wasmetric-crypto source code a function called encrypt calls to the function rand::thread_rng() and internally it imports the module crypto from Node.js to perform some operations. But when I execute the Next.js app the WASM file is not found by its JS file and my app crashes.
Note that compile wasmetric-crypto to the bundler target is not a solution because the previous error is not reproduced anymore but when I call to the wasmetric-crypto function encrypt, the web app crashes with the error could not initialize thread_rng: Node.js crypto module is unavailable because the rand crate tries to import crypto but it wasn't compiled for Node.js so the module is not available.
Expected solution
Configure Webpack to copy the WASM file (keeping the original filename) next to the JS file that reads it.
Attachments
wasmetric-crypto/Cargo.toml
[package]
name = "wasmetric-crypto"
version = "0.1.0"
authors = ["David Ignacio Espinoza Saavedra"]
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
# Enable JS feature for getrandom to support wasm32-unknown-unknown
getrandom = { version = "^0.2.5", features = ["js"] }
js-sys = "^0.3.56"
rsa = "^0.5.0"
rand = { version = "^0.8.5", features = ["getrandom"] }
sha2 = "^0.10.2"
wasm-bindgen = "^0.2.79"
console_error_panic_hook = { version = "^0.1.7", optional = true }
wee_alloc = { version = "^0.4.5", optional = true }
[dev-dependencies]
wasm-bindgen-test = "^0.3.29"
[profile.release]
opt-level = "s"
wasmetric-crypto/lib.rs
pub fn encrypt(&self, data: &Uint8Array) -> JsResult<ArrayBuffer> {
match &self.public_key {
Some(public_key) => {
let mut rng = rand::thread_rng(); // Error is raised here
// Some code
}
None => Err(JsError::new("The public key was not set to this instance")),
}
}
wasmetric-crypto/pkg/wasmetric_crypto.js
// Snippet of code generated by wasm-pack where the WASM file is read
const path = require('path').join(__dirname, 'wasmetric_crypto_bg.wasm');
const bytes = require('fs').readFileSync(path);
const wasmModule = new WebAssembly.Module(bytes);
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
wasm = wasmInstance.exports;
module.exports.__wasm = wasm;
app/package.json
{
"name": "ferrisdrive_file-repository",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^12.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"wasmetric-crypto": "file:../vendor/wasmetric-crypto/pkg",
}
app/next.config.js
module.exports = {
reactStrictMode: true,
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
config.experiments = {
asyncWebAssembly: true,
layers: true,
};
return config;
},
};
app/pages/api/files/index.js
import { WASMetricCrypto } from "wasmetric-crypto";
async function encryptSignature(signature) {
const publicKeyBuffer = await fs.readFile("secrets/key.pub");
const crypto = WASMetricCrypto.withPublicKey(
bufferToUint8Array(publicKeyBuffer, publicKeyBuffer.byteOffset)
);
return crypto.encrypt(bufferToUint8Array(signature, signature.byteOffset)); // Call to encrypt from WASM
}
This is the .next folder generated by Webpack and wasmetric_crypto_bg.wasm should be located next to files.js because that JS file reads the WASM file when the app is bundled.
Some other ideas to resolve my problem are welcome

Fatal error when scraping dynamic page content with x-ray and x-ray-phantom

I am getting this error in the command line when I run app.js on node:
FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
Abort trap: 6
This is what am app.js looks like:
var phantom = require('x-ray-phantom');
var Xray = require('x-ray');
var fs = require('fs');
x = new Xray().driver(phantom());;
x('http://www.bbc.co.uk/news', '.most-popular__list panel-read li', [{
content: ''
}])(function (err, results) {
fs.writeFile('results.json', JSON.stringify(results, null, '\t'));
})
My package.json
{
...
"dependencies": {
"phantomjs": "^1.9.19",
"x-ray": "^2.0.2",
"x-ray-phantom": "^1.0.1"
}
...
}
My node version is v5.3.0, Npm version is 3.3.12, Phantomjs version is 1.9.8. I am on a Mac El Capitan 10.11.1
Check if this works:
x = new Xray().driver(phantom({
dnodeOpts: {
weak: false
}
}));
I use phantom instead of x-ray-phantom and I encountered the same issue. It appears that the module node-weak is broken (https://github.com/TooTallNate/node-weak/issues/65), and bypassing this module as this link suggests has solved my case.

Using Benchmarkjs with Webpack and Babel

I'm trying to get some basic benchmark tests working and am having trouble figuring out the right configuration. I'm trying to use Benchmarkjs with webpack and babel to transpile my code to es5. I created a benchmarks.webpack.js as an entry point which looks like this:
var context = require.context('./src/js', true, /-benchmark\.js$/);
context.keys().forEach(context);
module.exports = context;
I then have a benchmark file that I want to run (test-benchmark.js):
import benchmark from 'benchmark';
import benchmarks from 'beautify-benchmark';
let suite = new benchmark.Suite;
suite.add('RegExp#test', function() {
/o/.test('Hello World!');
})
.add('String#indexOf', function() {
'Hello World!'.indexOf('o') > -1;
})
.on('cycle', function(event) {
benchmarks.add(event.target);
})
.on('complete', function() {
benchmarks.log();
})
.run();
I updated my webpack build to try and transpile the benchmarks:
_.assign(config, {
devtool: 'eval-cheap-module-source-map',
output: {
path: path.join(__dirname, 'build/benchmark'),
filename: 'benchmark.js',
publicPath: '/'
},
entry: [
'./benchmarks.webpack.js'
],
plugins: [
],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel?stage=0'],
include: path.join(__dirname, 'src/js')
},
]
},
});
Finally, I want to be able run this from an npm script:
"scripts": {
"bench": "webpack --config webpack.bench.config.js && node build/benchmark/benchmark.js"
},
However, I'm getting warnings that the result of the benchmark dependency is an expression and there no suitable loaders for the .json, .txt, etc files. I tried hacking up Benchmarkjs to export correctly but was not successful.
WARNING in ./~/benchmark/benchmark.js
Critical dependencies:
1122:34-49 the request of a dependency is an expression
# ./~/benchmark/benchmark.js 1122:34-49
WARNING in ./~/benchmark/package.json
Module parse failed: /home/bill/dev/levelstory/react-client-redux/node_modules/benchmark/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "name": "benchmark",
| "version": "1.0.0",
| "description": "A benchmarking library that works on nearly all JavaScript platforms, supports high-resolution timers, and returns statistically significant results.",
# ./~/benchmark ^\.\/.*$
WARNING in ./~/benchmark/LICENSE.txt
Module parse failed: /home/bill/dev/levelstory/react-client-redux/node_modules/benchmark/LICENSE.txt Line 1: Unexpected number
You may need an appropriate loader to handle this file type.
| Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
| Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
| Modified by John-David Dalton <http://allyoucanleet.com/>
# ./~/benchmark ^\.\/.*$
Looks like benchmark does something special with require. That messes it up for Webpack. It has the following lines:
var freeRequire = typeof require == 'function' && require;
...
function req(id) {
try {
var result = freeExports && freeRequire(id);
} catch(e) { }
return result || null;
}
If you comment out the function contents, the error goes away. Given it's not ideal to patch around it this way I would poke the benchmark guys about this directly instead. Perhaps there's something we're missing.

Resources