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.
Files changed (379) hide show
  1. package/README.md +2 -3
  2. package/dist/bin/obs-nvenc-test.exe +0 -0
  3. package/dist/bin/obs-qsv-test.exe +0 -0
  4. package/dist/data/obs-plugins/image-source/locale/af-ZA.ini +29 -0
  5. package/dist/data/obs-plugins/image-source/locale/ar-SA.ini +38 -0
  6. package/dist/data/obs-plugins/image-source/locale/az-AZ.ini +29 -0
  7. package/dist/data/obs-plugins/image-source/locale/ba-RU.ini +9 -0
  8. package/dist/data/obs-plugins/image-source/locale/be-BY.ini +38 -0
  9. package/dist/data/obs-plugins/image-source/locale/bg-BG.ini +22 -0
  10. package/dist/data/obs-plugins/image-source/locale/bn-BD.ini +32 -0
  11. package/dist/data/obs-plugins/image-source/locale/ca-ES.ini +37 -0
  12. package/dist/data/obs-plugins/image-source/locale/cs-CZ.ini +38 -0
  13. package/dist/data/obs-plugins/image-source/locale/da-DK.ini +36 -0
  14. package/dist/data/obs-plugins/image-source/locale/de-DE.ini +36 -0
  15. package/dist/data/obs-plugins/image-source/locale/el-GR.ini +34 -0
  16. package/dist/data/obs-plugins/image-source/locale/en-GB.ini +4 -0
  17. package/dist/data/obs-plugins/image-source/locale/en-US.ini +40 -0
  18. package/dist/data/obs-plugins/image-source/locale/es-ES.ini +37 -0
  19. package/dist/data/obs-plugins/image-source/locale/et-EE.ini +38 -0
  20. package/dist/data/obs-plugins/image-source/locale/eu-ES.ini +34 -0
  21. package/dist/data/obs-plugins/image-source/locale/fa-IR.ini +38 -0
  22. package/dist/data/obs-plugins/image-source/locale/fi-FI.ini +38 -0
  23. package/dist/data/obs-plugins/image-source/locale/fil-PH.ini +33 -0
  24. package/dist/data/obs-plugins/image-source/locale/fr-FR.ini +36 -0
  25. package/dist/data/obs-plugins/image-source/locale/gd-GB.ini +32 -0
  26. package/dist/data/obs-plugins/image-source/locale/gl-ES.ini +38 -0
  27. package/dist/data/obs-plugins/image-source/locale/he-IL.ini +38 -0
  28. package/dist/data/obs-plugins/image-source/locale/hi-IN.ini +38 -0
  29. package/dist/data/obs-plugins/image-source/locale/hr-HR.ini +34 -0
  30. package/dist/data/obs-plugins/image-source/locale/hu-HU.ini +38 -0
  31. package/dist/data/obs-plugins/image-source/locale/hy-AM.ini +34 -0
  32. package/dist/data/obs-plugins/image-source/locale/id-ID.ini +38 -0
  33. package/dist/data/obs-plugins/image-source/locale/it-IT.ini +36 -0
  34. package/dist/data/obs-plugins/image-source/locale/ja-JP.ini +38 -0
  35. package/dist/data/obs-plugins/image-source/locale/ka-GE.ini +38 -0
  36. package/dist/data/obs-plugins/image-source/locale/kaa.ini +21 -0
  37. package/dist/data/obs-plugins/image-source/locale/kab-KAB.ini +31 -0
  38. package/dist/data/obs-plugins/image-source/locale/kmr-TR.ini +34 -0
  39. package/dist/data/obs-plugins/image-source/locale/ko-KR.ini +38 -0
  40. package/dist/data/obs-plugins/image-source/locale/lo-LA.ini +2 -0
  41. package/dist/data/obs-plugins/image-source/locale/lt-LT.ini +32 -0
  42. package/dist/data/obs-plugins/image-source/locale/mn-MN.ini +19 -0
  43. package/dist/data/obs-plugins/image-source/locale/ms-MY.ini +38 -0
  44. package/dist/data/obs-plugins/image-source/locale/nb-NO.ini +35 -0
  45. package/dist/data/obs-plugins/image-source/locale/nl-NL.ini +36 -0
  46. package/dist/data/obs-plugins/image-source/locale/nn-NO.ini +6 -0
  47. package/dist/data/obs-plugins/image-source/locale/oc-FR.ini +2 -0
  48. package/dist/data/obs-plugins/image-source/locale/pa-IN.ini +1 -0
  49. package/dist/data/obs-plugins/image-source/locale/pl-PL.ini +38 -0
  50. package/dist/data/obs-plugins/image-source/locale/pt-BR.ini +36 -0
  51. package/dist/data/obs-plugins/image-source/locale/pt-PT.ini +38 -0
  52. package/dist/data/obs-plugins/image-source/locale/ro-RO.ini +34 -0
  53. package/dist/data/obs-plugins/image-source/locale/ru-RU.ini +38 -0
  54. package/dist/data/obs-plugins/image-source/locale/si-LK.ini +16 -0
  55. package/dist/data/obs-plugins/image-source/locale/sk-SK.ini +38 -0
  56. package/dist/data/obs-plugins/image-source/locale/sl-SI.ini +34 -0
  57. package/dist/data/obs-plugins/image-source/locale/sq-AL.ini +1 -0
  58. package/dist/data/obs-plugins/image-source/locale/sr-CS.ini +31 -0
  59. package/dist/data/obs-plugins/image-source/locale/sr-SP.ini +31 -0
  60. package/dist/data/obs-plugins/image-source/locale/sv-SE.ini +38 -0
  61. package/dist/data/obs-plugins/image-source/locale/ta-IN.ini +15 -0
  62. package/dist/data/obs-plugins/image-source/locale/th-TH.ini +38 -0
  63. package/dist/data/obs-plugins/image-source/locale/tl-PH.ini +31 -0
  64. package/dist/data/obs-plugins/image-source/locale/tr-TR.ini +38 -0
  65. package/dist/data/obs-plugins/image-source/locale/tt-RU.ini +13 -0
  66. package/dist/data/obs-plugins/image-source/locale/ug-CN.ini +38 -0
  67. package/dist/data/obs-plugins/image-source/locale/uk-UA.ini +38 -0
  68. package/dist/data/obs-plugins/image-source/locale/ur-PK.ini +1 -0
  69. package/dist/data/obs-plugins/image-source/locale/vi-VN.ini +38 -0
  70. package/dist/data/obs-plugins/image-source/locale/zh-CN.ini +38 -0
  71. package/dist/data/obs-plugins/image-source/locale/zh-TW.ini +38 -0
  72. package/dist/data/obs-plugins/obs-ffmpeg/locale/af-ZA.ini +73 -0
  73. package/dist/data/obs-plugins/obs-ffmpeg/locale/ar-SA.ini +101 -0
  74. package/dist/data/obs-plugins/obs-ffmpeg/locale/ba-RU.ini +12 -0
  75. package/dist/data/obs-plugins/obs-ffmpeg/locale/be-BY.ini +101 -0
  76. package/dist/data/obs-plugins/obs-ffmpeg/locale/bg-BG.ini +67 -0
  77. package/dist/data/obs-plugins/obs-ffmpeg/locale/bn-BD.ini +48 -0
  78. package/dist/data/obs-plugins/obs-ffmpeg/locale/ca-ES.ini +101 -0
  79. package/dist/data/obs-plugins/obs-ffmpeg/locale/cs-CZ.ini +98 -0
  80. package/dist/data/obs-plugins/obs-ffmpeg/locale/da-DK.ini +83 -0
  81. package/dist/data/obs-plugins/obs-ffmpeg/locale/de-DE.ini +97 -0
  82. package/dist/data/obs-plugins/obs-ffmpeg/locale/el-GR.ini +85 -0
  83. package/dist/data/obs-plugins/obs-ffmpeg/locale/en-GB.ini +10 -0
  84. package/dist/data/obs-plugins/obs-ffmpeg/locale/en-US.ini +127 -0
  85. package/dist/data/obs-plugins/obs-ffmpeg/locale/es-ES.ini +96 -0
  86. package/dist/data/obs-plugins/obs-ffmpeg/locale/et-EE.ini +73 -0
  87. package/dist/data/obs-plugins/obs-ffmpeg/locale/eu-ES.ini +89 -0
  88. package/dist/data/obs-plugins/obs-ffmpeg/locale/fa-IR.ini +102 -0
  89. package/dist/data/obs-plugins/obs-ffmpeg/locale/fi-FI.ini +96 -0
  90. package/dist/data/obs-plugins/obs-ffmpeg/locale/fil-PH.ini +77 -0
  91. package/dist/data/obs-plugins/obs-ffmpeg/locale/fr-FR.ini +94 -0
  92. package/dist/data/obs-plugins/obs-ffmpeg/locale/gd-GB.ini +48 -0
  93. package/dist/data/obs-plugins/obs-ffmpeg/locale/gl-ES.ini +97 -0
  94. package/dist/data/obs-plugins/obs-ffmpeg/locale/he-IL.ini +100 -0
  95. package/dist/data/obs-plugins/obs-ffmpeg/locale/hi-IN.ini +101 -0
  96. package/dist/data/obs-plugins/obs-ffmpeg/locale/hr-HR.ini +51 -0
  97. package/dist/data/obs-plugins/obs-ffmpeg/locale/hu-HU.ini +100 -0
  98. package/dist/data/obs-plugins/obs-ffmpeg/locale/hy-AM.ini +95 -0
  99. package/dist/data/obs-plugins/obs-ffmpeg/locale/id-ID.ini +88 -0
  100. package/dist/data/obs-plugins/obs-ffmpeg/locale/is-IS.ini +2 -0
  101. package/dist/data/obs-plugins/obs-ffmpeg/locale/it-IT.ini +96 -0
  102. package/dist/data/obs-plugins/obs-ffmpeg/locale/ja-JP.ini +88 -0
  103. package/dist/data/obs-plugins/obs-ffmpeg/locale/ka-GE.ini +102 -0
  104. package/dist/data/obs-plugins/obs-ffmpeg/locale/kaa.ini +42 -0
  105. package/dist/data/obs-plugins/obs-ffmpeg/locale/kab-KAB.ini +34 -0
  106. package/dist/data/obs-plugins/obs-ffmpeg/locale/kmr-TR.ini +89 -0
  107. package/dist/data/obs-plugins/obs-ffmpeg/locale/ko-KR.ini +96 -0
  108. package/dist/data/obs-plugins/obs-ffmpeg/locale/ms-MY.ini +93 -0
  109. package/dist/data/obs-plugins/obs-ffmpeg/locale/nb-NO.ini +71 -0
  110. package/dist/data/obs-plugins/obs-ffmpeg/locale/nl-NL.ini +85 -0
  111. package/dist/data/obs-plugins/obs-ffmpeg/locale/nn-NO.ini +21 -0
  112. package/dist/data/obs-plugins/obs-ffmpeg/locale/oc-FR.ini +1 -0
  113. package/dist/data/obs-plugins/obs-ffmpeg/locale/pl-PL.ini +96 -0
  114. package/dist/data/obs-plugins/obs-ffmpeg/locale/pt-BR.ini +95 -0
  115. package/dist/data/obs-plugins/obs-ffmpeg/locale/pt-PT.ini +97 -0
  116. package/dist/data/obs-plugins/obs-ffmpeg/locale/ro-RO.ini +92 -0
  117. package/dist/data/obs-plugins/obs-ffmpeg/locale/ru-RU.ini +102 -0
  118. package/dist/data/obs-plugins/obs-ffmpeg/locale/si-LK.ini +53 -0
  119. package/dist/data/obs-plugins/obs-ffmpeg/locale/sk-SK.ini +86 -0
  120. package/dist/data/obs-plugins/obs-ffmpeg/locale/sl-SI.ini +99 -0
  121. package/dist/data/obs-plugins/obs-ffmpeg/locale/sr-CS.ini +34 -0
  122. package/dist/data/obs-plugins/obs-ffmpeg/locale/sr-SP.ini +52 -0
  123. package/dist/data/obs-plugins/obs-ffmpeg/locale/sv-SE.ini +101 -0
  124. package/dist/data/obs-plugins/obs-ffmpeg/locale/szl-PL.ini +23 -0
  125. package/dist/data/obs-plugins/obs-ffmpeg/locale/ta-IN.ini +20 -0
  126. package/dist/data/obs-plugins/obs-ffmpeg/locale/th-TH.ini +98 -0
  127. package/dist/data/obs-plugins/obs-ffmpeg/locale/tl-PH.ini +26 -0
  128. package/dist/data/obs-plugins/obs-ffmpeg/locale/tr-TR.ini +98 -0
  129. package/dist/data/obs-plugins/obs-ffmpeg/locale/tt-RU.ini +32 -0
  130. package/dist/data/obs-plugins/obs-ffmpeg/locale/ug-CN.ini +96 -0
  131. package/dist/data/obs-plugins/obs-ffmpeg/locale/uk-UA.ini +98 -0
  132. package/dist/data/obs-plugins/obs-ffmpeg/locale/ur-PK.ini +1 -0
  133. package/dist/data/obs-plugins/obs-ffmpeg/locale/vi-VN.ini +91 -0
  134. package/dist/data/obs-plugins/obs-ffmpeg/locale/zh-CN.ini +101 -0
  135. package/dist/data/obs-plugins/obs-ffmpeg/locale/zh-TW.ini +98 -0
  136. package/dist/data/obs-plugins/obs-x264/locale/af-ZA.ini +8 -0
  137. package/dist/data/obs-plugins/obs-x264/locale/ar-SA.ini +13 -0
  138. package/dist/data/obs-plugins/obs-x264/locale/az-AZ.ini +12 -0
  139. package/dist/data/obs-plugins/obs-x264/locale/ba-RU.ini +4 -0
  140. package/dist/data/obs-plugins/obs-x264/locale/be-BY.ini +13 -0
  141. package/dist/data/obs-plugins/obs-x264/locale/bg-BG.ini +7 -0
  142. package/dist/data/obs-plugins/obs-x264/locale/bn-BD.ini +10 -0
  143. package/dist/data/obs-plugins/obs-x264/locale/ca-ES.ini +13 -0
  144. package/dist/data/obs-plugins/obs-x264/locale/cs-CZ.ini +12 -0
  145. package/dist/data/obs-plugins/obs-x264/locale/da-DK.ini +13 -0
  146. package/dist/data/obs-plugins/obs-x264/locale/de-DE.ini +10 -0
  147. package/dist/data/obs-plugins/obs-x264/locale/el-GR.ini +13 -0
  148. package/dist/data/obs-plugins/obs-x264/locale/en-GB.ini +1 -0
  149. package/dist/data/obs-plugins/obs-x264/locale/en-US.ini +14 -0
  150. package/dist/data/obs-plugins/obs-x264/locale/es-ES.ini +13 -0
  151. package/dist/data/obs-plugins/obs-x264/locale/et-EE.ini +13 -0
  152. package/dist/data/obs-plugins/obs-x264/locale/eu-ES.ini +12 -0
  153. package/dist/data/obs-plugins/obs-x264/locale/fa-IR.ini +13 -0
  154. package/dist/data/obs-plugins/obs-x264/locale/fi-FI.ini +13 -0
  155. package/dist/data/obs-plugins/obs-x264/locale/fil-PH.ini +12 -0
  156. package/dist/data/obs-plugins/obs-x264/locale/fr-FR.ini +13 -0
  157. package/dist/data/obs-plugins/obs-x264/locale/gd-GB.ini +10 -0
  158. package/dist/data/obs-plugins/obs-x264/locale/gl-ES.ini +13 -0
  159. package/dist/data/obs-plugins/obs-x264/locale/he-IL.ini +13 -0
  160. package/dist/data/obs-plugins/obs-x264/locale/hi-IN.ini +13 -0
  161. package/dist/data/obs-plugins/obs-x264/locale/hr-HR.ini +13 -0
  162. package/dist/data/obs-plugins/obs-x264/locale/hu-HU.ini +13 -0
  163. package/dist/data/obs-plugins/obs-x264/locale/hy-AM.ini +13 -0
  164. package/dist/data/obs-plugins/obs-x264/locale/id-ID.ini +11 -0
  165. package/dist/data/obs-plugins/obs-x264/locale/it-IT.ini +13 -0
  166. package/dist/data/obs-plugins/obs-x264/locale/ja-JP.ini +13 -0
  167. package/dist/data/obs-plugins/obs-x264/locale/ka-GE.ini +13 -0
  168. package/dist/data/obs-plugins/obs-x264/locale/kaa.ini +5 -0
  169. package/dist/data/obs-plugins/obs-x264/locale/kab-KAB.ini +10 -0
  170. package/dist/data/obs-plugins/obs-x264/locale/kmr-TR.ini +12 -0
  171. package/dist/data/obs-plugins/obs-x264/locale/ko-KR.ini +13 -0
  172. package/dist/data/obs-plugins/obs-x264/locale/lv-LV.ini +4 -0
  173. package/dist/data/obs-plugins/obs-x264/locale/mn-MN.ini +10 -0
  174. package/dist/data/obs-plugins/obs-x264/locale/ms-MY.ini +13 -0
  175. package/dist/data/obs-plugins/obs-x264/locale/nb-NO.ini +9 -0
  176. package/dist/data/obs-plugins/obs-x264/locale/nl-NL.ini +11 -0
  177. package/dist/data/obs-plugins/obs-x264/locale/nn-NO.ini +1 -0
  178. package/dist/data/obs-plugins/obs-x264/locale/oc-FR.ini +1 -0
  179. package/dist/data/obs-plugins/obs-x264/locale/pl-PL.ini +13 -0
  180. package/dist/data/obs-plugins/obs-x264/locale/pt-BR.ini +13 -0
  181. package/dist/data/obs-plugins/obs-x264/locale/pt-PT.ini +13 -0
  182. package/dist/data/obs-plugins/obs-x264/locale/ro-RO.ini +13 -0
  183. package/dist/data/obs-plugins/obs-x264/locale/ru-RU.ini +13 -0
  184. package/dist/data/obs-plugins/obs-x264/locale/si-LK.ini +8 -0
  185. package/dist/data/obs-plugins/obs-x264/locale/sk-SK.ini +12 -0
  186. package/dist/data/obs-plugins/obs-x264/locale/sl-SI.ini +13 -0
  187. package/dist/data/obs-plugins/obs-x264/locale/sq-AL.ini +3 -0
  188. package/dist/data/obs-plugins/obs-x264/locale/sr-CS.ini +10 -0
  189. package/dist/data/obs-plugins/obs-x264/locale/sr-SP.ini +10 -0
  190. package/dist/data/obs-plugins/obs-x264/locale/sv-SE.ini +12 -0
  191. package/dist/data/obs-plugins/obs-x264/locale/szl-PL.ini +9 -0
  192. package/dist/data/obs-plugins/obs-x264/locale/ta-IN.ini +4 -0
  193. package/dist/data/obs-plugins/obs-x264/locale/th-TH.ini +13 -0
  194. package/dist/data/obs-plugins/obs-x264/locale/tl-PH.ini +9 -0
  195. package/dist/data/obs-plugins/obs-x264/locale/tr-TR.ini +13 -0
  196. package/dist/data/obs-plugins/obs-x264/locale/tt-RU.ini +4 -0
  197. package/dist/data/obs-plugins/obs-x264/locale/ug-CN.ini +13 -0
  198. package/dist/data/obs-plugins/obs-x264/locale/uk-UA.ini +13 -0
  199. package/dist/data/obs-plugins/obs-x264/locale/ur-PK.ini +1 -0
  200. package/dist/data/obs-plugins/obs-x264/locale/vi-VN.ini +13 -0
  201. package/dist/data/obs-plugins/obs-x264/locale/zh-CN.ini +13 -0
  202. package/dist/data/obs-plugins/obs-x264/locale/zh-TW.ini +13 -0
  203. package/dist/data/obs-plugins/win-capture/compatibility.json +664 -0
  204. package/dist/data/obs-plugins/win-capture/get-graphics-offsets32.exe +0 -0
  205. package/dist/data/obs-plugins/win-capture/get-graphics-offsets64.exe +0 -0
  206. package/dist/data/obs-plugins/win-capture/graphics-hook32.dll +0 -0
  207. package/dist/data/obs-plugins/win-capture/graphics-hook64.dll +0 -0
  208. package/dist/data/obs-plugins/win-capture/inject-helper32.exe +0 -0
  209. package/dist/data/obs-plugins/win-capture/inject-helper64.exe +0 -0
  210. package/dist/data/obs-plugins/win-capture/locale/af-ZA.ini +30 -0
  211. package/dist/data/obs-plugins/win-capture/locale/ar-SA.ini +54 -0
  212. package/dist/data/obs-plugins/win-capture/locale/az-AZ.ini +13 -0
  213. package/dist/data/obs-plugins/win-capture/locale/ba-RU.ini +2 -0
  214. package/dist/data/obs-plugins/win-capture/locale/be-BY.ini +54 -0
  215. package/dist/data/obs-plugins/win-capture/locale/bg-BG.ini +33 -0
  216. package/dist/data/obs-plugins/win-capture/locale/bn-BD.ini +36 -0
  217. package/dist/data/obs-plugins/win-capture/locale/ca-ES.ini +53 -0
  218. package/dist/data/obs-plugins/win-capture/locale/cs-CZ.ini +54 -0
  219. package/dist/data/obs-plugins/win-capture/locale/da-DK.ini +53 -0
  220. package/dist/data/obs-plugins/win-capture/locale/de-DE.ini +53 -0
  221. package/dist/data/obs-plugins/win-capture/locale/el-GR.ini +48 -0
  222. package/dist/data/obs-plugins/win-capture/locale/en-GB.ini +3 -0
  223. package/dist/data/obs-plugins/win-capture/locale/en-US.ini +60 -0
  224. package/dist/data/obs-plugins/win-capture/locale/es-ES.ini +53 -0
  225. package/dist/data/obs-plugins/win-capture/locale/et-EE.ini +44 -0
  226. package/dist/data/obs-plugins/win-capture/locale/eu-ES.ini +38 -0
  227. package/dist/data/obs-plugins/win-capture/locale/fa-IR.ini +54 -0
  228. package/dist/data/obs-plugins/win-capture/locale/fi-FI.ini +54 -0
  229. package/dist/data/obs-plugins/win-capture/locale/fil-PH.ini +36 -0
  230. package/dist/data/obs-plugins/win-capture/locale/fr-FR.ini +52 -0
  231. package/dist/data/obs-plugins/win-capture/locale/gd-GB.ini +36 -0
  232. package/dist/data/obs-plugins/win-capture/locale/gl-ES.ini +54 -0
  233. package/dist/data/obs-plugins/win-capture/locale/he-IL.ini +54 -0
  234. package/dist/data/obs-plugins/win-capture/locale/hi-IN.ini +54 -0
  235. package/dist/data/obs-plugins/win-capture/locale/hr-HR.ini +40 -0
  236. package/dist/data/obs-plugins/win-capture/locale/hu-HU.ini +54 -0
  237. package/dist/data/obs-plugins/win-capture/locale/hy-AM.ini +42 -0
  238. package/dist/data/obs-plugins/win-capture/locale/id-ID.ini +52 -0
  239. package/dist/data/obs-plugins/win-capture/locale/is-IS.ini +2 -0
  240. package/dist/data/obs-plugins/win-capture/locale/it-IT.ini +53 -0
  241. package/dist/data/obs-plugins/win-capture/locale/ja-JP.ini +54 -0
  242. package/dist/data/obs-plugins/win-capture/locale/ka-GE.ini +54 -0
  243. package/dist/data/obs-plugins/win-capture/locale/kaa.ini +19 -0
  244. package/dist/data/obs-plugins/win-capture/locale/kab-KAB.ini +27 -0
  245. package/dist/data/obs-plugins/win-capture/locale/kmr-TR.ini +42 -0
  246. package/dist/data/obs-plugins/win-capture/locale/ko-KR.ini +54 -0
  247. package/dist/data/obs-plugins/win-capture/locale/lo-LA.ini +6 -0
  248. package/dist/data/obs-plugins/win-capture/locale/lt-LT.ini +36 -0
  249. package/dist/data/obs-plugins/win-capture/locale/mn-MN.ini +21 -0
  250. package/dist/data/obs-plugins/win-capture/locale/ms-MY.ini +53 -0
  251. package/dist/data/obs-plugins/win-capture/locale/nb-NO.ini +39 -0
  252. package/dist/data/obs-plugins/win-capture/locale/nl-NL.ini +50 -0
  253. package/dist/data/obs-plugins/win-capture/locale/nn-NO.ini +4 -0
  254. package/dist/data/obs-plugins/win-capture/locale/pl-PL.ini +54 -0
  255. package/dist/data/obs-plugins/win-capture/locale/pt-BR.ini +54 -0
  256. package/dist/data/obs-plugins/win-capture/locale/pt-PT.ini +54 -0
  257. package/dist/data/obs-plugins/win-capture/locale/ro-RO.ini +41 -0
  258. package/dist/data/obs-plugins/win-capture/locale/ru-RU.ini +54 -0
  259. package/dist/data/obs-plugins/win-capture/locale/si-LK.ini +24 -0
  260. package/dist/data/obs-plugins/win-capture/locale/sk-SK.ini +53 -0
  261. package/dist/data/obs-plugins/win-capture/locale/sl-SI.ini +52 -0
  262. package/dist/data/obs-plugins/win-capture/locale/sq-AL.ini +16 -0
  263. package/dist/data/obs-plugins/win-capture/locale/sr-CS.ini +28 -0
  264. package/dist/data/obs-plugins/win-capture/locale/sr-SP.ini +38 -0
  265. package/dist/data/obs-plugins/win-capture/locale/sv-SE.ini +54 -0
  266. package/dist/data/obs-plugins/win-capture/locale/ta-IN.ini +17 -0
  267. package/dist/data/obs-plugins/win-capture/locale/th-TH.ini +54 -0
  268. package/dist/data/obs-plugins/win-capture/locale/tl-PH.ini +23 -0
  269. package/dist/data/obs-plugins/win-capture/locale/tr-TR.ini +54 -0
  270. package/dist/data/obs-plugins/win-capture/locale/tt-RU.ini +14 -0
  271. package/dist/data/obs-plugins/win-capture/locale/ug-CN.ini +54 -0
  272. package/dist/data/obs-plugins/win-capture/locale/uk-UA.ini +54 -0
  273. package/dist/data/obs-plugins/win-capture/locale/vi-VN.ini +54 -0
  274. package/dist/data/obs-plugins/win-capture/locale/zh-CN.ini +54 -0
  275. package/dist/data/obs-plugins/win-capture/locale/zh-TW.ini +54 -0
  276. package/dist/data/obs-plugins/win-capture/obs-vulkan32.json +17 -0
  277. package/dist/data/obs-plugins/win-capture/obs-vulkan64.json +17 -0
  278. package/dist/data/obs-plugins/win-capture/package.json +11 -0
  279. package/dist/data/obs-plugins/win-capture/schema/compatibility-schema-v1.json +99 -0
  280. package/dist/data/obs-plugins/win-capture/schema/package-schema.json +47 -0
  281. package/dist/data/obs-plugins/win-wasapi/locale/af-ZA.ini +8 -0
  282. package/dist/data/obs-plugins/win-wasapi/locale/an-ES.ini +5 -0
  283. package/dist/data/obs-plugins/win-wasapi/locale/ar-SA.ini +11 -0
  284. package/dist/data/obs-plugins/win-wasapi/locale/ba-RU.ini +2 -0
  285. package/dist/data/obs-plugins/win-wasapi/locale/be-BY.ini +11 -0
  286. package/dist/data/obs-plugins/win-wasapi/locale/bg-BG.ini +3 -0
  287. package/dist/data/obs-plugins/win-wasapi/locale/bn-BD.ini +5 -0
  288. package/dist/data/obs-plugins/win-wasapi/locale/ca-ES.ini +11 -0
  289. package/dist/data/obs-plugins/win-wasapi/locale/cs-CZ.ini +11 -0
  290. package/dist/data/obs-plugins/win-wasapi/locale/da-DK.ini +11 -0
  291. package/dist/data/obs-plugins/win-wasapi/locale/de-DE.ini +11 -0
  292. package/dist/data/obs-plugins/win-wasapi/locale/el-GR.ini +11 -0
  293. package/dist/data/obs-plugins/win-wasapi/locale/en-GB.ini +1 -0
  294. package/dist/data/obs-plugins/win-wasapi/locale/en-US.ini +11 -0
  295. package/dist/data/obs-plugins/win-wasapi/locale/es-ES.ini +11 -0
  296. package/dist/data/obs-plugins/win-wasapi/locale/et-EE.ini +11 -0
  297. package/dist/data/obs-plugins/win-wasapi/locale/eu-ES.ini +11 -0
  298. package/dist/data/obs-plugins/win-wasapi/locale/fa-IR.ini +11 -0
  299. package/dist/data/obs-plugins/win-wasapi/locale/fi-FI.ini +11 -0
  300. package/dist/data/obs-plugins/win-wasapi/locale/fil-PH.ini +9 -0
  301. package/dist/data/obs-plugins/win-wasapi/locale/fr-FR.ini +11 -0
  302. package/dist/data/obs-plugins/win-wasapi/locale/gd-GB.ini +5 -0
  303. package/dist/data/obs-plugins/win-wasapi/locale/gl-ES.ini +11 -0
  304. package/dist/data/obs-plugins/win-wasapi/locale/he-IL.ini +11 -0
  305. package/dist/data/obs-plugins/win-wasapi/locale/hi-IN.ini +11 -0
  306. package/dist/data/obs-plugins/win-wasapi/locale/hr-HR.ini +6 -0
  307. package/dist/data/obs-plugins/win-wasapi/locale/hu-HU.ini +11 -0
  308. package/dist/data/obs-plugins/win-wasapi/locale/hy-AM.ini +10 -0
  309. package/dist/data/obs-plugins/win-wasapi/locale/id-ID.ini +11 -0
  310. package/dist/data/obs-plugins/win-wasapi/locale/is-IS.ini +1 -0
  311. package/dist/data/obs-plugins/win-wasapi/locale/it-IT.ini +11 -0
  312. package/dist/data/obs-plugins/win-wasapi/locale/ja-JP.ini +11 -0
  313. package/dist/data/obs-plugins/win-wasapi/locale/ka-GE.ini +11 -0
  314. package/dist/data/obs-plugins/win-wasapi/locale/kaa.ini +3 -0
  315. package/dist/data/obs-plugins/win-wasapi/locale/kab-KAB.ini +4 -0
  316. package/dist/data/obs-plugins/win-wasapi/locale/kmr-TR.ini +10 -0
  317. package/dist/data/obs-plugins/win-wasapi/locale/ko-KR.ini +11 -0
  318. package/dist/data/obs-plugins/win-wasapi/locale/lt-LT.ini +2 -0
  319. package/dist/data/obs-plugins/win-wasapi/locale/mn-MN.ini +5 -0
  320. package/dist/data/obs-plugins/win-wasapi/locale/ms-MY.ini +11 -0
  321. package/dist/data/obs-plugins/win-wasapi/locale/nb-NO.ini +7 -0
  322. package/dist/data/obs-plugins/win-wasapi/locale/nl-NL.ini +11 -0
  323. package/dist/data/obs-plugins/win-wasapi/locale/nn-NO.ini +2 -0
  324. package/dist/data/obs-plugins/win-wasapi/locale/pl-PL.ini +11 -0
  325. package/dist/data/obs-plugins/win-wasapi/locale/pt-BR.ini +11 -0
  326. package/dist/data/obs-plugins/win-wasapi/locale/pt-PT.ini +11 -0
  327. package/dist/data/obs-plugins/win-wasapi/locale/ro-RO.ini +10 -0
  328. package/dist/data/obs-plugins/win-wasapi/locale/ru-RU.ini +11 -0
  329. package/dist/data/obs-plugins/win-wasapi/locale/si-LK.ini +5 -0
  330. package/dist/data/obs-plugins/win-wasapi/locale/sk-SK.ini +11 -0
  331. package/dist/data/obs-plugins/win-wasapi/locale/sl-SI.ini +11 -0
  332. package/dist/data/obs-plugins/win-wasapi/locale/sq-AL.ini +1 -0
  333. package/dist/data/obs-plugins/win-wasapi/locale/sr-CS.ini +5 -0
  334. package/dist/data/obs-plugins/win-wasapi/locale/sr-SP.ini +10 -0
  335. package/dist/data/obs-plugins/win-wasapi/locale/sv-SE.ini +11 -0
  336. package/dist/data/obs-plugins/win-wasapi/locale/szl-PL.ini +5 -0
  337. package/dist/data/obs-plugins/win-wasapi/locale/ta-IN.ini +5 -0
  338. package/dist/data/obs-plugins/win-wasapi/locale/th-TH.ini +11 -0
  339. package/dist/data/obs-plugins/win-wasapi/locale/tl-PH.ini +5 -0
  340. package/dist/data/obs-plugins/win-wasapi/locale/tr-TR.ini +11 -0
  341. package/dist/data/obs-plugins/win-wasapi/locale/tt-RU.ini +5 -0
  342. package/dist/data/obs-plugins/win-wasapi/locale/ug-CN.ini +11 -0
  343. package/dist/data/obs-plugins/win-wasapi/locale/uk-UA.ini +11 -0
  344. package/dist/data/obs-plugins/win-wasapi/locale/ur-PK.ini +1 -0
  345. package/dist/data/obs-plugins/win-wasapi/locale/vi-VN.ini +11 -0
  346. package/dist/data/obs-plugins/win-wasapi/locale/zh-CN.ini +11 -0
  347. package/dist/data/obs-plugins/win-wasapi/locale/zh-TW.ini +11 -0
  348. package/dist/noobs.node +0 -0
  349. package/dist/{plugins → obs-plugins}/win-capture.dll +0 -0
  350. package/index.d.ts +27 -8
  351. package/package.json +3 -2
  352. package/src/main.cpp +250 -20
  353. package/src/obs_interface.cpp +469 -213
  354. package/src/obs_interface.h +83 -33
  355. /package/dist/{effects → data/effects}/area.effect +0 -0
  356. /package/dist/{effects → data/effects}/bicubic_scale.effect +0 -0
  357. /package/dist/{effects → data/effects}/bilinear_lowres_scale.effect +0 -0
  358. /package/dist/{effects → data/effects}/color.effect +0 -0
  359. /package/dist/{effects → data/effects}/default.effect +0 -0
  360. /package/dist/{effects → data/effects}/default_rect.effect +0 -0
  361. /package/dist/{effects → data/effects}/deinterlace_base.effect +0 -0
  362. /package/dist/{effects → data/effects}/deinterlace_blend.effect +0 -0
  363. /package/dist/{effects → data/effects}/deinterlace_blend_2x.effect +0 -0
  364. /package/dist/{effects → data/effects}/deinterlace_discard.effect +0 -0
  365. /package/dist/{effects → data/effects}/deinterlace_discard_2x.effect +0 -0
  366. /package/dist/{effects → data/effects}/deinterlace_linear.effect +0 -0
  367. /package/dist/{effects → data/effects}/deinterlace_linear_2x.effect +0 -0
  368. /package/dist/{effects → data/effects}/deinterlace_yadif.effect +0 -0
  369. /package/dist/{effects → data/effects}/deinterlace_yadif_2x.effect +0 -0
  370. /package/dist/{effects → data/effects}/format_conversion.effect +0 -0
  371. /package/dist/{effects → data/effects}/lanczos_scale.effect +0 -0
  372. /package/dist/{effects → data/effects}/opaque.effect +0 -0
  373. /package/dist/{effects → data/effects}/premultiplied_alpha.effect +0 -0
  374. /package/dist/{effects → data/effects}/repeat.effect +0 -0
  375. /package/dist/{effects → data/effects}/solid.effect +0 -0
  376. /package/dist/{plugins → obs-plugins}/image-source.dll +0 -0
  377. /package/dist/{plugins → obs-plugins}/obs-ffmpeg.dll +0 -0
  378. /package/dist/{plugins → obs-plugins}/obs-x264.dll +0 -0
  379. /package/dist/{plugins → obs-plugins}/win-wasapi.dll +0 -0
