noobs 0.0.84 → 0.0.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/dist/bin/obs-nvenc-test.exe +0 -0
- package/dist/bin/obs-qsv-test.exe +0 -0
- package/dist/data/obs-plugins/image-source/locale/af-ZA.ini +29 -0
- package/dist/data/obs-plugins/image-source/locale/ar-SA.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/az-AZ.ini +29 -0
- package/dist/data/obs-plugins/image-source/locale/ba-RU.ini +9 -0
- package/dist/data/obs-plugins/image-source/locale/be-BY.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/bg-BG.ini +22 -0
- package/dist/data/obs-plugins/image-source/locale/bn-BD.ini +32 -0
- package/dist/data/obs-plugins/image-source/locale/ca-ES.ini +37 -0
- package/dist/data/obs-plugins/image-source/locale/cs-CZ.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/da-DK.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/de-DE.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/el-GR.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/en-GB.ini +4 -0
- package/dist/data/obs-plugins/image-source/locale/en-US.ini +40 -0
- package/dist/data/obs-plugins/image-source/locale/es-ES.ini +37 -0
- package/dist/data/obs-plugins/image-source/locale/et-EE.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/eu-ES.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/fa-IR.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/fi-FI.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/fil-PH.ini +33 -0
- package/dist/data/obs-plugins/image-source/locale/fr-FR.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/gd-GB.ini +32 -0
- package/dist/data/obs-plugins/image-source/locale/gl-ES.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/he-IL.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/hi-IN.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/hr-HR.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/hu-HU.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/hy-AM.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/id-ID.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/it-IT.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/ja-JP.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/ka-GE.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/kaa.ini +21 -0
- package/dist/data/obs-plugins/image-source/locale/kab-KAB.ini +31 -0
- package/dist/data/obs-plugins/image-source/locale/kmr-TR.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/ko-KR.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/lo-LA.ini +2 -0
- package/dist/data/obs-plugins/image-source/locale/lt-LT.ini +32 -0
- package/dist/data/obs-plugins/image-source/locale/mn-MN.ini +19 -0
- package/dist/data/obs-plugins/image-source/locale/ms-MY.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/nb-NO.ini +35 -0
- package/dist/data/obs-plugins/image-source/locale/nl-NL.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/nn-NO.ini +6 -0
- package/dist/data/obs-plugins/image-source/locale/oc-FR.ini +2 -0
- package/dist/data/obs-plugins/image-source/locale/pa-IN.ini +1 -0
- package/dist/data/obs-plugins/image-source/locale/pl-PL.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/pt-BR.ini +36 -0
- package/dist/data/obs-plugins/image-source/locale/pt-PT.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/ro-RO.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/ru-RU.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/si-LK.ini +16 -0
- package/dist/data/obs-plugins/image-source/locale/sk-SK.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/sl-SI.ini +34 -0
- package/dist/data/obs-plugins/image-source/locale/sq-AL.ini +1 -0
- package/dist/data/obs-plugins/image-source/locale/sr-CS.ini +31 -0
- package/dist/data/obs-plugins/image-source/locale/sr-SP.ini +31 -0
- package/dist/data/obs-plugins/image-source/locale/sv-SE.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/ta-IN.ini +15 -0
- package/dist/data/obs-plugins/image-source/locale/th-TH.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/tl-PH.ini +31 -0
- package/dist/data/obs-plugins/image-source/locale/tr-TR.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/tt-RU.ini +13 -0
- package/dist/data/obs-plugins/image-source/locale/ug-CN.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/uk-UA.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/ur-PK.ini +1 -0
- package/dist/data/obs-plugins/image-source/locale/vi-VN.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/zh-CN.ini +38 -0
- package/dist/data/obs-plugins/image-source/locale/zh-TW.ini +38 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/af-ZA.ini +73 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ar-SA.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ba-RU.ini +12 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/be-BY.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/bg-BG.ini +67 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/bn-BD.ini +48 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ca-ES.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/cs-CZ.ini +98 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/da-DK.ini +83 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/de-DE.ini +97 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/el-GR.ini +85 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/en-GB.ini +10 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/en-US.ini +127 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/es-ES.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/et-EE.ini +73 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/eu-ES.ini +89 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/fa-IR.ini +102 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/fi-FI.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/fil-PH.ini +77 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/fr-FR.ini +94 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/gd-GB.ini +48 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/gl-ES.ini +97 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/he-IL.ini +100 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/hi-IN.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/hr-HR.ini +51 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/hu-HU.ini +100 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/hy-AM.ini +95 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/id-ID.ini +88 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/is-IS.ini +2 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/it-IT.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ja-JP.ini +88 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ka-GE.ini +102 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/kaa.ini +42 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/kab-KAB.ini +34 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/kmr-TR.ini +89 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ko-KR.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ms-MY.ini +93 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/nb-NO.ini +71 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/nl-NL.ini +85 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/nn-NO.ini +21 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/oc-FR.ini +1 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/pl-PL.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/pt-BR.ini +95 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/pt-PT.ini +97 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ro-RO.ini +92 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ru-RU.ini +102 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/si-LK.ini +53 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/sk-SK.ini +86 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/sl-SI.ini +99 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/sr-CS.ini +34 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/sr-SP.ini +52 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/sv-SE.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/szl-PL.ini +23 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ta-IN.ini +20 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/th-TH.ini +98 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/tl-PH.ini +26 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/tr-TR.ini +98 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/tt-RU.ini +32 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ug-CN.ini +96 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/uk-UA.ini +98 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/ur-PK.ini +1 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/vi-VN.ini +91 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/zh-CN.ini +101 -0
- package/dist/data/obs-plugins/obs-ffmpeg/locale/zh-TW.ini +98 -0
- package/dist/data/obs-plugins/obs-x264/locale/af-ZA.ini +8 -0
- package/dist/data/obs-plugins/obs-x264/locale/ar-SA.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/az-AZ.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/ba-RU.ini +4 -0
- package/dist/data/obs-plugins/obs-x264/locale/be-BY.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/bg-BG.ini +7 -0
- package/dist/data/obs-plugins/obs-x264/locale/bn-BD.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/ca-ES.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/cs-CZ.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/da-DK.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/de-DE.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/el-GR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/en-GB.ini +1 -0
- package/dist/data/obs-plugins/obs-x264/locale/en-US.ini +14 -0
- package/dist/data/obs-plugins/obs-x264/locale/es-ES.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/et-EE.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/eu-ES.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/fa-IR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/fi-FI.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/fil-PH.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/fr-FR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/gd-GB.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/gl-ES.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/he-IL.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/hi-IN.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/hr-HR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/hu-HU.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/hy-AM.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/id-ID.ini +11 -0
- package/dist/data/obs-plugins/obs-x264/locale/it-IT.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/ja-JP.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/ka-GE.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/kaa.ini +5 -0
- package/dist/data/obs-plugins/obs-x264/locale/kab-KAB.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/kmr-TR.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/ko-KR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/lv-LV.ini +4 -0
- package/dist/data/obs-plugins/obs-x264/locale/mn-MN.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/ms-MY.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/nb-NO.ini +9 -0
- package/dist/data/obs-plugins/obs-x264/locale/nl-NL.ini +11 -0
- package/dist/data/obs-plugins/obs-x264/locale/nn-NO.ini +1 -0
- package/dist/data/obs-plugins/obs-x264/locale/oc-FR.ini +1 -0
- package/dist/data/obs-plugins/obs-x264/locale/pl-PL.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/pt-BR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/pt-PT.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/ro-RO.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/ru-RU.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/si-LK.ini +8 -0
- package/dist/data/obs-plugins/obs-x264/locale/sk-SK.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/sl-SI.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/sq-AL.ini +3 -0
- package/dist/data/obs-plugins/obs-x264/locale/sr-CS.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/sr-SP.ini +10 -0
- package/dist/data/obs-plugins/obs-x264/locale/sv-SE.ini +12 -0
- package/dist/data/obs-plugins/obs-x264/locale/szl-PL.ini +9 -0
- package/dist/data/obs-plugins/obs-x264/locale/ta-IN.ini +4 -0
- package/dist/data/obs-plugins/obs-x264/locale/th-TH.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/tl-PH.ini +9 -0
- package/dist/data/obs-plugins/obs-x264/locale/tr-TR.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/tt-RU.ini +4 -0
- package/dist/data/obs-plugins/obs-x264/locale/ug-CN.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/uk-UA.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/ur-PK.ini +1 -0
- package/dist/data/obs-plugins/obs-x264/locale/vi-VN.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/zh-CN.ini +13 -0
- package/dist/data/obs-plugins/obs-x264/locale/zh-TW.ini +13 -0
- package/dist/data/obs-plugins/win-capture/compatibility.json +664 -0
- package/dist/data/obs-plugins/win-capture/get-graphics-offsets32.exe +0 -0
- package/dist/data/obs-plugins/win-capture/get-graphics-offsets64.exe +0 -0
- package/dist/data/obs-plugins/win-capture/graphics-hook32.dll +0 -0
- package/dist/data/obs-plugins/win-capture/graphics-hook64.dll +0 -0
- package/dist/data/obs-plugins/win-capture/inject-helper32.exe +0 -0
- package/dist/data/obs-plugins/win-capture/inject-helper64.exe +0 -0
- package/dist/data/obs-plugins/win-capture/locale/af-ZA.ini +30 -0
- package/dist/data/obs-plugins/win-capture/locale/ar-SA.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/az-AZ.ini +13 -0
- package/dist/data/obs-plugins/win-capture/locale/ba-RU.ini +2 -0
- package/dist/data/obs-plugins/win-capture/locale/be-BY.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/bg-BG.ini +33 -0
- package/dist/data/obs-plugins/win-capture/locale/bn-BD.ini +36 -0
- package/dist/data/obs-plugins/win-capture/locale/ca-ES.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/cs-CZ.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/da-DK.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/de-DE.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/el-GR.ini +48 -0
- package/dist/data/obs-plugins/win-capture/locale/en-GB.ini +3 -0
- package/dist/data/obs-plugins/win-capture/locale/en-US.ini +60 -0
- package/dist/data/obs-plugins/win-capture/locale/es-ES.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/et-EE.ini +44 -0
- package/dist/data/obs-plugins/win-capture/locale/eu-ES.ini +38 -0
- package/dist/data/obs-plugins/win-capture/locale/fa-IR.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/fi-FI.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/fil-PH.ini +36 -0
- package/dist/data/obs-plugins/win-capture/locale/fr-FR.ini +52 -0
- package/dist/data/obs-plugins/win-capture/locale/gd-GB.ini +36 -0
- package/dist/data/obs-plugins/win-capture/locale/gl-ES.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/he-IL.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/hi-IN.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/hr-HR.ini +40 -0
- package/dist/data/obs-plugins/win-capture/locale/hu-HU.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/hy-AM.ini +42 -0
- package/dist/data/obs-plugins/win-capture/locale/id-ID.ini +52 -0
- package/dist/data/obs-plugins/win-capture/locale/is-IS.ini +2 -0
- package/dist/data/obs-plugins/win-capture/locale/it-IT.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/ja-JP.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/ka-GE.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/kaa.ini +19 -0
- package/dist/data/obs-plugins/win-capture/locale/kab-KAB.ini +27 -0
- package/dist/data/obs-plugins/win-capture/locale/kmr-TR.ini +42 -0
- package/dist/data/obs-plugins/win-capture/locale/ko-KR.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/lo-LA.ini +6 -0
- package/dist/data/obs-plugins/win-capture/locale/lt-LT.ini +36 -0
- package/dist/data/obs-plugins/win-capture/locale/mn-MN.ini +21 -0
- package/dist/data/obs-plugins/win-capture/locale/ms-MY.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/nb-NO.ini +39 -0
- package/dist/data/obs-plugins/win-capture/locale/nl-NL.ini +50 -0
- package/dist/data/obs-plugins/win-capture/locale/nn-NO.ini +4 -0
- package/dist/data/obs-plugins/win-capture/locale/pl-PL.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/pt-BR.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/pt-PT.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/ro-RO.ini +41 -0
- package/dist/data/obs-plugins/win-capture/locale/ru-RU.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/si-LK.ini +24 -0
- package/dist/data/obs-plugins/win-capture/locale/sk-SK.ini +53 -0
- package/dist/data/obs-plugins/win-capture/locale/sl-SI.ini +52 -0
- package/dist/data/obs-plugins/win-capture/locale/sq-AL.ini +16 -0
- package/dist/data/obs-plugins/win-capture/locale/sr-CS.ini +28 -0
- package/dist/data/obs-plugins/win-capture/locale/sr-SP.ini +38 -0
- package/dist/data/obs-plugins/win-capture/locale/sv-SE.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/ta-IN.ini +17 -0
- package/dist/data/obs-plugins/win-capture/locale/th-TH.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/tl-PH.ini +23 -0
- package/dist/data/obs-plugins/win-capture/locale/tr-TR.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/tt-RU.ini +14 -0
- package/dist/data/obs-plugins/win-capture/locale/ug-CN.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/uk-UA.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/vi-VN.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/zh-CN.ini +54 -0
- package/dist/data/obs-plugins/win-capture/locale/zh-TW.ini +54 -0
- package/dist/data/obs-plugins/win-capture/obs-vulkan32.json +17 -0
- package/dist/data/obs-plugins/win-capture/obs-vulkan64.json +17 -0
- package/dist/data/obs-plugins/win-capture/package.json +11 -0
- package/dist/data/obs-plugins/win-capture/schema/compatibility-schema-v1.json +99 -0
- package/dist/data/obs-plugins/win-capture/schema/package-schema.json +47 -0
- package/dist/data/obs-plugins/win-wasapi/locale/af-ZA.ini +8 -0
- package/dist/data/obs-plugins/win-wasapi/locale/an-ES.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ar-SA.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ba-RU.ini +2 -0
- package/dist/data/obs-plugins/win-wasapi/locale/be-BY.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/bg-BG.ini +3 -0
- package/dist/data/obs-plugins/win-wasapi/locale/bn-BD.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ca-ES.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/cs-CZ.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/da-DK.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/de-DE.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/el-GR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/en-GB.ini +1 -0
- package/dist/data/obs-plugins/win-wasapi/locale/en-US.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/es-ES.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/et-EE.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/eu-ES.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/fa-IR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/fi-FI.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/fil-PH.ini +9 -0
- package/dist/data/obs-plugins/win-wasapi/locale/fr-FR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/gd-GB.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/gl-ES.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/he-IL.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/hi-IN.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/hr-HR.ini +6 -0
- package/dist/data/obs-plugins/win-wasapi/locale/hu-HU.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/hy-AM.ini +10 -0
- package/dist/data/obs-plugins/win-wasapi/locale/id-ID.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/is-IS.ini +1 -0
- package/dist/data/obs-plugins/win-wasapi/locale/it-IT.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ja-JP.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ka-GE.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/kaa.ini +3 -0
- package/dist/data/obs-plugins/win-wasapi/locale/kab-KAB.ini +4 -0
- package/dist/data/obs-plugins/win-wasapi/locale/kmr-TR.ini +10 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ko-KR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/lt-LT.ini +2 -0
- package/dist/data/obs-plugins/win-wasapi/locale/mn-MN.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ms-MY.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/nb-NO.ini +7 -0
- package/dist/data/obs-plugins/win-wasapi/locale/nl-NL.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/nn-NO.ini +2 -0
- package/dist/data/obs-plugins/win-wasapi/locale/pl-PL.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/pt-BR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/pt-PT.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ro-RO.ini +10 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ru-RU.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/si-LK.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sk-SK.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sl-SI.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sq-AL.ini +1 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sr-CS.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sr-SP.ini +10 -0
- package/dist/data/obs-plugins/win-wasapi/locale/sv-SE.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/szl-PL.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ta-IN.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/th-TH.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/tl-PH.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/tr-TR.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/tt-RU.ini +5 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ug-CN.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/uk-UA.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/ur-PK.ini +1 -0
- package/dist/data/obs-plugins/win-wasapi/locale/vi-VN.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/zh-CN.ini +11 -0
- package/dist/data/obs-plugins/win-wasapi/locale/zh-TW.ini +11 -0
- package/dist/noobs.node +0 -0
- package/dist/{plugins → obs-plugins}/win-capture.dll +0 -0
- package/index.d.ts +27 -8
- package/package.json +3 -2
- package/src/main.cpp +250 -20
- package/src/obs_interface.cpp +469 -213
- package/src/obs_interface.h +83 -33
- /package/dist/{effects → data/effects}/area.effect +0 -0
- /package/dist/{effects → data/effects}/bicubic_scale.effect +0 -0
- /package/dist/{effects → data/effects}/bilinear_lowres_scale.effect +0 -0
- /package/dist/{effects → data/effects}/color.effect +0 -0
- /package/dist/{effects → data/effects}/default.effect +0 -0
- /package/dist/{effects → data/effects}/default_rect.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_base.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_blend.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_blend_2x.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_discard.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_discard_2x.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_linear.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_linear_2x.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_yadif.effect +0 -0
- /package/dist/{effects → data/effects}/deinterlace_yadif_2x.effect +0 -0
- /package/dist/{effects → data/effects}/format_conversion.effect +0 -0
- /package/dist/{effects → data/effects}/lanczos_scale.effect +0 -0
- /package/dist/{effects → data/effects}/opaque.effect +0 -0
- /package/dist/{effects → data/effects}/premultiplied_alpha.effect +0 -0
- /package/dist/{effects → data/effects}/repeat.effect +0 -0
- /package/dist/{effects → data/effects}/solid.effect +0 -0
- /package/dist/{plugins → obs-plugins}/image-source.dll +0 -0
- /package/dist/{plugins → obs-plugins}/obs-ffmpeg.dll +0 -0
- /package/dist/{plugins → obs-plugins}/obs-x264.dll +0 -0
- /package/dist/{plugins → obs-plugins}/win-wasapi.dll +0 -0
package/src/obs_interface.cpp
CHANGED
|
@@ -1,58 +1,41 @@
|
|
|
1
|
-
#include <iostream>
|
|
2
1
|
#include <windows.h>
|
|
3
2
|
#include <obs.h>
|
|
4
3
|
#include "utils.h"
|
|
5
|
-
#include <chrono>
|
|
6
4
|
#include "obs_interface.h"
|
|
7
5
|
#include <vector>
|
|
8
|
-
#include <thread>
|
|
9
|
-
#include <iostream>
|
|
10
|
-
#include <map>
|
|
11
6
|
#include <string>
|
|
12
7
|
#include <graphics/matrix4.h>
|
|
13
8
|
#include <graphics/vec4.h>
|
|
14
9
|
#include <util/platform.h>
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
while (obs_enum_encoder_types(idx++, &encoder_type)) {
|
|
23
|
-
bool video = obs_get_encoder_type(encoder_type) == OBS_ENCODER_VIDEO;
|
|
11
|
+
void call_jscb(Napi::Env env, Napi::Function cb, SignalData* sd) {
|
|
12
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
13
|
+
obj.Set("type", Napi::String::New(env, sd->type));
|
|
14
|
+
obj.Set("id", Napi::String::New(env, sd->id));
|
|
15
|
+
obj.Set("code", Napi::Number::New(env, sd->code));
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
if (sd->value.has_value()) {
|
|
18
|
+
obj.Set("value", Napi::Number::New(env, sd->value.value()));
|
|
27
19
|
}
|
|
28
20
|
|
|
29
|
-
|
|
21
|
+
cb.Call({ obj });
|
|
22
|
+
delete sd;
|
|
30
23
|
}
|
|
31
24
|
|
|
32
25
|
void ObsInterface::list_encoders(obs_encoder_type type)
|
|
33
26
|
{
|
|
34
|
-
blog(LOG_INFO, "
|
|
35
|
-
blog(LOG_INFO, "List encoders of type: %d", type);
|
|
36
|
-
|
|
27
|
+
blog(LOG_INFO, "Encoders:");
|
|
37
28
|
size_t idx = 0;
|
|
38
29
|
const char *encoder_type;
|
|
39
30
|
|
|
40
31
|
while (obs_enum_encoder_types(idx++, &encoder_type)) {
|
|
41
|
-
if (obs_get_encoder_type(encoder_type) != type) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// if (obs_get_encoder_caps(encoder_type) & hide_flags) {
|
|
46
|
-
// continue;
|
|
47
|
-
// }
|
|
48
|
-
|
|
49
32
|
blog(LOG_INFO, "\t- %s (%s)", encoder_type, obs_encoder_get_display_name(encoder_type));
|
|
50
33
|
}
|
|
51
34
|
};
|
|
52
35
|
|
|
53
36
|
void ObsInterface::list_source_types()
|
|
54
37
|
{
|
|
55
|
-
blog(LOG_INFO, "
|
|
38
|
+
blog(LOG_INFO, "Sources:");
|
|
56
39
|
size_t idx = 0;
|
|
57
40
|
const char *src = nullptr;
|
|
58
41
|
|
|
@@ -61,20 +44,9 @@ void ObsInterface::list_source_types()
|
|
|
61
44
|
}
|
|
62
45
|
}
|
|
63
46
|
|
|
64
|
-
void ObsInterface::list_input_types()
|
|
65
|
-
{
|
|
66
|
-
blog(LOG_INFO, "List input types");
|
|
67
|
-
size_t idx = 0;
|
|
68
|
-
const char *src = nullptr;
|
|
69
|
-
|
|
70
|
-
while (obs_enum_input_types(idx++, &src)) {
|
|
71
|
-
blog(LOG_INFO, "\t- %s", src);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
47
|
void ObsInterface::list_output_types()
|
|
76
48
|
{
|
|
77
|
-
blog(LOG_INFO, "
|
|
49
|
+
blog(LOG_INFO, "Outputs:");
|
|
78
50
|
size_t idx = 0;
|
|
79
51
|
const char *src = nullptr;
|
|
80
52
|
|
|
@@ -83,11 +55,12 @@ void ObsInterface::list_output_types()
|
|
|
83
55
|
}
|
|
84
56
|
}
|
|
85
57
|
|
|
86
|
-
void ObsInterface::load_module(const char* module) {
|
|
58
|
+
void ObsInterface::load_module(const char* module, const char* data) {
|
|
87
59
|
blog(LOG_INFO, "Loading module: %s", module);
|
|
60
|
+
blog(LOG_INFO, "Data path: %s", data);
|
|
88
61
|
|
|
89
62
|
obs_module_t *ptr = NULL;
|
|
90
|
-
int success = obs_open_module(&ptr, module,
|
|
63
|
+
int success = obs_open_module(&ptr, module, data);
|
|
91
64
|
|
|
92
65
|
if (success != MODULE_SUCCESS) {
|
|
93
66
|
blog(LOG_ERROR, "Failed to open module: %s", module);
|
|
@@ -102,16 +75,50 @@ void ObsInterface::load_module(const char* module) {
|
|
|
102
75
|
}
|
|
103
76
|
}
|
|
104
77
|
|
|
105
|
-
void ObsInterface::
|
|
106
|
-
blog(LOG_INFO, "
|
|
78
|
+
void ObsInterface::setVideoContext(int fps, int width, int height) {
|
|
79
|
+
blog(LOG_INFO, "Reset video context");
|
|
107
80
|
|
|
81
|
+
blog(LOG_INFO, "FPS: %d", fps);
|
|
82
|
+
blog(LOG_INFO, "Width: %d", width);
|
|
83
|
+
blog(LOG_INFO, "Height: %d", height);
|
|
84
|
+
|
|
85
|
+
if (fps <= 10) {
|
|
86
|
+
blog(LOG_WARNING, "Invalid FPS provided for reset, using default 10");
|
|
87
|
+
fps = 60;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (width <= 32 || height <= 32) {
|
|
91
|
+
blog(LOG_WARNING, "Invalid width or height provided for reset, using default 1920x1080");
|
|
92
|
+
width = 1920;
|
|
93
|
+
height = 1080;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
int ret = reset_video(fps, width, height);
|
|
97
|
+
|
|
98
|
+
if (ret == OBS_VIDEO_CURRENTLY_ACTIVE) {
|
|
99
|
+
blog(LOG_WARNING, "Can't reset video as currently active");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (ret != OBS_VIDEO_SUCCESS) {
|
|
104
|
+
blog(LOG_ERROR, "Failed to reset video context: %d", ret);
|
|
105
|
+
throw std::runtime_error("Failed to reset video context");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Recreate the encoders as they are tied to the video context.
|
|
109
|
+
create_video_encoders();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
int ObsInterface::reset_video(int fps, int width, int height) {
|
|
114
|
+
blog(LOG_INFO, "Reset video");
|
|
108
115
|
obs_video_info ovi = {};
|
|
109
116
|
|
|
110
|
-
ovi.base_width =
|
|
111
|
-
ovi.base_height =
|
|
112
|
-
ovi.output_width =
|
|
113
|
-
ovi.output_height =
|
|
114
|
-
ovi.fps_num =
|
|
117
|
+
ovi.base_width = width;
|
|
118
|
+
ovi.base_height = height;
|
|
119
|
+
ovi.output_width = width;
|
|
120
|
+
ovi.output_height = height;
|
|
121
|
+
ovi.fps_num = fps;
|
|
115
122
|
ovi.fps_den = 1;
|
|
116
123
|
|
|
117
124
|
ovi.output_format = VIDEO_FORMAT_NV12;
|
|
@@ -122,32 +129,17 @@ void ObsInterface::reset_video() {
|
|
|
122
129
|
ovi.gpu_conversion = true;
|
|
123
130
|
ovi.graphics_module = "libobs-d3d11.dll";
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
obs_enter_graphics();
|
|
128
|
-
int dt = gs_get_device_type();
|
|
129
|
-
blog(LOG_INFO, "Device type = %d", dt); // should be 1 for D3D11
|
|
130
|
-
obs_leave_graphics();
|
|
131
|
-
|
|
132
|
-
if (success != OBS_VIDEO_SUCCESS) {
|
|
133
|
-
blog(LOG_ERROR, "Failed to reset video!");
|
|
134
|
-
throw std::runtime_error("Failed to reset video!");
|
|
135
|
-
}
|
|
132
|
+
return obs_reset_video(&ovi);
|
|
136
133
|
}
|
|
137
134
|
|
|
138
|
-
|
|
135
|
+
bool ObsInterface::reset_audio() {
|
|
139
136
|
struct obs_audio_info oai = {0};
|
|
140
137
|
oai.samples_per_sec = 48000;
|
|
141
138
|
oai.speakers = SPEAKERS_STEREO;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (!reset) {
|
|
145
|
-
blog(LOG_ERROR, "Failed to reset audio!");
|
|
146
|
-
throw std::runtime_error("Failed to reset audio!");
|
|
147
|
-
}
|
|
139
|
+
return obs_reset_audio(&oai);
|
|
148
140
|
}
|
|
149
141
|
|
|
150
|
-
void ObsInterface::init_obs(const std::string&
|
|
142
|
+
void ObsInterface::init_obs(const std::string& distPath) {
|
|
151
143
|
blog(LOG_INFO, "Enter init_obs");
|
|
152
144
|
auto success = obs_startup("en-US", NULL, NULL);
|
|
153
145
|
|
|
@@ -161,40 +153,59 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
|
|
|
161
153
|
throw std::runtime_error("OBS initialization failed");
|
|
162
154
|
}
|
|
163
155
|
|
|
164
|
-
std::string
|
|
156
|
+
std::string basePath = distPath;
|
|
165
157
|
|
|
166
|
-
if (
|
|
167
|
-
// Add a trailing slash if not present
|
|
168
|
-
|
|
158
|
+
if (basePath.back() != '/' && basePath.back() != '\\') {
|
|
159
|
+
// Add a trailing slash if not present.
|
|
160
|
+
basePath += '/';
|
|
169
161
|
}
|
|
170
162
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
163
|
+
std::string effectsPath = basePath + "data/effects/";
|
|
164
|
+
std::string pluginPath = basePath + "obs-plugins/";
|
|
165
|
+
std::string pluginDataPath = basePath + "data/obs-plugins/";
|
|
166
|
+
|
|
167
|
+
blog(LOG_INFO, "Base path: %s", basePath.c_str());
|
|
168
|
+
blog(LOG_INFO, "Effects path: %s", effectsPath.c_str());
|
|
169
|
+
blog(LOG_INFO, "Plugin path: %s", pluginPath.c_str());
|
|
170
|
+
blog(LOG_INFO, "Data path: %s", pluginDataPath.c_str());
|
|
171
|
+
|
|
172
|
+
// Add the effects path. We need this before resetting video and audio
|
|
173
|
+
// to ensure the effects are available. The function is deprecated in
|
|
174
|
+
// libobs but it works for now.
|
|
175
|
+
obs_add_data_path(effectsPath.c_str());
|
|
175
176
|
|
|
176
177
|
// This must come before loading modules to initialize D3D11.
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
// Choose some sensible defaults that can be reconfigured.
|
|
179
|
+
int rc = reset_video(60, 1920, 1080);
|
|
180
|
+
|
|
181
|
+
if (rc != OBS_VIDEO_SUCCESS) {
|
|
182
|
+
blog(LOG_ERROR, "Failed to reset video!");
|
|
183
|
+
throw std::runtime_error("Failed to reset video!");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!reset_audio()) {
|
|
187
|
+
blog(LOG_ERROR, "Failed to reset audio!");
|
|
188
|
+
throw std::runtime_error("Failed to reset audio!");
|
|
189
|
+
}
|
|
179
190
|
|
|
180
191
|
std::vector<std::string> modules = {
|
|
181
|
-
"obs-x264
|
|
182
|
-
"obs-ffmpeg
|
|
183
|
-
"win-capture
|
|
184
|
-
"image-source
|
|
185
|
-
"win-wasapi
|
|
192
|
+
"obs-x264",
|
|
193
|
+
"obs-ffmpeg",
|
|
194
|
+
"win-capture", // Required for basically all forms of capture on Windows.
|
|
195
|
+
"image-source", // Required for image sources.
|
|
196
|
+
"win-wasapi" // Required for WASAPI audio input.
|
|
186
197
|
};
|
|
187
198
|
|
|
188
199
|
for (const auto& module : modules) {
|
|
189
|
-
std::string
|
|
190
|
-
|
|
200
|
+
std::string modulePath = pluginPath + module + ".dll";
|
|
201
|
+
std::string moduleDataPath = pluginDataPath + module;
|
|
202
|
+
load_module(modulePath.c_str(), moduleDataPath.c_str());
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
obs_post_load_modules();
|
|
194
206
|
|
|
195
207
|
list_encoders();
|
|
196
208
|
list_source_types();
|
|
197
|
-
list_input_types();
|
|
198
209
|
list_output_types();
|
|
199
210
|
|
|
200
211
|
blog(LOG_INFO, "Exit init_obs");
|
|
@@ -231,10 +242,10 @@ void ObsInterface::create_output() {
|
|
|
231
242
|
|
|
232
243
|
blog(LOG_INFO, "Set ffmpeg_muxer settings");
|
|
233
244
|
obs_data_t *ffmpeg_settings = obs_data_create();
|
|
234
|
-
// Need to specify the exact path for ffmpeg_muxer.
|
|
245
|
+
// Need to specify the exact path for ffmpeg_muxer. We will write this again at start recording.
|
|
235
246
|
std::string filename = recording_path + "\\" + get_current_date_time() + ".mp4";
|
|
236
247
|
obs_data_set_string(ffmpeg_settings, "path", filename.c_str());
|
|
237
|
-
|
|
248
|
+
unbuffered_output_filename = filename;
|
|
238
249
|
|
|
239
250
|
// Apply and release the settings.
|
|
240
251
|
obs_output_update(file_output, ffmpeg_settings);
|
|
@@ -275,38 +286,48 @@ void ObsInterface::setRecordingDir(const std::string& recordingPath) {
|
|
|
275
286
|
}
|
|
276
287
|
|
|
277
288
|
void ObsInterface::create_video_encoders() {
|
|
278
|
-
blog(LOG_INFO, "
|
|
289
|
+
blog(LOG_INFO, "Set video encoder: %s", video_encoder_id.c_str());
|
|
279
290
|
|
|
280
|
-
|
|
291
|
+
if (file_video_encoder) {
|
|
292
|
+
blog(LOG_DEBUG, "Releasing file video encoder");
|
|
293
|
+
obs_encoder_release(file_video_encoder);
|
|
294
|
+
file_video_encoder = nullptr;
|
|
295
|
+
}
|
|
281
296
|
|
|
297
|
+
file_video_encoder = obs_video_encoder_create(
|
|
298
|
+
video_encoder_id.c_str(),
|
|
299
|
+
"noobs_file_encoder",
|
|
300
|
+
video_encoder_settings,
|
|
301
|
+
NULL
|
|
302
|
+
);
|
|
282
303
|
|
|
283
304
|
if (!file_video_encoder) {
|
|
284
305
|
blog(LOG_ERROR, "Failed to create video encoder!");
|
|
285
306
|
throw std::runtime_error("Failed to create video encoder!");
|
|
286
307
|
}
|
|
287
308
|
|
|
288
|
-
|
|
309
|
+
if (buffer_video_encoder) {
|
|
310
|
+
blog(LOG_DEBUG, "Releasing buffer video encoder");
|
|
311
|
+
obs_encoder_release(buffer_video_encoder);
|
|
312
|
+
buffer_video_encoder = nullptr;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
buffer_video_encoder = obs_video_encoder_create(
|
|
316
|
+
video_encoder_id.c_str(),
|
|
317
|
+
"noobs_buffer_encoder",
|
|
318
|
+
video_encoder_settings,
|
|
319
|
+
NULL
|
|
320
|
+
);
|
|
289
321
|
|
|
290
322
|
if (!buffer_video_encoder) {
|
|
291
323
|
blog(LOG_ERROR, "Failed to create buffer video encoder!");
|
|
292
324
|
throw std::runtime_error("Failed to create buffer video encoder!");
|
|
293
325
|
}
|
|
294
326
|
|
|
295
|
-
blog(LOG_INFO, "Set file video encoder settings");
|
|
296
|
-
obs_data_t* venc_settings = obs_data_create();
|
|
297
|
-
// obs_data_set_string(venc_settings, "preset", "speed"); // Faster preset
|
|
298
|
-
obs_data_set_string(venc_settings, "rate_control", "CRF");
|
|
299
|
-
obs_data_set_int(venc_settings, "crf", 22);
|
|
300
|
-
obs_data_set_string(venc_settings, "profile", "main");
|
|
301
|
-
obs_data_set_int(venc_settings, "keyint_sec", 1); // Set keyframe interval to 1 second
|
|
302
|
-
|
|
303
|
-
obs_encoder_update(file_video_encoder, venc_settings);
|
|
304
|
-
obs_encoder_update(buffer_video_encoder, venc_settings);
|
|
305
|
-
obs_data_release(venc_settings);
|
|
306
|
-
|
|
307
327
|
obs_output_set_video_encoder(file_output, file_video_encoder);
|
|
308
|
-
obs_encoder_set_video(file_video_encoder, obs_get_video());
|
|
309
328
|
obs_output_set_video_encoder(buffer_output, buffer_video_encoder);
|
|
329
|
+
|
|
330
|
+
obs_encoder_set_video(file_video_encoder, obs_get_video());
|
|
310
331
|
obs_encoder_set_video(buffer_video_encoder, obs_get_video());
|
|
311
332
|
}
|
|
312
333
|
|
|
@@ -371,12 +392,34 @@ void ObsInterface::create_scene() {
|
|
|
371
392
|
obs_set_output_source(0, scene_source); // 0 = video track
|
|
372
393
|
}
|
|
373
394
|
|
|
395
|
+
void ObsInterface::volmeter_callback(void *data,
|
|
396
|
+
const float magnitude[MAX_AUDIO_CHANNELS],
|
|
397
|
+
const float peak[MAX_AUDIO_CHANNELS],
|
|
398
|
+
const float inputPeak[MAX_AUDIO_CHANNELS])
|
|
399
|
+
{
|
|
400
|
+
// blog(LOG_DEBUG, "Volmeter callback triggered: %f %f %f",
|
|
401
|
+
// obs_db_to_mul(magnitude[0]),
|
|
402
|
+
// obs_db_to_mul(peak[0]),
|
|
403
|
+
// obs_db_to_mul(inputPeak[0])
|
|
404
|
+
// );
|
|
405
|
+
|
|
406
|
+
SignalContext* ctx = static_cast<SignalContext*>(data);
|
|
407
|
+
ObsInterface* self = ctx->self;
|
|
408
|
+
|
|
409
|
+
if (!self->volmeter_enabled) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
SignalData* sd = new SignalData{ "volmeter", ctx->id.c_str(), 0, obs_db_to_mul(peak[0]) };
|
|
414
|
+
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
415
|
+
}
|
|
416
|
+
|
|
374
417
|
void ObsInterface::createSource(std::string name, std::string type) {
|
|
375
418
|
blog(LOG_INFO, "Create source: %s of type %s", name.c_str(), type.c_str());
|
|
376
419
|
|
|
377
420
|
obs_source_t *source = obs_source_create(
|
|
378
|
-
type.c_str(),
|
|
379
|
-
name.c_str(),
|
|
421
|
+
type.c_str(), // Type of source, e.g. "wasapi_input_capture"
|
|
422
|
+
name.c_str(), // Name of the source, e.g. "My Audio Input"
|
|
380
423
|
NULL, // No settings.
|
|
381
424
|
NULL // No hotkey data.
|
|
382
425
|
);
|
|
@@ -385,30 +428,77 @@ void ObsInterface::createSource(std::string name, std::string type) {
|
|
|
385
428
|
blog(LOG_ERROR, "Failed to create source: %s", name.c_str());
|
|
386
429
|
throw std::runtime_error("Failed to create source!");
|
|
387
430
|
}
|
|
431
|
+
|
|
432
|
+
if (type == AUDIO_OUTPUT) {
|
|
433
|
+
blog(LOG_INFO, "Setting output volume for source: %s to %d", name.c_str(), output_volume);
|
|
434
|
+
obs_source_set_volume(source, output_volume);
|
|
435
|
+
} else if (type == AUDIO_INPUT) {
|
|
436
|
+
blog(LOG_INFO, "Setting input volume for source: %s to %d", name.c_str(), input_volume);
|
|
437
|
+
obs_source_set_volume(source, input_volume);
|
|
438
|
+
} else if (type == AUDIO_PROCESS) {
|
|
439
|
+
blog(LOG_INFO, "Setting process volume for source: %s to %d", name.c_str(), process_volume);
|
|
440
|
+
obs_source_set_volume(source, process_volume);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (type == AUDIO_OUTPUT || type == AUDIO_INPUT || type == AUDIO_PROCESS) {
|
|
444
|
+
blog(LOG_INFO, "Creating volmeter for source: %s", name.c_str());
|
|
445
|
+
|
|
446
|
+
obs_volmeter_t *volmeter = obs_volmeter_create(OBS_FADER_CUBIC);
|
|
447
|
+
obs_volmeter_attach_source(volmeter, source);
|
|
448
|
+
|
|
449
|
+
SignalContext* ctx = new SignalContext{ this, name }; // TODO don't leak this.
|
|
450
|
+
obs_volmeter_add_callback(volmeter, volmeter_callback, ctx);
|
|
451
|
+
|
|
452
|
+
// Store the volmeter in the volmeters map.
|
|
453
|
+
volmeters[name] = volmeter;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Store the source in the sources map.
|
|
457
|
+
sources[name] = source;
|
|
388
458
|
}
|
|
389
459
|
|
|
390
460
|
void ObsInterface::deleteSource(std::string name) {
|
|
391
461
|
blog(LOG_INFO, "Delete source: %s", name.c_str());
|
|
392
|
-
|
|
462
|
+
|
|
463
|
+
// First release a volmeter if there is one present.
|
|
464
|
+
// Only audio sources have volmeters ofcourse.
|
|
465
|
+
auto vol_it = volmeters.find(name);
|
|
393
466
|
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
|
|
467
|
+
if (vol_it != volmeters.end()) {
|
|
468
|
+
obs_volmeter_t* volmeter = vol_it->second;
|
|
469
|
+
obs_volmeter_remove_callback(volmeter, volmeter_callback, this);
|
|
470
|
+
obs_volmeter_detach_source(volmeter);
|
|
471
|
+
obs_volmeter_destroy(volmeter);
|
|
472
|
+
blog(LOG_INFO, "Volmeter deleted for source: %s", name.c_str());
|
|
473
|
+
volmeters.erase(name);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Now deal with the source itself.
|
|
477
|
+
auto it = sources.find(name);
|
|
478
|
+
|
|
479
|
+
if (it == sources.end()) {
|
|
480
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
481
|
+
return;
|
|
397
482
|
}
|
|
398
483
|
|
|
484
|
+
obs_source_t* source = it->second;
|
|
485
|
+
obs_source_remove(source); // ???
|
|
399
486
|
obs_source_release(source);
|
|
487
|
+
sources.erase(name);
|
|
400
488
|
blog(LOG_INFO, "Source deleted: %s", name.c_str());
|
|
401
489
|
}
|
|
402
490
|
|
|
403
491
|
obs_data_t* ObsInterface::getSourceSettings(std::string name) {
|
|
404
492
|
blog(LOG_INFO, "Get source settings for: %s", name.c_str());
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
493
|
+
|
|
494
|
+
auto it = sources.find(name);
|
|
495
|
+
|
|
496
|
+
if (it == sources.end()) {
|
|
497
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
409
498
|
throw std::runtime_error("Source not found!");
|
|
410
499
|
}
|
|
411
500
|
|
|
501
|
+
obs_source_t* source = it->second;
|
|
412
502
|
obs_data_t *settings = obs_source_get_settings(source);
|
|
413
503
|
|
|
414
504
|
if (!settings) {
|
|
@@ -416,30 +506,34 @@ obs_data_t* ObsInterface::getSourceSettings(std::string name) {
|
|
|
416
506
|
throw std::runtime_error("Failed to get source settings!");
|
|
417
507
|
}
|
|
418
508
|
|
|
509
|
+
// obs_data_release(settings); TODO release after returning to client.
|
|
419
510
|
return settings;
|
|
420
511
|
}
|
|
421
512
|
|
|
422
513
|
void ObsInterface::setSourceSettings(std::string name, obs_data_t* settings) {
|
|
423
514
|
blog(LOG_INFO, "Set source settings for: %s", name.c_str());
|
|
424
|
-
|
|
515
|
+
auto it = sources.find(name);
|
|
425
516
|
|
|
426
|
-
if (
|
|
427
|
-
blog(
|
|
517
|
+
if (it == sources.end()) {
|
|
518
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
428
519
|
throw std::runtime_error("Source not found!");
|
|
429
520
|
}
|
|
430
521
|
|
|
522
|
+
obs_source_t* source = it->second;
|
|
523
|
+
|
|
431
524
|
obs_source_update(source, settings);
|
|
432
525
|
}
|
|
433
526
|
|
|
434
527
|
obs_properties_t* ObsInterface::getSourceProperties(std::string name) {
|
|
435
528
|
blog(LOG_INFO, "Get source properties for: %s", name.c_str());
|
|
436
|
-
|
|
529
|
+
auto it = sources.find(name);
|
|
437
530
|
|
|
438
|
-
if (
|
|
439
|
-
blog(
|
|
531
|
+
if (it == sources.end()) {
|
|
532
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
440
533
|
throw std::runtime_error("Source not found!");
|
|
441
534
|
}
|
|
442
535
|
|
|
536
|
+
obs_source_t* source = it->second;
|
|
443
537
|
obs_properties_t *props = obs_source_properties(source);
|
|
444
538
|
|
|
445
539
|
if (!props) {
|
|
@@ -450,68 +544,33 @@ obs_properties_t* ObsInterface::getSourceProperties(std::string name) {
|
|
|
450
544
|
return props;
|
|
451
545
|
}
|
|
452
546
|
|
|
453
|
-
void
|
|
454
|
-
Napi::Object obj = Napi::Object::New(env);
|
|
455
|
-
obj.Set("id", Napi::String::New(env, sd->id));
|
|
456
|
-
obj.Set("code", Napi::Number::New(env, sd->code));
|
|
457
|
-
cb.Call({ obj });
|
|
458
|
-
delete sd;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
void ObsInterface::output_signal_handler_starting(void *data, calldata_t *cd) {
|
|
462
|
-
long long code = calldata_int(cd, "code");
|
|
463
|
-
ObsInterface* self = static_cast<ObsInterface*>(data);
|
|
464
|
-
SignalData* sd = new SignalData{ "starting", code };
|
|
465
|
-
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
void ObsInterface::output_signal_handler_start(void *data, calldata_t *cd) {
|
|
469
|
-
long long code = calldata_int(cd, "code");
|
|
470
|
-
ObsInterface* self = static_cast<ObsInterface*>(data);
|
|
471
|
-
SignalData* sd = new SignalData{ "start", code };
|
|
472
|
-
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
void ObsInterface::output_signal_handler_stop(void *data, calldata_t *cd) {
|
|
547
|
+
void ObsInterface::output_signal_handler(void *data, calldata_t *cd) {
|
|
476
548
|
long long code = calldata_int(cd, "code");
|
|
477
|
-
ObsInterface* self = static_cast<ObsInterface*>(data);
|
|
478
|
-
SignalData* sd = new SignalData{ "stop", code };
|
|
479
|
-
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
480
|
-
}
|
|
481
549
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
ObsInterface* self = static_cast<ObsInterface*>(data);
|
|
485
|
-
SignalData* sd = new SignalData{ "stopping", code };
|
|
486
|
-
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
487
|
-
}
|
|
550
|
+
SignalContext* ctx = static_cast<SignalContext*>(data);
|
|
551
|
+
ObsInterface* self = ctx->self;
|
|
488
552
|
|
|
489
|
-
|
|
490
|
-
long long code = calldata_int(cd, "code");
|
|
491
|
-
ObsInterface* self = static_cast<ObsInterface*>(data);
|
|
492
|
-
SignalData* sd = new SignalData{ "saved", code };
|
|
553
|
+
SignalData* sd = new SignalData{ "output", ctx->id.c_str(), code };
|
|
493
554
|
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
494
555
|
}
|
|
495
556
|
|
|
496
557
|
void ObsInterface::connect_signal_handlers(obs_output_t *output) {
|
|
497
558
|
signal_handler_t *sh = obs_output_get_signal_handler(output);
|
|
498
|
-
signal_handler_connect(sh, "
|
|
499
|
-
signal_handler_connect(sh, "
|
|
500
|
-
signal_handler_connect(sh, "stopping",
|
|
501
|
-
signal_handler_connect(sh, "stop",
|
|
502
|
-
signal_handler_connect(sh, "saved", output_signal_handler_saved, this);
|
|
559
|
+
signal_handler_connect(sh, "start", output_signal_handler, start_ctx);
|
|
560
|
+
signal_handler_connect(sh, "starting", output_signal_handler, starting_ctx);
|
|
561
|
+
signal_handler_connect(sh, "stopping", output_signal_handler, stopping_ctx);
|
|
562
|
+
signal_handler_connect(sh, "stop", output_signal_handler, stop_ctx);
|
|
503
563
|
}
|
|
504
564
|
|
|
505
565
|
void ObsInterface::disconnect_signal_handlers(obs_output_t *output) {
|
|
506
566
|
signal_handler_t *sh = obs_output_get_signal_handler(output);
|
|
507
|
-
signal_handler_disconnect(sh, "starting",
|
|
508
|
-
signal_handler_disconnect(sh, "start",
|
|
509
|
-
signal_handler_disconnect(sh, "stopping",
|
|
510
|
-
signal_handler_disconnect(sh, "stop",
|
|
511
|
-
signal_handler_disconnect(sh, "saved", output_signal_handler_saved, this);
|
|
567
|
+
signal_handler_disconnect(sh, "starting", output_signal_handler, starting_ctx);
|
|
568
|
+
signal_handler_disconnect(sh, "start", output_signal_handler, start_ctx);
|
|
569
|
+
signal_handler_disconnect(sh, "stopping", output_signal_handler, stopping_ctx);
|
|
570
|
+
signal_handler_disconnect(sh, "stop", output_signal_handler, stop_ctx);
|
|
512
571
|
}
|
|
513
572
|
|
|
514
|
-
bool
|
|
573
|
+
bool draw_source_outline(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
515
574
|
// Get the item position and size
|
|
516
575
|
vec2 pos; vec2 scale;
|
|
517
576
|
obs_sceneitem_get_pos(item, &pos);
|
|
@@ -566,6 +625,12 @@ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
|
566
625
|
gs_draw_sprite(nullptr, 0, 4.0f, height);
|
|
567
626
|
gs_matrix_pop();
|
|
568
627
|
|
|
628
|
+
// Dragging point box (25x25 pixels in bottom-right corner)
|
|
629
|
+
gs_matrix_push();
|
|
630
|
+
gs_matrix_translate3f(pos.x + width - 25.0f, pos.y + height - 25.0f, 0.0f);
|
|
631
|
+
gs_draw_sprite(nullptr, 0, 25.0f, 25.0f);
|
|
632
|
+
gs_matrix_pop();
|
|
633
|
+
|
|
569
634
|
gs_matrix_pop();
|
|
570
635
|
|
|
571
636
|
gs_technique_end_pass(tech);
|
|
@@ -575,6 +640,8 @@ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
|
575
640
|
}
|
|
576
641
|
|
|
577
642
|
void draw_callback(void* data, uint32_t cx, uint32_t cy) {
|
|
643
|
+
ObsInterface* obsInterface = (ObsInterface*)data;
|
|
644
|
+
|
|
578
645
|
obs_video_info ovi;
|
|
579
646
|
obs_get_video_info(&ovi);
|
|
580
647
|
|
|
@@ -606,7 +673,9 @@ void draw_callback(void* data, uint32_t cx, uint32_t cy) {
|
|
|
606
673
|
|
|
607
674
|
// Draw boxes around sources.
|
|
608
675
|
obs_scene_t* scene = obs_get_scene_by_name("WCR Scene");
|
|
609
|
-
|
|
676
|
+
if (obsInterface->getDrawSourceOutlineEnabled()) {
|
|
677
|
+
obs_scene_enum_items(scene, draw_source_outline, NULL);
|
|
678
|
+
}
|
|
610
679
|
obs_scene_release(scene);
|
|
611
680
|
|
|
612
681
|
gs_projection_pop();
|
|
@@ -657,13 +726,13 @@ void ObsInterface::initPreview(HWND parent) {
|
|
|
657
726
|
return;
|
|
658
727
|
}
|
|
659
728
|
|
|
660
|
-
obs_display_add_draw_callback(display, draw_callback,
|
|
729
|
+
obs_display_add_draw_callback(display, draw_callback, this);
|
|
661
730
|
}
|
|
662
731
|
|
|
663
732
|
obs_display_set_enabled(display, false);
|
|
664
733
|
}
|
|
665
734
|
|
|
666
|
-
void ObsInterface::
|
|
735
|
+
void ObsInterface::configurePreview(int x, int y, int width, int height) {
|
|
667
736
|
blog(LOG_INFO, "ObsInterface::showPreview");
|
|
668
737
|
|
|
669
738
|
if (!preview_hwnd || !display) {
|
|
@@ -671,7 +740,7 @@ void ObsInterface::showPreview(int x, int y, int width, int height) {
|
|
|
671
740
|
return;
|
|
672
741
|
}
|
|
673
742
|
|
|
674
|
-
blog(LOG_INFO, "
|
|
743
|
+
blog(LOG_INFO, "Moving preview child window to (%d, %d) with size (%d x %d)", x, y, width, height);
|
|
675
744
|
|
|
676
745
|
// Resize and move the existing child window.
|
|
677
746
|
bool success = SetWindowPos(
|
|
@@ -690,8 +759,18 @@ void ObsInterface::showPreview(int x, int y, int width, int height) {
|
|
|
690
759
|
uint32_t w, h;
|
|
691
760
|
obs_display_size(display, &w, &h); // Get the display size to match the video context.
|
|
692
761
|
blog(LOG_INFO, "Current Display size set to (%d x %d)", w, h);
|
|
693
|
-
|
|
694
762
|
obs_display_resize(display, width, height);
|
|
763
|
+
obs_display_set_enabled(display, true);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
void ObsInterface::showPreview() {
|
|
767
|
+
blog(LOG_INFO, "ObsInterface::showPreview");
|
|
768
|
+
|
|
769
|
+
if (!preview_hwnd || !display) {
|
|
770
|
+
blog(LOG_ERROR, "Preview window not initialized");
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
|
|
695
774
|
ShowWindow(preview_hwnd, SW_SHOW);
|
|
696
775
|
obs_display_set_enabled(display, true);
|
|
697
776
|
}
|
|
@@ -703,14 +782,24 @@ void ObsInterface::hidePreview() {
|
|
|
703
782
|
ShowWindow(preview_hwnd, SW_HIDE);
|
|
704
783
|
blog(LOG_INFO, "Preview child window hidden");
|
|
705
784
|
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
void ObsInterface::disablePreview() {
|
|
788
|
+
blog(LOG_INFO, "ObsInterface::disablePreview");
|
|
789
|
+
|
|
790
|
+
if (!display) {
|
|
791
|
+
blog(LOG_ERROR, "Preview window not initialized");
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
706
794
|
|
|
795
|
+
hidePreview();
|
|
707
796
|
obs_display_set_enabled(display, false);
|
|
708
797
|
}
|
|
709
798
|
|
|
710
|
-
|
|
799
|
+
PreviewInfo ObsInterface::getPreviewInfo() {
|
|
711
800
|
if (!display) {
|
|
712
|
-
blog(LOG_WARNING, "Display not initialized");
|
|
713
|
-
return
|
|
801
|
+
blog(LOG_WARNING, "Display not initialized when calling getPreviewInfo");
|
|
802
|
+
return { 1920, 1080, 1920, 1080 }; // Default values
|
|
714
803
|
}
|
|
715
804
|
|
|
716
805
|
obs_video_info ovi;
|
|
@@ -719,25 +808,27 @@ float ObsInterface::getPreviewScaleFactor() {
|
|
|
719
808
|
uint32_t width, height;
|
|
720
809
|
obs_display_size(display, &width, &height);
|
|
721
810
|
|
|
722
|
-
|
|
723
|
-
|
|
811
|
+
PreviewInfo info = {
|
|
812
|
+
ovi.base_width,
|
|
813
|
+
ovi.base_height,
|
|
814
|
+
width,
|
|
815
|
+
height,
|
|
816
|
+
};
|
|
724
817
|
|
|
725
|
-
|
|
818
|
+
return info;
|
|
819
|
+
}
|
|
726
820
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
} else {
|
|
731
|
-
previewScale = scaleY;
|
|
732
|
-
}
|
|
821
|
+
void ObsInterface::setDrawSourceOutline(bool enabled) {
|
|
822
|
+
drawSourceOutline = enabled;
|
|
823
|
+
}
|
|
733
824
|
|
|
734
|
-
|
|
825
|
+
bool ObsInterface::getDrawSourceOutlineEnabled() {
|
|
826
|
+
return drawSourceOutline;
|
|
735
827
|
}
|
|
736
828
|
|
|
737
829
|
ObsInterface::ObsInterface(
|
|
738
|
-
const std::string&
|
|
830
|
+
const std::string& distPath,
|
|
739
831
|
const std::string& logPath,
|
|
740
|
-
const std::string& dataPath,
|
|
741
832
|
const std::string& recordingPath,
|
|
742
833
|
Napi::ThreadSafeFunction cb
|
|
743
834
|
) {
|
|
@@ -746,16 +837,23 @@ ObsInterface::ObsInterface(
|
|
|
746
837
|
blog(LOG_DEBUG, "Creating ObsInterface");
|
|
747
838
|
|
|
748
839
|
// Initialize OBS and load required modules.
|
|
749
|
-
init_obs(
|
|
840
|
+
init_obs(distPath);
|
|
750
841
|
|
|
751
842
|
// Setup callback function.
|
|
752
843
|
jscb = cb;
|
|
753
844
|
recording_path = recordingPath;
|
|
754
845
|
|
|
846
|
+
starting_ctx = new SignalContext{ this, "starting" };
|
|
847
|
+
start_ctx = new SignalContext{ this, "start" };
|
|
848
|
+
stopping_ctx = new SignalContext{ this, "stopping" };
|
|
849
|
+
stop_ctx = new SignalContext{ this, "stop" };
|
|
850
|
+
|
|
755
851
|
// Create the resources we rely on.
|
|
756
852
|
create_output();
|
|
757
853
|
create_scene();
|
|
758
854
|
|
|
855
|
+
video_encoder_id = "obs_x264";
|
|
856
|
+
video_encoder_settings = obs_data_create();
|
|
759
857
|
create_video_encoders();
|
|
760
858
|
create_audio_encoders();
|
|
761
859
|
}
|
|
@@ -763,14 +861,26 @@ ObsInterface::ObsInterface(
|
|
|
763
861
|
ObsInterface::~ObsInterface() {
|
|
764
862
|
blog(LOG_DEBUG, "Destroying ObsInterface");
|
|
765
863
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
864
|
+
for (auto& kv : volmeters) {
|
|
865
|
+
obs_volmeter_t* volmeter = kv.second;
|
|
866
|
+
obs_volmeter_remove_callback(volmeter, volmeter_callback, this);
|
|
867
|
+
obs_volmeter_detach_source(volmeter);
|
|
868
|
+
obs_volmeter_destroy(volmeter);
|
|
869
|
+
blog(LOG_INFO, "Volmeter deleted for source: %s", kv.first.c_str());
|
|
870
|
+
volmeters.erase(kv.first);
|
|
769
871
|
}
|
|
770
872
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
873
|
+
delete starting_ctx;
|
|
874
|
+
delete start_ctx;
|
|
875
|
+
delete stopping_ctx;
|
|
876
|
+
delete stop_ctx;
|
|
877
|
+
|
|
878
|
+
for (auto& kv : sources) {
|
|
879
|
+
std::string name = kv.first;
|
|
880
|
+
obs_source_t* source = kv.second;
|
|
881
|
+
blog(LOG_DEBUG, "Releasing source: %s", name.c_str());
|
|
882
|
+
obs_source_release(source);
|
|
883
|
+
sources.erase(name);
|
|
774
884
|
}
|
|
775
885
|
|
|
776
886
|
if (scene) {
|
|
@@ -810,6 +920,11 @@ ObsInterface::~ObsInterface() {
|
|
|
810
920
|
|
|
811
921
|
blog(LOG_DEBUG, "Now shutting down OBS");
|
|
812
922
|
obs_shutdown();
|
|
923
|
+
|
|
924
|
+
if (jscb) {
|
|
925
|
+
blog(LOG_DEBUG, "Releasing JavaScript callback");
|
|
926
|
+
jscb.Release();
|
|
927
|
+
}
|
|
813
928
|
}
|
|
814
929
|
|
|
815
930
|
bool ObsInterface::setBuffering(bool value) {
|
|
@@ -880,6 +995,14 @@ void ObsInterface::startRecording(int offset) {
|
|
|
880
995
|
throw std::runtime_error("Failed to call convert procedure handler");
|
|
881
996
|
}
|
|
882
997
|
} else {
|
|
998
|
+
|
|
999
|
+
obs_data_t *ffmpeg_settings = obs_data_create();
|
|
1000
|
+
std::string filename = recording_path + "\\" + get_current_date_time() + ".mp4";
|
|
1001
|
+
obs_data_set_string(ffmpeg_settings, "path", filename.c_str());
|
|
1002
|
+
obs_output_update(output, ffmpeg_settings);
|
|
1003
|
+
obs_data_release(ffmpeg_settings);
|
|
1004
|
+
unbuffered_output_filename = filename;
|
|
1005
|
+
|
|
883
1006
|
blog(LOG_INFO, "Starting ffmpeg_muxer output");
|
|
884
1007
|
|
|
885
1008
|
bool is_active = obs_output_active(output);
|
|
@@ -916,6 +1039,20 @@ void ObsInterface::stopRecording() {
|
|
|
916
1039
|
blog(LOG_INFO, "ObsInterface::stopRecording exited");
|
|
917
1040
|
}
|
|
918
1041
|
|
|
1042
|
+
void ObsInterface::forceStopRecording() {
|
|
1043
|
+
blog(LOG_INFO, "ObsInterface::forceStopRecording enter");
|
|
1044
|
+
obs_output_t* output = buffering ? buffer_output : file_output;
|
|
1045
|
+
bool is_active = obs_output_active(output);
|
|
1046
|
+
|
|
1047
|
+
if (!is_active) {
|
|
1048
|
+
blog(LOG_WARNING, "Output is not active");
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
obs_output_force_stop(output);
|
|
1053
|
+
blog(LOG_INFO, "ObsInterface::forceStopRecording exited");
|
|
1054
|
+
}
|
|
1055
|
+
|
|
919
1056
|
std::string ObsInterface::getLastRecording() {
|
|
920
1057
|
blog(LOG_INFO, "calling get last replay proc handler");
|
|
921
1058
|
calldata cd;
|
|
@@ -928,7 +1065,7 @@ std::string ObsInterface::getLastRecording() {
|
|
|
928
1065
|
|
|
929
1066
|
if (!buffering) {
|
|
930
1067
|
blog(LOG_INFO, "Getting last recording path from ffmpeg_muxer");
|
|
931
|
-
return
|
|
1068
|
+
return unbuffered_output_filename;
|
|
932
1069
|
}
|
|
933
1070
|
|
|
934
1071
|
bool success = proc_handler_call(ph, "get_last_replay", &cd);
|
|
@@ -952,21 +1089,22 @@ std::string ObsInterface::getLastRecording() {
|
|
|
952
1089
|
void ObsInterface::addSourceToScene(std::string name) {
|
|
953
1090
|
blog(LOG_INFO, "ObsInterface::addSourceToScene called for source: %s", name.c_str());
|
|
954
1091
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
if (
|
|
958
|
-
blog(LOG_WARNING, "
|
|
959
|
-
|
|
1092
|
+
auto it = sources.find(name);
|
|
1093
|
+
|
|
1094
|
+
if (it == sources.end()) {
|
|
1095
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1096
|
+
throw std::runtime_error("Source not found!");
|
|
960
1097
|
}
|
|
961
1098
|
|
|
1099
|
+
obs_source_t* source = it->second;
|
|
1100
|
+
|
|
962
1101
|
// TODO refuse to add twice?
|
|
1102
|
+
obs_sceneitem_t *item = obs_scene_add(scene, source);
|
|
963
1103
|
|
|
964
|
-
obs_sceneitem_t *item = obs_scene_add(scene, src);
|
|
965
|
-
|
|
966
1104
|
if (!item) {
|
|
967
1105
|
blog(LOG_ERROR, "Failed to add source to scene: %s", name.c_str());
|
|
968
|
-
obs_source_release(
|
|
969
|
-
|
|
1106
|
+
obs_source_release(source);
|
|
1107
|
+
throw std::runtime_error("Failed to add source to scene");
|
|
970
1108
|
}
|
|
971
1109
|
|
|
972
1110
|
blog(LOG_INFO, "ObsInterface::addSourceToScene exited");
|
|
@@ -988,16 +1126,24 @@ void ObsInterface::removeSourceFromScene(std::string name) {
|
|
|
988
1126
|
|
|
989
1127
|
void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* scale)
|
|
990
1128
|
{
|
|
991
|
-
|
|
992
|
-
|
|
1129
|
+
auto it = sources.find(name);
|
|
1130
|
+
|
|
1131
|
+
if (it == sources.end()) {
|
|
1132
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1133
|
+
throw std::runtime_error("Source not found!");
|
|
1134
|
+
}
|
|
993
1135
|
|
|
994
|
-
|
|
995
|
-
|
|
1136
|
+
obs_source_t* source = it->second;
|
|
1137
|
+
|
|
1138
|
+
if (!source) {
|
|
1139
|
+
blog(LOG_WARNING, "Did not find source for video source: %s", name.c_str());
|
|
996
1140
|
return;
|
|
997
1141
|
}
|
|
998
1142
|
|
|
1143
|
+
obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
|
|
1144
|
+
|
|
999
1145
|
if (!item) {
|
|
1000
|
-
blog(LOG_WARNING, "Did not find scene item for video source: %s", name);
|
|
1146
|
+
blog(LOG_WARNING, "Did not find scene item for video source: %s", name.c_str());
|
|
1001
1147
|
return;
|
|
1002
1148
|
}
|
|
1003
1149
|
|
|
@@ -1005,18 +1151,128 @@ void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* s
|
|
|
1005
1151
|
obs_sceneitem_get_scale(item, scale);
|
|
1006
1152
|
|
|
1007
1153
|
// Pre-scaled sizes.
|
|
1008
|
-
size->x = obs_source_get_width(
|
|
1009
|
-
size->y = obs_source_get_height(
|
|
1154
|
+
size->x = obs_source_get_width(source);
|
|
1155
|
+
size->y = obs_source_get_height(source);
|
|
1010
1156
|
}
|
|
1011
1157
|
|
|
1012
1158
|
void ObsInterface::setSourcePos(std::string name, vec2* pos, vec2* scale) {
|
|
1013
1159
|
obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
|
|
1014
1160
|
|
|
1015
1161
|
if (!item) {
|
|
1016
|
-
blog(LOG_WARNING, "Did not find scene item for video source: %s", name);
|
|
1162
|
+
blog(LOG_WARNING, "Did not find scene item for video source: %s", name.c_str());
|
|
1017
1163
|
return;
|
|
1018
1164
|
}
|
|
1019
1165
|
|
|
1020
1166
|
obs_sceneitem_set_pos(item, pos);
|
|
1021
1167
|
obs_sceneitem_set_scale(item, scale);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
std::vector<std::string> ObsInterface::listAvailableVideoEncoders()
|
|
1171
|
+
{
|
|
1172
|
+
std::vector<std::string> encoders;
|
|
1173
|
+
size_t idx = 0;
|
|
1174
|
+
const char *encoder_type;
|
|
1175
|
+
|
|
1176
|
+
while (obs_enum_encoder_types(idx++, &encoder_type)) {
|
|
1177
|
+
bool video = obs_get_encoder_type(encoder_type) == OBS_ENCODER_VIDEO;
|
|
1178
|
+
|
|
1179
|
+
if (video)
|
|
1180
|
+
encoders.emplace_back(encoder_type);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
return encoders;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
void ObsInterface::setVideoEncoder(std::string id, obs_data_t* settings) {
|
|
1187
|
+
// TODO don't allow this if output is active.
|
|
1188
|
+
video_encoder_id = id;
|
|
1189
|
+
video_encoder_settings = settings;
|
|
1190
|
+
create_video_encoders();
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
void ObsInterface::setMuteAudioInputs(bool mute) {
|
|
1194
|
+
// Loop over all sources, and set the mute state if they are of type "wasapi_input_capture".
|
|
1195
|
+
for (const auto& kv : sources) {
|
|
1196
|
+
const std::string& name = kv.first;
|
|
1197
|
+
obs_source_t* source = kv.second;
|
|
1198
|
+
|
|
1199
|
+
if (!source) {
|
|
1200
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1201
|
+
continue;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
const char* type = obs_source_get_id(source);
|
|
1205
|
+
|
|
1206
|
+
if (strcmp(type, AUDIO_INPUT) == 0) {
|
|
1207
|
+
obs_source_set_muted(source, mute);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
void ObsInterface::setOutputVolume(float volume) {
|
|
1213
|
+
blog(LOG_INFO, "Setting output volume to %f", volume);
|
|
1214
|
+
output_volume = volume;
|
|
1215
|
+
|
|
1216
|
+
for (const auto& kv : sources) {
|
|
1217
|
+
const std::string& name = kv.first;
|
|
1218
|
+
obs_source_t* source = kv.second;
|
|
1219
|
+
|
|
1220
|
+
if (!source) {
|
|
1221
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
const char* type = obs_source_get_id(source);
|
|
1226
|
+
|
|
1227
|
+
if (strcmp(type, AUDIO_OUTPUT) == 0) {
|
|
1228
|
+
obs_source_set_volume(source, output_volume);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
void ObsInterface::setInputVolume(float volume) {
|
|
1234
|
+
blog(LOG_INFO, "Setting input volume to %f", volume);
|
|
1235
|
+
input_volume = volume;
|
|
1236
|
+
|
|
1237
|
+
for (const auto& kv : sources) {
|
|
1238
|
+
const std::string& name = kv.first;
|
|
1239
|
+
obs_source_t* source = kv.second;
|
|
1240
|
+
|
|
1241
|
+
if (!source) {
|
|
1242
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1243
|
+
continue;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
const char* type = obs_source_get_id(source);
|
|
1247
|
+
|
|
1248
|
+
if (strcmp(type, AUDIO_INPUT) == 0) {
|
|
1249
|
+
obs_source_set_volume(source, input_volume);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
void ObsInterface::setProcessVolume(float volume) {
|
|
1255
|
+
blog(LOG_INFO, "Setting process volume to %f", volume);
|
|
1256
|
+
process_volume = volume;
|
|
1257
|
+
|
|
1258
|
+
for (const auto& kv : sources) {
|
|
1259
|
+
const std::string& name = kv.first;
|
|
1260
|
+
obs_source_t* source = kv.second;
|
|
1261
|
+
|
|
1262
|
+
if (!source) {
|
|
1263
|
+
blog(LOG_WARNING, "Source %s not found", name.c_str());
|
|
1264
|
+
continue;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
const char* type = obs_source_get_id(source);
|
|
1268
|
+
|
|
1269
|
+
if (strcmp(type, AUDIO_PROCESS) == 0) {
|
|
1270
|
+
obs_source_set_volume(source, process_volume);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
void ObsInterface::setVolmeterEnabled(bool enabled) {
|
|
1276
|
+
blog(LOG_INFO, "Setting volmeter enabled: %d", enabled);
|
|
1277
|
+
volmeter_enabled = enabled;
|
|
1022
1278
|
}
|