安装 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