@@ -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
- std::vector<std::string> ObsInterface::get_available_video_encoders()
17
- {
18
- std::vector<std::string> encoders;
19
- size_t idx = 0;
20
- const char *encoder_type;
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
- if (video)
26
- encoders.emplace_back(encoder_type);
17
+ if (sd->value.has_value()) {
18
+ obj.Set("value", Napi::Number::New(env, sd->value.value()));
27
19
  }
28
20
 
29
- return encoders;
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, "List encoders");
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, "List src types");
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, "List output types");
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, NULL);
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::reset_video() {
106
- blog(LOG_INFO, "Setup video 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 = 1920;
111
- ovi.base_height = 1080;
112
- ovi.output_width = 1920;
113
- ovi.output_height = 1080;
114
- ovi.fps_num = 60;
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
- int success = obs_reset_video(&ovi);
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
- void ObsInterface::reset_audio() {
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
- bool reset = obs_reset_audio(&oai);
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& pluginPath, const std::string& dataPath) {
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 dp = dataPath;
156
+ std::string basePath = distPath;
165
157
 
166
- if (dp.back() != '/' && dp.back() != '\\') {
167
- // Add a trailing slash if not present, else libobs gets upset.
168
- dp += '/';
158
+ if (basePath.back() != '/' && basePath.back() != '\\') {
159
+ // Add a trailing slash if not present.
160
+ basePath += '/';
169
161
  }
170
162
 
171
- // We need this before resetting video and audio to ensure the effects
172
- // are available. The function is deprecated in libobs but it works for
173
- // now.
174
- obs_add_data_path(dp.c_str());
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
- reset_video();
178
- reset_audio();
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.dll",
182
- "obs-ffmpeg.dll",
183
- "win-capture.dll", // Required for basically all forms of capture on Windows.
184
- "image-source.dll", // Required for image sources.
185
- "win-wasapi.dll" // Required for WASAPI audio input.
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 path = pluginPath + "/" + module;
190
- load_module(path.c_str());
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
- recording_path = filename;
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, "Create video encoder");
289
+ blog(LOG_INFO, "Set video encoder: %s", video_encoder_id.c_str());
279
290
 
280
- file_video_encoder = obs_video_encoder_create("obs_x264", "h264_stream_file", NULL, NULL);
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
- buffer_video_encoder = obs_video_encoder_create("obs_x264", "h264_stream_buffer", NULL, NULL);
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
- obs_source_t *source = obs_get_source_by_name(name.c_str());
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 (!source) {
395
- blog(LOG_WARNING, "Source not found: %s", name.c_str());
396
- return; // Source not found, nothing to delete.
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
- obs_source_t *source = obs_get_source_by_name(name.c_str());
406
-
407
- if (!source) {
408
- blog(LOG_ERROR, "Source not found: %s", name.c_str());
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
- obs_source_t *source = obs_get_source_by_name(name.c_str());
515
+ auto it = sources.find(name);
425
516
 
426
- if (!source) {
427
- blog(LOG_ERROR, "Source not found: %s", name.c_str());
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
- obs_source_t *source = obs_get_source_by_name(name.c_str());
529
+ auto it = sources.find(name);
437
530
 
438
- if (!source) {
439
- blog(LOG_ERROR, "Source not found: %s", name.c_str());
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 call_jscb(Napi::Env env, Napi::Function cb, SignalData* sd) {
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
- void ObsInterface::output_signal_handler_stopping(void *data, calldata_t *cd) {
483
- long long code = calldata_int(cd, "code");
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
- void ObsInterface::output_signal_handler_saved(void *data, calldata_t *cd) {
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, "starting", output_signal_handler_starting, this);
499
- signal_handler_connect(sh, "start", output_signal_handler_start, this);
500
- signal_handler_connect(sh, "stopping", output_signal_handler_stopping, this);
501
- signal_handler_connect(sh, "stop", output_signal_handler_stop, this);
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", output_signal_handler_starting, this);
508
- signal_handler_disconnect(sh, "start", output_signal_handler_start, this);
509
- signal_handler_disconnect(sh, "stopping", output_signal_handler_stopping, this);
510
- signal_handler_disconnect(sh, "stop", output_signal_handler_stop, this);
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 draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
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
- obs_scene_enum_items(scene, draw_box, NULL);
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, NULL);
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::showPreview(int x, int y, int width, int height) {
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, "Showing preview child window at (%d, %d) with size (%d x %d)", x, y, width, height);
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
- float ObsInterface::getPreviewScaleFactor() {
799
+ PreviewInfo ObsInterface::getPreviewInfo() {
711
800
  if (!display) {
712
- blog(LOG_WARNING, "Display not initialized");
713
- return 1.0f; // Default scale
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
- float scaleX = float(width) / float(ovi.base_width);
723
- float scaleY = float(height) / float(ovi.base_height);
811
+ PreviewInfo info = {
812
+ ovi.base_width,
813
+ ovi.base_height,
814
+ width,
815
+ height,
816
+ };
724
817
 
725
- float previewScale;
818
+ return info;
819
+ }
726
820
 
727
- // Pick the limiting scale factor.
728
- if (scaleX < scaleY) {
729
- previewScale = scaleX;
730
- } else {
731
- previewScale = scaleY;
732
- }
821
+ void ObsInterface::setDrawSourceOutline(bool enabled) {
822
+ drawSourceOutline = enabled;
823
+ }
733
824
 
734
- return previewScale;
825
+ bool ObsInterface::getDrawSourceOutlineEnabled() {
826
+ return drawSourceOutline;
735
827
  }
736
828
 
737
829
  ObsInterface::ObsInterface(
738
- const std::string& pluginPath,
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(pluginPath, dataPath);
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
- if (jscb) {
767
- blog(LOG_DEBUG, "Releasing JavaScript callback");
768
- jscb.Release();
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
- if (video_source) {
772
- blog(LOG_DEBUG, "Releasing video source");
773
- obs_source_release(video_source);
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 recording_path;
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
- obs_source_t *src = obs_get_source_by_name(name.c_str());
956
-
957
- if (!src) {
958
- blog(LOG_WARNING, "Did not find source for video source: %s", name.c_str());
959
- return;
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(src);
969
- return;
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
- obs_source_t *src = obs_get_source_by_name(name.c_str());
992
- obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
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
- if (!src) {
995
- blog(LOG_WARNING, "Did not find source for video source: %s", name);
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(src);
1009
- size->y = obs_source_get_height(src);
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
  }