Node-red-contrib-ffmpeg-spawn

The ffmpeg node is ready for testing. It is similar to the exec node to spawn ffmpeg, with additional features.

An example flow doing way more than a regular human needs to do:

[{"id":"93d74c4e.4c8fe","type":"ffmpeg-spawn","z":"5967c855.68b978","name":"","outputs":5,"migrate":1e-9,"cmdPath":"ffmpeg","cmdArgs":"[\"-loglevel\",\"error\",\"-nostats\",\"-f\",\"hls\",\"-http_multiple\",\"1\",\"-re\",\"-i\",\"https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on\",\"-c:v\",\"copy\",\"-c:a\",\"aac\",\"-f\",\"mp4\",\"-movflags\",\"+frag_keyframe+empty_moov+default_base_moof\",\"pipe:1\",\"-progress\",\"pipe:3\",\"-f\",\"image2pipe\",\"-vf\",\"select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2\",\"-vsync\",\"vfr\",\"pipe:4\"]","cmdOutputs":4,"killSignal":"SIGTERM","x":400,"y":488,"wires":[["96b432b8.72f38","c5674070.e26ec"],["96b432b8.72f38"],["a03a1b22.1f27a8"],["22984340.c40eac"],["45912098.31d65"]]},{"id":"96b432b8.72f38","type":"mp4frag","z":"5967c855.68b978","name":"","migrate":1e-9,"hlsPlaylistSize":"20","hlsPlaylistExtra":"10","basePath":"abc","x":671,"y":358,"wires":[["379420d.31038e"],["d4600315.dbc7d","97c44c17.d56ce"]]},{"id":"379420d.31038e","type":"ui_mp4frag","z":"5967c855.68b978","name":"","group":"5e1c22f8.d65d2c","order":1,"width":6,"height":4,"readyPoster":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAMAAACtqHJCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMzgwMTE3NDA3MjA2ODExODIyQUIzREQ3RTA0MDAyNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRkU5MkM4RDJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRkU5MkM4QzJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Rjc3RjExNzQwNzIwNjgxMTgyMkFDQTkzQjdGQkY1MzAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDM4MDExNzQwNzIwNjgxMTgyMkFCM0REN0UwNDAwMjQiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7USCkmAAAAM1BMVEUAplH///9Cs3HR6dqc0rDp9O1rwIy43sUmrWJ9xpn0+vbF5NBYun+q2LuNzKTd7+P///8HAxLBAAAAEXRSTlP/////////////////////ACWtmWIAAA6fSURBVHja7d1rY6JIGoBRI6gIXub//9qZ7o4KRdVbZezuJLvnfNpJektujyAg2fwDFG0sAhAICAQEAgIBgYBAQCAgEBAIIBAQCAgEBAICAYGAQEAgIBAQCCAQEAgIBAQCAgGBgEBAICAQQCAgEBAICAQEAgIBgYBAQCAgEEAgIBAQCAgEBAICAYGAQEAggEBAICAQEAgIBAQCAgGBgEBAIIBAQCAgEBAICAQEAgIBgYBAAIGAQEAgIBAQCAgEBAICAYGAQACBgEBAICAQEAgIBAQCAgGBgEAsAhAICAQEAgIBgYBAQCAgEBAIIBAQCAgEBAICAYGAQEAgIBAQCCAQEAgIBAQCAgGBgEBAICAQQCAgEBAICAQEAgIBgYBAQCAgEEAgIBAQCAgEBAICAYGAQEAggEBAICAQEAgIBAQCAgGBgEBAIIBAQCAgEBAICAQEAgIBgYBAAIGAQEAgIBAQCAgEBAICAYGAQACBgEBAICAQEAgIBAQCAgGBgEAsAhAICAQEAgIBgYBAQCAgEBAIIBAQCAgEBAICAYGAQEAgIBAQCCAQEAgIBAQCAgGBgEBAICAQQCAgEBAICAQEAgIBgYBAQCAgEEAgIBAQCAgEBAICAYGAQEAggEBAICAQEAgIBAQCAgGBgEBAIIBAQCAgEBAICAQEAgIBgYBAAIGAQEAgIBAQCAgEBAICAYGAQIAkEAAAAAAAAAAAAAAAAAAAAAAAgD/v0u/efjj0228/L33/c1be+t56/d92+rWi33aZnw2b7fv/6n7+/PZfN12/n/2/0t++b0H3PMbZT6dsIskI1/64+lUXzsQP558/OdxeaL5Rv/9su57WTLPrMdcjJb9cT+TwPtO7IZrR5ctXlmNxwsprp7IwCN2229mPjr9+Mm4qgfxY88e2FTt0yc+P9UB+TMKlKZDLvL35LPyYh7vpMURmWrt9bcz7ZF6TkLfFibwNcqnN6Nt13xpIacLKa6eyMAjd1vZp9e7SNQTy37tfy4odrqtfXFoC+e+Vh4ZAzvONYtn9Y7aG2RRt422wMOb7OLvVdrgtBbLL/P9rL18LpDRhwdqJFwahaf2Wfrgv3IZA7oVEK/aQ+c22KZDkpbtwHma7wmm1BRxnW0l+Wi+VMTO/WEzVaiILO5C4gVogpQkL1k68MIg/bq7fS673n7QEcksrWLH78pbfuN3EgSze00+LbXNK33mv5Vcat/GYm+K87POBFHYg8cvXAilNWLB24oVB6Lj+vDfeF21TILvq5j1lf3Vq3G6GWiBDptf7z4Yk+3MwJ3085k9d+26utAMpvfy5JZDihAVrJ14YNJ3G6lbbxrYxkPe1VF6xw/xD43AonRuKNtswkFNuU7omm9Awf7MvvNJYGTOdl+1hcbyYTmRpBxK/fCWQ0oSFaydcGISG1ee9/eP4Nh/Ir386nJefQsrb8HG+L3gc1F1L282v8ftx9u/CQI6LDWJaHjqeV6fmVsNdduudWnbM9byc5zuJZCKLO5D45eOjyeKEhWsnXBjEdunu91LaLrdJS/3iv8sr9pyc8h3TV8yu4sfR/lDZavrlCdPlO+11ORFTblq364/p2TEz8/KWOXDrFgdju00lkOTlK4GUJixcO+HCINal756zpRcHsjy0La/Y9ETZtfAhJB1/9u/CreZ2Tn95ZicJ/zpPIB1uKp0r6tKzRYV5mdaj7uvns7MvXwmkNGHx2okWBrFz+nlvKh36p6vgvgVv4xWbJjgVjoDT8Q+PfxduNb8mY0wuDi/n67TYQtLh1qfy8mMW5+W6HrW8A4lfvhJIacLitRMtDJ48zzt7e6kE0uU++JYD2a43/KZALpWt5n0bPS5LX56e6xfHGKXzTX1lzOK87FajBjuQ4ssfGgIpTVi8dqKFQWyfXhLPXFD70oG8vx9Op2QrH+ejTdmLccVASmO2BxLsQF4JpDhhlbUTLAxi2+QD3Ha2//0WgRxvqzspfZofDY2LI6NqIKUxmwOJdiCvBFKcsMraCRYGFePynN9+9p/fIpD+9q92y9LnW/1pOXI1kNKYzYFEO5BXAilOWGXtBAuDiuvyI1s/Wz/fIpDD7f1wWpY+zK4V9MvrANVr3qUxWwPZRjuQuM84kOKEVdZOsDCoSLbXc/HM/hcN5Hrr+5y8zvWxDU3Lj7Sl00j76piNgRzCN+kXAilOWGXtBAuDxtNYl9VZ3u8RyHhb831yZqd/HHePy7fbdLhucXk8GrMLvmj0GHUb303+QiDFCasFUl4YVByXa3M3W/DfIZDt/Tf7ZLN8nOk5JleOk+GOb/nfZ8ZsC+SQBtd2HWRfDaQ8YbVAyguDitNy8yhf/PuagRzvH3CH9C7I3W3GzskngsVw2/NbOkHlMZsCqexA4h1Yy21nuZmtBFJeGNQszvOeyjf1fVYg8ZX0/rExjsk/Ot82vGty5Xgb3G4ej9kUSGUHUtqB1W76jGe2FkhxYVCzmzdxnNfykUDWXzb8aCBt92IdVnd1j+nB46V0SjT/5eFozJZAdrXvsxZ2YKdNvBzjma0FUlwY1Ezzld6X73r9y4E03s3bPbauQ3qP0bjYYvsokPHSNGZLIG+177OGO7AwkGBma4EUFwY15/mSPMyX32cG0vp9kPFxW+vqbO1U2GBzW+h5aBnzmUDOTwUSfLf/0DKz1UCmtnpZWZxl7HLfEvy7gTz1jcJhNk3HwgXx1UWJ7CuNp4YxnwlkfCaQy6YhkGhmq4GUFgY1+/k73pg7Hv7MQCrfSd/PDglP6Vv3UHhDrzy0IRjzmUCKJ4rCI7wokGhmq4EMTXs3NqU34Z/LfQi+N/E5gVSuns3vmxhWX0S9PvWAg64+5lOBdM8cYnUNgUQzWw2ktDCoGldfztxtvkogtedinecHGqvHJPTJnih7nvXYvWXPiObGfCqQ0oM9831O9UCima0HUlgYVF0f39+8ZFfW370Osuij9mTFbj5Wl57GOmWfb1D8zuuhOuZzgZyfCaT0dK3Gma0HUlgYVB0eZzb67CnHzwqk4dm843zs8+oUzZh7Qs5quO3yY3Uw5nOBjA3XQfbTcqut33aWn9l6IIWFQdXsxrdD8M27vxzIruXp7sNiS+xXn44fT7IdgkCWt/xHY7YFMh6eud29fyvfvdA+sw2B5BcGVbMzhtfFQv3cW02iLTo5bLguZ+S8mrXllePVcIvnSERjtgXSn8KP6enLj43PxQpntiGQ/MKg6vQ4BB+zx7VfN5D8Z6bHIfb9IVx9ONxhfnInGrPl+yA/PgJfo4/p6cufG5+LFc5sQyD5hUHdfZ0sd+LfIJDzco2vR+hyL1YM5FIbsymQS/aZ4OWXb33sTzizDYHkFwbNp7F2tytR128TSP652G8vBRKN2RLI/HnRY0sgrd9JD2dWIH/QbckPl/x9QV83kF1+mzm9Ekg0ZvNjfw7BFbn05feNgYQzK5A/6H7G8Jy/v+fLBjLkN5nZZvl8IOGYTz84rvt9gcQzK5A/6LaPP4YPN/iCgZzeyjc4fjSQcMzmQO5v99vfFkg8swL5C6ex+uvyCOXLB3IsbDPTC4GEY7YHEnxM/2Ag8cwK5A+67bwPyWfcz314dUMgfWGbuT4ZyPyh7eGYhXnZNSytlwOJZzZeOwJ5ze3pisky/tw/f9AQSOG8zuw0Vlsg80t14Zhp3N38y7PLUbvix/QPBhLPbLx2BPKaLn+A8ql/QKclkNUfulhd6W4K5DjfmMIxk3m5lZXbtC/FGwM/GEg8s/HaEchrDvmbUD/zT7A1BbLaF63OrrYE0i8OVsIxb/OyG9YfNEp3kGx/UyDxzMZrRyCv6eOvf/7dP+IZBLK8mzHzl2BWH43DQHJTG4+5nJflA0lKd5D0HwpkNWWVmd1Wz3gL5OOOmS8mbD7rz0C3B7L+Y5TH9H3zmUB+7uIqY3blRZBu96fS/HwskMqExWtHIK9ZLt3hqUCO1UD20VdMXwmkXw2V/rnKpwLpZ2/LpTH39SsRq5voj78lkMqEbes7EIF8XP5rPi2BnDfVQJKPOKULaM8HclgfrKXz8EQg03xai2NO1X1olx4CTY2BdOFyrExY7WmRAnnJNfve3hDIYdMQyHB9a3jix/OBXNcH+ekF7PZApsWSKI457EoHi6tASufrSsdi13A5Vias9rRIgbxkyi7VaiC746YlkM3QRXv+DwcyrgdLL7q0BnKfk+qY26T2cV881XbIf0xP/+HikkVxOVYmLF47AvmNp7H6xkC6fl89bHk8w22cv1mH3yNqDuSUOVpLTx01BTKbk5Yxz4s36aF8Lnq/PClc/IfTbLdaWo61CYvXjkC+vkv/64jg0G+///vJ7eEWvpsHAAAAAAAAAAAAAAAAAAAAAAAAwP+Xf4AigYBAQCAgEBAICAQEAgIBgYBAAIGAQEAgIBAQCAgEBAICAYGAQACBgEBAICAQEAgIBAQCAgGBAAIBgYBAQCAgEBAICAQEAgIBgQACAYGAQEAgIBAQCAgEBAICAQQCAgGBgEBAICAQEAgIBAQCAgEEAgIBgYBAQCAgEBAICAQEAggEBAICAYGAQEAgIBAQCAgEBAIIBAQCAgGBgEBAICAQEAgIBBAICAQEAgIBgYBAQCAgEBAICAQQCAgEBAICAYGAQEAgIBAQCAgEEAgIBAQCAgGBgEBAICAQEAggEBAICAQEAgIBgYBAQCAgEBAIIBAQCAgEBAICAYGAQEAgIBBAICAQEAgIBAQCAgGBgEBAICAQQCAgEBAICAQEAgIBgYBAQCCAQEAgIBAQCAgEBAICAYGAQEAggEBAICAQEAgIBAQCAgGBgEAAgYBAQCAgEBAICAQEAgIBgYBAAIGAQEAgIBAQCAgEBAICAYGAQACBgEBAICAQEAgIBAQCAgGBAAIBgYBAQCAgEBAICAQEAgIBgQACAYGAQEAgIBAQCAgEBAICAQQCAgGBgEBAICAQEAgIBAQCAgEEAgIBgYBAQCAgEBAICAQEAggEBAICAYGAQEAgIBAQCAgEBAIk/gX38R0SGa0LJgAAAABJRU5ErkJggg==","errorPoster":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAMAAACtqHJCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMzgwMTE3NDA3MjA2ODExODIyQUIzREQ3RTA0MDAyNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRkU5MkM5MTJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRkU5MkM5MDJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Rjc3RjExNzQwNzIwNjgxMTgyMkFDQTkzQjdGQkY1MzAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDM4MDExNzQwNzIwNjgxMTgyMkFCM0REN0UwNDAwMjQiLz4gPC9yZGY6RGVzY3Jp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","hlsJsConfig":"{\"liveDurationInfinity\":true,\"liveBackBufferLength\":5,\"maxBufferLength\":10,\"manifestLoadingTimeOut\":1000,\"manifestLoadingMaxRetry\":10,\"manifestLoadingRetryDelay\":500}","retry":true,"play":true,"unload":true,"threshold":0.5,"players":["socket.io","hls.js","hls","mp4"],"x":915,"y":103,"wires":[[]]},{"id":"bd56b3d.24cd65","type":"inject","z":"5967c855.68b978","name":"start default","props":[{"p":"action","v":"{\"command\":\"start\"}","vt":"json"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payloadType":"str","x":122,"y":265,"wires":[["93d74c4e.4c8fe"]]},{"id":"143a363a.17fc7a","type":"inject","z":"5967c855.68b978","name":"stop default","props":[{"p":"action","v":"{\"command\":\"stop\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":122,"y":366,"wires":[["93d74c4e.4c8fe"]]},{"id":"e90ee3ed.da535","type":"delay","z":"5967c855.68b978","name":"delay","pauseType":"delayv","timeout":"1","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":450,"y":104,"wires":[["93d74c4e.4c8fe"]]},{"id":"c5674070.e26ec","type":"function","z":"5967c855.68b978","name":"restart","func":"const { status, code, signal, killed } = msg.payload;\n\n\nif (status === 'close' && killed === false) {\n    return { action: { command: 'start' }, delay: 5000 };\n}\n\nreturn;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":330,"y":104,"wires":[["e90ee3ed.da535"]]},{"id":"781251e2.1e719","type":"inject","z":"5967c855.68b978","name":"stop SIGHUP","props":[{"p":"action","v":"{\"command\":\"stop\",\"signal\":\"SIGHUP\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":122,"y":402,"wires":[["93d74c4e.4c8fe"]]},{"id":"c7c78a8d.180f48","type":"inject","z":"5967c855.68b978","name":"stop SIGINT","props":[{"p":"action","v":"{\"command\":\"stop\",\"signal\":\"SIGINT\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":122,"y":438,"wires":[["93d74c4e.4c8fe"]]},{"id":"ccf3b2e6.7f78f","type":"inject","z":"5967c855.68b978","name":"stop SIGKILL","props":[{"p":"action","v":"{\"command\":\"stop\",\"signal\":\"SIGKILL\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":122,"y":474,"wires":[["93d74c4e.4c8fe"]]},{"id":"2db4e64d.d4022a","type":"inject","z":"5967c855.68b978","name":"stop SIGTERM","props":[{"p":"action","v":"{\"command\":\"stop\",\"signal\":\"SIGTERM\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":132,"y":510,"wires":[["93d74c4e.4c8fe"]]},{"id":"1d5155f9.0f929a","type":"debug","z":"5967c855.68b978","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1339,"y":400,"wires":[]},{"id":"a03a1b22.1f27a8","type":"function","z":"5967c855.68b978","name":"errors","func":"const { payload } = msg;\n\nreturn { payload: payload.toString() };","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1219,"y":400,"wires":[["1d5155f9.0f929a"]]},{"id":"22984340.c40eac","type":"function","z":"5967c855.68b978","name":"progress","func":"const props = msg.payload.toString().split('\\n');\n\nconst progress = {};\n\nprops.forEach(item => {\n    \n    const [name, value] = item.split('=');\n    \n    if (name && value) {\n    \n        progress[name] = value;\n\n    }\n    \n});\n\nconst color = progress['progress'] === 'continue' ? 'green' : 'red';\n\nconst message = `fps: ${progress['fps']}, bitrate: ${progress['bitrate']}`;\n\nnode.status({ fill: color, shape: 'dot', text: message });\n\nreturn { payload: progress };","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1210,"y":498,"wires":[["21bb6347.11389c"]]},{"id":"21bb6347.11389c","type":"debug","z":"5967c855.68b978","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1340,"y":498,"wires":[]},{"id":"7f035cf8.c1f6d4","type":"function","z":"5967c855.68b978","name":"filename","func":"const { payload } = msg;\n\nif (Buffer.isBuffer(payload)) {\n\n    msg.filename = context.get('filename');\n    \n    return msg;\n}\n\nconst { status } = payload;\n\nif (status === 'spawn') {\n\n    context.set('filename', `videos/abc/p/${Date.now()}.mp4`);\n\n    \n} else if (status === 'close') {\n    \n    context.set('filename', undefined);\n\n}\n\nreturn;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n\ncontext.set('filename', undefined);","finalize":"// Code added here will be run when the\n// node is being stopped or re-deployed.\n\ncontext.set('filename', undefined);","x":1084,"y":198,"wires":[["fb03fea0.c6e59"]]},{"id":"d4600315.dbc7d","type":"ffmpeg-spawn","z":"5967c855.68b978","name":"","outputs":2,"migrate":1e-9,"cmdPath":"","cmdArgs":"[\"-f\",\"mp4\",\"-i\",\"pipe:0\",\"-c:v\",\"copy\",\"-c:a\",\"copy\",\"-f\",\"mp4\",\"-movflags\",\"+faststart+empty_moov\",\"pipe:1\"]","cmdOutputs":1,"killSignal":"SIGTERM","x":923,"y":198,"wires":[["7f035cf8.c1f6d4"],["7f035cf8.c1f6d4"]]},{"id":"fb03fea0.c6e59","type":"file","z":"5967c855.68b978","name":"","filename":"","appendNewline":false,"createDir":true,"overwriteFile":"false","encoding":"none","x":1214,"y":198,"wires":[["9c69a6cf.45c9c8"]]},{"id":"1b3c5f.f19183a1","type":"inject","z":"5967c855.68b978","name":"write start default","props":[{"p":"action","v":"{\"subject\":\"write\",\"command\":\"start\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":674,"y":103,"wires":[["96b432b8.72f38"]]},{"id":"9c69a6cf.45c9c8","type":"debug","z":"5967c855.68b978","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1334,"y":198,"wires":[]},{"id":"97c44c17.d56ce","type":"function","z":"5967c855.68b978","name":"filename","func":"const { payload, action } = msg;\n\nif (Buffer.isBuffer(payload)) {\n\n    msg.filename = context.get('filename');\n    \n    return msg;\n}\n\nif (typeof action === 'object') {\n    const { command } = action;\n    \n    if (command === 'start') {\n        \n        context.set('filename', `videos/abc/r/${Date.now()}.mp4`);\n        \n    } else if (command === 'stop') {\n        \n        context.set('filename', undefined);\n        \n    }\n}\n\nreturn;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n\ncontext.set('filename', undefined);","finalize":"// Code added here will be run when the\n// node is being stopped or re-deployed.\n\ncontext.set('filename', undefined);","x":1085,"y":298,"wires":[["9c6dad2f.e4165"]]},{"id":"9c6dad2f.e4165","type":"file","z":"5967c855.68b978","name":"","filename":"","appendNewline":false,"createDir":true,"overwriteFile":"false","encoding":"none","x":1215,"y":298,"wires":[["92473934.4b74b8"]]},{"id":"92473934.4b74b8","type":"debug","z":"5967c855.68b978","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1335,"y":298,"wires":[]},{"id":"45912098.31d65","type":"pipe2jpeg","z":"5967c855.68b978","name":"","x":799,"y":573,"wires":[["e382fb4.ce83a08"]]},{"id":"e382fb4.ce83a08","type":"image","z":"5967c855.68b978","name":"jpeg preview","width":"400","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":false,"outputs":0,"x":949,"y":573,"wires":[]},{"id":"e27f974a.0ef868","type":"comment","z":"5967c855.68b978","name":"start ffmpeg","info":"","x":122,"y":229,"wires":[]},{"id":"36953f1b.fdbac","type":"comment","z":"5967c855.68b978","name":"- - - - - daemonize - - - - -","info":"","x":390,"y":69,"wires":[]},{"id":"d9f21b53.703b28","type":"comment","z":"5967c855.68b978","name":"- - - - - - - - - - jpegs - - - - - - - - - -","info":"","x":878,"y":538,"wires":[]},{"id":"8b84ea34.3465f8","type":"comment","z":"5967c855.68b978","name":"- - - - - progress logs - - - - -","info":"","x":1269,"y":463,"wires":[]},{"id":"e1ae8181.29ed6","type":"comment","z":"5967c855.68b978","name":"- - - - - error logs - - - - -","info":"","x":1277,"y":365,"wires":[]},{"id":"4220195.ce45ae8","type":"comment","z":"5967c855.68b978","name":"- - - - - - - - - save raw mp4 files - - - - - - - - - -","info":"","x":1204,"y":263,"wires":[]},{"id":"1640592.c4917a7","type":"comment","z":"5967c855.68b978","name":"- - - - - - - - - - - - - - - - - save processed mp4 files - - - - - - - - - - - - - - - - - ","info":"","x":1113,"y":163,"wires":[]},{"id":"ec9153b3.c3be6","type":"comment","z":"5967c855.68b978","name":"stop ffmpeg","info":"","x":122,"y":330,"wires":[]},{"id":"2e0fa25d.f5878e","type":"comment","z":"5967c855.68b978","name":"- output mp4 -","info":"","x":673,"y":68,"wires":[]},{"id":"fd12ad4d.89379","type":"comment","z":"5967c855.68b978","name":"- view mp4 -","info":"","x":914,"y":68,"wires":[]},{"id":"5e1c22f8.d65d2c","type":"ui_group","z":"","name":"group 2","tab":"b6843d96.72b57","order":2,"disp":false,"width":"6","collapse":false},{"id":"b6843d96.72b57","type":"ui_tab","z":"","name":"socket.io sub","icon":"dashboard","disabled":false,"hidden":false}]

Edit: remove reference to #branch for mp4frag, it has been merged with master

nodes listed that begin with kevinGodell/ are not published to npm and will be installed from github.

  • npm install kevinGodell/node-red-contrib-ffmpeg-spawn
  • npm install kevinGodell/node-red-contrib-mp4frag
  • npm install kevinGodell/node-red-contrib-ui-mp4frag
  • npm install node-red-contrib-pipe2jpeg

5 Likes

Hi Kevin,
Since I cannot test your node at the moment, it would be nice if you could explain those features on your readme page.
When I saw the enthousiam recently from @SuperNinja and @krambriw (when you announced that you wanted to build this new node), then I assume this node earns to be installed for some reasons :wink:
Bart

You may notice the lack of help text, also. I will probably have a chance to make a rough draft and get something online if I can find the time today.

For now, I will make a general list right here in no particular order:

  • It designed to be used for long running ffmpeg processes, therefore internally it will always use child_process spawn.

  • Video can be piped into stdin (typically when using -i pipe:0), allowing for pipelining video modification or creation. I don't think using stdin was an option with the exec node. The example flow shows stream copying mp4 to fix the durations before writing to disk using the file node.

  • Extra care is taken to close the ffmpeg process. Some kill codes do not immediately close the process unless the stdin pipe is destroyed properly causing it to hang. Use sigterm to allow ffmpeg to close gracefully and not corrupt video output.

  • The existing ffmpeg process must close before another may be spawned. I do not want the chance of orphaned processes building up on the system. If an existing ffmpeg process is running, you must send a stop command before it will respond to a start command. A problem I had with the exec node would be that I accidentally hit the start button while it was already running, causing it to output video from 2 simultaneously running processes.

  • You can select the number of process outputs from 0 - 5, which correspond when ffmpeg outputs to stdout, stderr, stdio[3], stdio[4], stdio[5]. If you really need more pipes than 5, I can probably adjust that with a setting that you can add to settings.js. 5 seemed reasonable for now.

  • By default, the node will always have at least 1 output, which is status. You may not need ffmpeg to output to pipes 1 - 5 because you may be writing the files directly to disk.

  • It is made to work with my other cctv nodes by passing the action object containing a command, etc.

  • The example flow shows how to output ffmpeg's progress details and then parse and display it, such as fps and bitrate.

3 Likes

To install, I do recommend to use yarn instead, much, much faster

yarn add kevinGodell/node-red-contrib-ffmpeg-spawn
yarn add kevinGodell/node-red-contrib-mp4frag#recorder
yarn add kevinGodell/node-red-contrib-ui-mp4frag
yarn add node-red-contrib-pipe2jpeg

Dear Kevin, I must have done something wrong
The ffmpeg crashes and restarts. Error message is as seen in debug window and more in detail:
https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on: Protocol not found
Did you mean file:https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on?

It could be that the url is down. That was just a random video url I found online. Also, I recognize the error message to be from the older version of mp4frag. I have noticed that yarn has issues when installing branches. I usually have to install it twice with yarn because it seems to confuse branches.

Please press the button next to the error log debugger to view the stderr output from ffmpeg.

Edit. mp4frag should have 2 outputs. Yours only has 1. Yarn didn’t install the branch. You may have to do ‘yarn upgrade-interactive’ and select to install it. Maybe twice. I am no yarn expert. It is faster but not always right.

HI all,
For me, the installation went well with npm, and not too long, about less than a minute for each. :ok_hand:
@kevinGodell , well done for your work! My RTSP camera streams are working with your node, and so far I haven't had any dual streams running by mistake. :+1:

So I'm going to switch all my EXE nodes to your ffmepg-spawn node for my RTSP cameras, BUT I need some advice: how to inject a msg. to modify the command in the Args {[ ]} of your node? (to switch from an SD stream to an FHD stream by injecting another RTSP address).
I join @BartButenaers on the need for a readme. At least the different msg. that we can inject to control your node directly.
This is the least exciting part of the project and the most time consuming but essential :yum:

1 Like

It is in the plans to be able to change the cmd args dynamically via the input. I have that written in the todo list. But the feature is not built yet.

Support added for injecting args via the action object.

Install the latest push from github for node-red-contrib-ffmpeg-spawn.

2 sample inject nodes that can be used to start the ffmpeg process with the args, or restart the ffmpeg process using the new args:

[
    {
        "id": "e27f974a.0ef868",
        "type": "comment",
        "z": "5967c855.68b978",
        "name": "start args",
        "info": "",
        "x": 111,
        "y": 151,
        "wires": []
    },
    {
        "id": "42cda3a1.8f558c",
        "type": "inject",
        "z": "5967c855.68b978",
        "name": "start args",
        "props": [
            {
                "p": "action",
                "v": "{\"command\":\"start\",\"args\":[\"-loglevel\",\"error\",\"-nostats\",\"-f\",\"hls\",\"-http_multiple\",\"1\",\"-re\",\"-i\",\"https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on\",\"-c:v\",\"copy\",\"-c:a\",\"aac\",\"-f\",\"mp4\",\"-movflags\",\"+frag_keyframe+empty_moov+default_base_moof\",\"pipe:1\",\"-progress\",\"pipe:3\",\"-f\",\"image2pipe\",\"-vf\",\"select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2\",\"-vsync\",\"vfr\",\"pipe:4\"]}",
                "vt": "json"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 112,
        "y": 186,
        "wires": [
            [
                "93d74c4e.4c8fe"
            ]
        ]
    },
    {
        "id": "6b35f3b5.48ffcc",
        "type": "inject",
        "z": "5967c855.68b978",
        "name": "restart args",
        "props": [
            {
                "p": "action",
                "v": "{\"command\":\"restart\",\"args\":[\"-loglevel\",\"error\",\"-nostats\",\"-f\",\"hls\",\"-http_multiple\",\"1\",\"-re\",\"-i\",\"https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on\",\"-c:v\",\"copy\",\"-c:a\",\"aac\",\"-f\",\"mp4\",\"-movflags\",\"+frag_keyframe+empty_moov+default_base_moof\",\"pipe:1\",\"-progress\",\"pipe:3\",\"-f\",\"image2pipe\",\"-vf\",\"select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2\",\"-vsync\",\"vfr\",\"pipe:4\"]}",
                "vt": "json"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 121,
        "y": 277,
        "wires": [
            [
                "93d74c4e.4c8fe"
            ]
        ]
    },
    {
        "id": "4ebc8cba.dedf34",
        "type": "comment",
        "z": "5967c855.68b978",
        "name": "restart args",
        "info": "",
        "x": 121,
        "y": 242,
        "wires": []
    }
]

If you are going to start an ffmpeg process with a new set of args, then you must first stop the existing process.

Or you can use the shortcut command restart, which will stop the existing and then immediately start the new. In the code, it does async await stop(), ensuring that the previous ffmpeg process closes before spawning a new one.

Edit. just one thought. if you are piping out video, you will already have to have the necessary nodes in place to receive the expected video. I think we will be limited to the fact that you cannot dynamically change the number of outputs as that has to be set ahead of time. So, when changing the args, the new output must be somewhat similar to the previous output so that the flow can be compatible.

1 Like

Also, if anybody is looking for test video streams that are open access, I found a curated list on a github repo that had many live hls video links. The lists are in the channels folder.

Warning. I have not reviewed what is playing on those video streams. I found one there playing the weather channel and used it in the shared flow example.

2 Likes

Perhaps you can add a checkbox "Single output with topics" (or something like that). When activated, your node gets a single output (see here). And all the output messages will be send to that output, but you specify a topic on each output messge. That way the messages can be routed/filtered afterwards in the next nodes of the flow.

i just upgrade your latest github node-red-contrib-ffmpeg-spawn. and paste restart args for SD and FHD streamming ,


i can't let ARgs field blanc in the node . What do i put in ?

If I try your default arguments

["-loglevel","error","-nostats","-f","hls","-http_multiple","1","-re","-i","https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on","-c:v","copy","-c:a","aac","-f","mp4","-movflags","+frag_keyframe+empty_moov+default_base_moof","pipe:1","-progress","pipe:3","-f","image2pipe","-vf","select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2","-vsync","vfr","pipe:4"]

it doesn't work for me, I get this error in debug

payload: "https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on: Protocol not found↵Did you mean file:https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on?↵"

_msgid: "54ccd765.e38008"

If I try a local file with these arguments it works perfect

["-re", "-i", "/home/pi/Qvideos/TheDriver-1.ts", "-bsf:a", "aac_adtstoasc", "-c:v", "copy", "-f", "mp4", "-movflags", "+frag_keyframe+empty_moov+default_base_moof", "pipe:1", "-progress","pipe:3","-f","image2pipe","-vf","select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2","-vsync","vfr","pipe:4"]

I think everything installed fine, do I maybe miss some part here

Hi Walter, try this , it's work for me :

[
    "-loglevel",
    "error",
    "-nostats",
    "-f",
    "hls",
    "-http_multiple",
    "1",
    "-re",
    "-i",
    "http://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/master_1660.m3u8",
    "-c:v",
    "copy",
    "-c:a",
    "aac",
    "-f",
    "mp4",
    "-movflags",
    "+frag_keyframe+empty_moov+default_base_moof",
    "pipe:1",
    "-progress",
    "pipe:3",
    "-f",
    "image2pipe",
    "-vf",
    "select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2",
    "-vsync",
    "vfr",
    "pipe:4"
]

The weather Args you posted, works for me :thinking:

Yes, it must be something with my setup/install that is not correct. I get the following error message when I try yours. Thanks for providing the sample!

Error when loading first segment 'https://rbmn-live.akamaized.net/hls/live/590964/BoRB-AT/20210204T200259/master_1660/00362/master_1660_02800.ts'

When something works for one user and not the other, this could be an issue depending on the ffmpeg build and version. I know i have run into the issue in the past. In the original flow example, i tried to be as generic as possible to make a sample that should work for anybody. i guess not.

Also, I had considered including ffmpeg binary with this node and originally was using ffmpeg-static library. It worked, but NOT well. While ffmpeg was compatible with the pi, it was not specifically built for the pi, and therefore had none of the special features such as hardware acceleration decoding, etc. i decided to remove the lib before releasing this for testing to not cause extra trouble. You can always try other ffmpeg libs from npm. After install, just figure out its path in your folders and give that cmdPath in the settings window.

Right now, it needs to see an array. Just put an empty array [] to satisfy its complaint. I can fix that later to either be empty or an array.

As of now, outputs = cmdOutputs + 1, and as far as I know, can only be done in the editor. If some people can use the feature to pipe everything to 1 output with an attached topic, seems like that would not be too difficult to do. Instead of targeting the wires array position, I would just attach topic: ['status', 'stdout', 'stderr', 'stdio3', 'stdio4', 'stdio5'][i]. Hmm, after writing this topics array, I realize that it could be set and verified to be an array of strings. Are there any nodes that currently have the options to make a unified output like this? Other than redirecting the ouput, what else can be done with topic? I have seen this mentioned in the past and have never needed a topic. Of course, I am new to nodered and have not fully utilized all of its features.

image
image
This is the "empty spawn option" with []
BUT doesn't working :


Error logs

Is it useful to display the installed ffmpeg version number on your config screen, and a warning if ffmpeg not (or not correctly) installed. A collegue of mine recently reported to me that he could not get your mp4frag node running. And the end it seemed that he didn't know that he had to install ffmpeg. Showing the version on the config screen would have alarmed his brain...

Yes I also "think" you can only change it via the UI. But I should e.g. put the following info on the readme page: "setting the args dynamically via the input meassage is only accepted if the checkbox '...' is activated". That way you know that - when args arrive via an input message - that you can send everything to the one and only output. So set ´node.outputs = 1´ when the checkbox is activated via the config screen.

Can you explain that a bit more? When the checkbox is activated, you send all your messages to that single output (after you have set e.g. msg.topic="stdout"). You could also use another msg field, but the topic field is widely used. Then it becomes e.g. possible to add a Switch-node to process your output messages, and do topic-based routing. See also here.

Right, I think that is my problem. I did build it earlier with GPU support but I do not by far have as many configuration options as @SuperNinja seems to have in his screen shot. Mine is like this, maybe not enough any longer

ffmpeg version N-99578-gaf701196ec Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 8 (Raspbian 8.3.0-6+rpi1)
  configuration: --extra-ldflags=-latomic --arch=armel --target-os=linux --enable-gpl --enable-omx --enable-omx-rpi --enable-libx264 --enable-nonfree
  libavutil      56. 60.100 / 56. 60.100
  libavcodec     58.111.101 / 58.111.101
  libavformat    58. 62.100 / 58. 62.100
  libavdevice    58. 11.102 / 58. 11.102
  libavfilter     7. 87.100 /  7. 87.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Yes, also it would be useful if we could define a command that builds and installs ffmpeg with the necessary options, at least for a RPi I think. I'm myself a bit lost here, there are so many different advices found everywhere. What to select? My target platform is just a RPi3 where I successfully managed to use the GPU after I earlier built ffmpeg from source

Currently I'm looking at a command like below. But is it enough? Will it rebuild ffmpeg also with GPU support?

git clone --depth 1 https://github.com/FFmpeg/FFmpeg.git ~/FFmpeg \
  && cd ~/FFmpeg \
  && ./configure \
    --extra-cflags="-I/usr/local/include" \
    --extra-ldflags="-L/usr/local/lib" \
    --extra-libs="-lpthread -lm -latomic" \
    --arch=armel \
    --enable-gmp \
    --enable-gpl \
    --enable-libaom \
    --enable-libass \
    --enable-libdav1d \
    --enable-libdrm \
    --enable-libfdk-aac \
    --enable-libfreetype \
    --enable-libkvazaar \
    --enable-libmp3lame \
    --enable-libopencore-amrnb \
    --enable-libopencore-amrwb \
    --enable-libopus \
    --enable-librtmp \
    --enable-libsnappy \
    --enable-libsoxr \
    --enable-libssh \
    --enable-libvorbis \
    --enable-libvpx \
    --enable-libzimg \
    --enable-libwebp \
    --enable-libx264 \
    --enable-libx265 \
    --enable-libxml2 \
    --enable-mmal \
    --enable-nonfree \
    --enable-omx \
    --enable-omx-rpi \
    --enable-version3 \
    --target-os=linux \
    --enable-pthreads \
    --enable-openssl \
    --enable-hardcoded-tables \
  && make -j1 \
  && sudo make install