安装 1 npm install --save fluent-ffmpeg
或者添加
1 2 3 "dependencies" : { "fluent-ffmpeg" : "^2.1.2" }
之后
报错
This relative module was not found:
./lib-cov/fluent-ffmpeg in ./node_modules/fluent-ffmpeg/index.js
解决方法
1 npm install git+https://gitee.com/suniv/node-fluent-ffmpeg.git
或者
1 2 3 "dependencies" : { "fluent-ffmpeg" : "https://gitee.com/suniv/node-fluent-ffmpeg.git" }
当然也可以使用Github上的地址
https://github.com/fluent-ffmpeg/node-fluent-ffmpeg.git
我这里用Github地址下载不下来,才用的镜像地址。
在Windows上无法安装依赖的问题 Code 128
解决方法:
升级Git版本,node-fluent-ffmpeg项目下有部分文件的名称有[]导致Git无法Clone,网上的方法我都试了都不行,但是同事的电脑却可以,所以就怀疑是Git版本的问题,果然升级后就解决了。
视频文件推流 引用及变量
1 2 3 4 5 6 const ffmpeg = require ('fluent-ffmpeg' );const ffmpegPath = "/Users/zhangjian/psvmc/app/me/electron/zjclass/libs/ffmpeg_mac/ffmpeg" ;const inputPath = '/Users/zhangjian/psvmc/app/me/electron/zjclass/libs/mv.mp4' ;const logo = '/Users/zhangjian/psvmc/app/me/electron/zjclass/libs/logo.png' ; const outputPath = 'rtmp://119.3.212.205:1935/live/xiaoming' ;
具体的推流代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 var command = ffmpeg(inputPath) .setFfmpegPath(ffmpegPath) .inputOptions('-re' ) .inputOptions('-ac 2' ) .addInput(logo) .complexFilter([{ filter: 'scale' , options: [600 , -1 ], inputs: '[0:v]' , outputs: 'video' }, { filter: 'scale' , options: [60 , -1 ], inputs: '[1:v]' , outputs: 'logo' }, { filter: 'overlay' , options: { x: 'main_w-overlay_w-15' , y: 15 }, inputs: ['video' , 'logo' ] }]) .on('start' , function (commandLine ) { console .log('[' + new Date () + '] Vedio is Pushing !' ); console .log('commandLine: ' + commandLine); }) .on('error' , function (err, stdout, stderr ) { console .log('error: ' + err.message); console .log('stdout: ' + stdout); console .log('stderr: ' + stderr); }) .on('end' , function ( ) { console .log('[' + new Date () + '] Vedio Pushing is Finished !' ); }) .addOptions([ '-vcodec libx264' , '-preset veryfast' , '-crf 22' , '-maxrate 1000k' , '-bufsize 3000k' , '-acodec libmp3lame' , '-ac 2' , '-ar 44100' , '-b:a 96k' ]) .format('flv' ); command .output(outputPath, { end: true }) .run();
桌面及麦克风推流(MAC) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 const ffmpeg = require ('fluent-ffmpeg' );const ffmpegPath = "/Users/zhangjian/psvmc/app/me/electron/zjclass/libs/ffmpeg_mac/ffmpeg" ;const outputPath = 'rtmp://119.3.212.205:1935/live/xiaoming' ;let audioStream;function getAudioStream ( ) { navigator.mediaDevices.getUserMedia({audio : true , video : false }) .then(function (stream ) { audioStream = stream; pushStream(); stream.onended = () => { console .log('Micro audio ended.' ) } }) .catch(function (error ) { console .log('getUserMedia() failed.' ) }); } var command;function pushStream ( ) { command = ffmpeg("1:0" ) .setFfmpegPath(ffmpegPath) .inputOptions('-f avfoundation' ) .inputOptions('-framerate 30' ) .inputOptions('-video_size 640x480' ) .on('start' , function (commandLine ) { console .log('[' + new Date () + '] Vedio is Pushing !' ); console .log('commandLine: ' + commandLine); }) .on('error' , function (err, stdout, stderr ) { console .log('error: ' + err.message); console .log('stdout: ' + stdout); console .log('stderr: ' + stderr); }) .on('end' , function ( ) { console .log('[' + new Date () + '] Vedio Pushing is Finished !' ); }) .addOptions([ '-vcodec libx264' , '-preset ultrafast' , '-acodec libmp3lame' ]) .format('flv' ); command .output(outputPath, { end: true }) .run(); } document .querySelector(".start_action" ).addEventListener("click" , function ( ) { getAudioStream(); }); document .querySelector(".stop_action" ).addEventListener("click" , function ( ) { if (command){ command.kill(); } });
桌面+麦克风推流(Win) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 const ffmpeg = require ('fluent-ffmpeg' );const ffmpegPath = __dirname+"\\..\\libs\\ffmpeg.exe" ;let command = null ;command = ffmpeg() .setFfmpegPath(ffmpegPath) .input('desktop' ) .inputFormat('gdigrab' ) .input('audio=麦克风 (2- High Definition Audio 设备)' ) .inputFormat('dshow' ) .addOptions([ '-vcodec libx264' , '-preset ultrafast' , '-acodec libmp3lame' , '-pix_fmt yuv422p' ]) .format('flv' ) .output(outputPath, { end: true }) .on('start' , function (commandLine ) { console .log('[' + new Date () + '] Vedio is Pushing !' ); console .log('commandLine: ' + commandLine); }) .on('error' , function (err, stdout, stderr ) { console .log('error: ' + err.message); }) .on('end' , function ( ) { console .log('[' + new Date () + '] Vedio Pushing is Finished !' ); }); command.run();
注意audio=麦克风 (2- High Definition Audio 设备) 后面的中文名称不要用双引号括起来,括起来后推流是报错的!
引用的文件路径中的反斜杠也要注意。
这样其实生成的命令如下
1 ffmpeg -f gdigrab -i desktop -f dshow -i audio=麦克风 (2- High Definition Audio 设备) -vcodec libx264 -preset ultrafast -acodec libmp3lame -pix_fmt yuv422p -f flv rtmp://live.psvmc.cn:1935/live/xiaoming
但是这样的命令直接在cmd中无法运行 要把麦克风名字用双引号括起来才能运行
1 ffmpeg -f gdigrab -i desktop -f dshow -i audio="麦克风 (2- High Definition Audio 设备)" -vcodec libx264 -preset ultrafast -acodec libmp3lame -pix_fmt yuv422p -f flv rtmp://live.psvmc.cn:1935/live/xiaoming
这两个地方不一样真是折腾死我了,花了大半天才找到原因。
获取Windows音视频输入设备 设备管理器 此电脑=>管理=>设备管理器
FFMpeg方式获取 该方式获取的设备如果包含中文则乱码 并且没法在代码中获取到,只能在控制台打印。
1 ffmpeg -list_devices true -f dshow -i dummy
JS获取音视频设备 本来打算用C++获取设备生成DLL,用Node-ffi调用DLL获取,后来发现js就能获取,真是绕了个大圈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 getDeviceList: function ( ) { if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { console .log("menumerateDevices is not supported!" ); } else { let devicelist = { audioinput: [], videoinput: [], audiooutput: [] }; navigator.mediaDevices .enumerateDevices() .then(deviceInfos => { deviceInfos.forEach(e => { if (devicelist[e.kind]) { devicelist[e.kind].push(e); } }); console .info("devicelist:" , devicelist); }) .catch(err => { console .log(`${err.name} :${err.message} ` ); }); } },
获取默认的音频输入设备的名称
注意默认设备的名称的前面被添加上了Default -,
如"Default - 麦克风 (Realtek High Definition Audio)",要进行移除。
1 2 3 4 5 6 7 for (let i = 0 ; i < devicelist.audioinput.length; i++) { let ainput = devicelist.audioinput[i]; if (ainput.deviceId === "default" ) { let defaultname = ainput.label.replace("Default - " , "" ); that.pushStream(defaultname); } }
1 ffmpeg -f gdigrab -i desktop -f dshow -i audio="麦克风 (Realtek High Definition Audio)" -vcodec libx264 -preset ultrafast -acodec libmp3lame -pix_fmt yuv422p -f flv rtmp://live.psvmc.cn/class/110