1
0

studio.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /******************************************************************************
  2. Copyright (C) 2019-2020 by Dillon Pentz <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include "importers.hpp"
  15. #if !defined(_WIN32) && !defined(__APPLE__)
  16. #include <obs-nix-platform.h>
  17. #endif
  18. using namespace std;
  19. using namespace json11;
  20. void TranslateOSStudio(Json &res)
  21. {
  22. Json::object out = res.object_items();
  23. Json::array sources = out["sources"].array_items();
  24. for (size_t i = 0; i < sources.size(); i++) {
  25. Json::object source = sources[i].object_items();
  26. Json::object settings = source["settings"].object_items();
  27. string id = source["id"].string_value();
  28. #define DirectTranslation(before, after) \
  29. if (id == before) { \
  30. source["id"] = after; \
  31. source["versioned_id"] = obs_get_latest_input_type_id(after); \
  32. }
  33. #define ClearTranslation(before, after) \
  34. if (id == before) { \
  35. source["id"] = after; \
  36. source["settings"] = Json::object{}; \
  37. source["versioned_id"] = obs_get_latest_input_type_id(after); \
  38. }
  39. #ifdef __APPLE__
  40. DirectTranslation("text_gdiplus", "text_ft2_source");
  41. ClearTranslation("game_capture", "syphon-input");
  42. ClearTranslation("wasapi_input_capture", "coreaudio_input_capture");
  43. ClearTranslation("wasapi_output_capture", "coreaudio_output_capture");
  44. ClearTranslation("pulse_input_capture", "coreaudio_input_capture");
  45. ClearTranslation("pulse_output_capture", "coreaudio_output_capture");
  46. ClearTranslation("jack_output_capture", "coreaudio_output_capture");
  47. ClearTranslation("alsa_input_capture", "coreaudio_input_capture");
  48. ClearTranslation("dshow_input", "av_capture_input");
  49. ClearTranslation("v4l2_input", "av_capture_input");
  50. ClearTranslation("xcomposite_input", "window_capture");
  51. if (id == "monitor_capture") {
  52. if (settings["show_cursor"].is_null() && !settings["capture_cursor"].is_null()) {
  53. bool cursor = settings["capture_cursor"].bool_value();
  54. settings["show_cursor"] = cursor;
  55. }
  56. }
  57. DirectTranslation("xshm_input", "monitor_capture");
  58. #elif defined(_WIN32)
  59. DirectTranslation("text_ft2_source", "text_gdiplus");
  60. ClearTranslation("syphon-input", "game_capture");
  61. ClearTranslation("coreaudio_input_capture", "wasapi_input_capture");
  62. ClearTranslation("coreaudio_output_capture", "wasapi_output_capture");
  63. ClearTranslation("pulse_input_capture", "wasapi_input_capture");
  64. ClearTranslation("pulse_output_capture", "wasapi_output_capture");
  65. ClearTranslation("jack_output_capture", "wasapi_output_capture");
  66. ClearTranslation("alsa_input_capture", "wasapi_input_capture");
  67. ClearTranslation("av_capture_input", "dshow_input");
  68. ClearTranslation("v4l2_input", "dshow_input");
  69. ClearTranslation("xcomposite_input", "window_capture");
  70. if (id == "monitor_capture" || id == "xshm_input") {
  71. if (!settings["show_cursor"].is_null()) {
  72. bool cursor = settings["show_cursor"].bool_value();
  73. settings["capture_cursor"] = cursor;
  74. }
  75. source["id"] = "monitor_capture";
  76. }
  77. #else
  78. DirectTranslation("text_gdiplus", "text_ft2_source");
  79. ClearTranslation("coreaudio_input_capture", "pulse_input_capture");
  80. ClearTranslation("coreaudio_output_capture", "pulse_output_capture");
  81. ClearTranslation("wasapi_input_capture", "pulse_input_capture");
  82. ClearTranslation("wasapi_output_capture", "pulse_output_capture");
  83. ClearTranslation("av_capture_input", "v4l2_input");
  84. ClearTranslation("dshow_input", "v4l2_input");
  85. if (obs_get_nix_platform() == OBS_NIX_PLATFORM_X11_EGL) {
  86. ClearTranslation("game_capture", "xcomposite_input");
  87. ClearTranslation("window_capture", "xcomposite_input");
  88. } else {
  89. ClearTranslation("game_capture", "pipewire-screen-capture-source");
  90. ClearTranslation("window_capture", "pipewire-screen-capture-source");
  91. }
  92. if (id == "monitor_capture") {
  93. source["id"] = "xshm_input";
  94. if (settings["show_cursor"].is_null() && !settings["capture_cursor"].is_null()) {
  95. bool cursor = settings["capture_cursor"].bool_value();
  96. settings["show_cursor"] = cursor;
  97. }
  98. }
  99. #endif
  100. source["settings"] = settings;
  101. sources[i] = source;
  102. #undef DirectTranslation
  103. #undef ClearTranslation
  104. }
  105. out["sources"] = sources;
  106. res = out;
  107. }
  108. static string CheckPath(const string &path, const string &rootDir)
  109. {
  110. char root[512];
  111. *root = 0;
  112. size_t rootLen = os_get_abs_path(rootDir.c_str(), root, sizeof(root));
  113. char absPath[512];
  114. *absPath = 0;
  115. size_t len = os_get_abs_path((rootDir + path).c_str(), absPath, sizeof(absPath));
  116. if (len == 0)
  117. return path;
  118. if (strstr(absPath, root) != absPath)
  119. return path;
  120. if (*(absPath + rootLen) != QDir::separator().toLatin1())
  121. return path;
  122. return absPath;
  123. }
  124. void TranslatePaths(Json &res, const string &rootDir)
  125. {
  126. if (res.is_object()) {
  127. Json::object out = res.object_items();
  128. for (auto it = out.begin(); it != out.end(); it++) {
  129. Json val = it->second;
  130. if (val.is_string()) {
  131. if (val.string_value().rfind("./", 0) != 0)
  132. continue;
  133. out[it->first] = CheckPath(val.string_value(), rootDir);
  134. } else if (val.is_array() || val.is_object()) {
  135. TranslatePaths(val, rootDir);
  136. out[it->first] = val;
  137. }
  138. }
  139. res = out;
  140. } else if (res.is_array()) {
  141. Json::array out = res.array_items();
  142. for (size_t i = 0; i != out.size(); i++) {
  143. Json val = out[i];
  144. if (val.is_string()) {
  145. if (val.string_value().rfind("./", 0) != 0)
  146. continue;
  147. out[i] = CheckPath(val.string_value(), rootDir);
  148. } else if (val.is_array() || val.is_object()) {
  149. TranslatePaths(val, rootDir);
  150. out[i] = val;
  151. }
  152. }
  153. res = out;
  154. }
  155. }
  156. bool StudioImporter::Check(const string &path)
  157. {
  158. BPtr<char> file_data = os_quick_read_utf8_file(path.c_str());
  159. string err;
  160. Json collection = Json::parse(file_data, err);
  161. if (err != "")
  162. return false;
  163. if (collection.is_null())
  164. return false;
  165. if (collection["sources"].is_null())
  166. return false;
  167. if (collection["name"].is_null())
  168. return false;
  169. if (collection["current_scene"].is_null())
  170. return false;
  171. return true;
  172. }
  173. string StudioImporter::Name(const string &path)
  174. {
  175. BPtr<char> file_data = os_quick_read_utf8_file(path.c_str());
  176. string err;
  177. Json d = Json::parse(file_data, err);
  178. string name = d["name"].string_value();
  179. return name;
  180. }
  181. int StudioImporter::ImportScenes(const string &path, string &name, Json &res)
  182. {
  183. if (!os_file_exists(path.c_str()))
  184. return IMPORTER_FILE_NOT_FOUND;
  185. if (!Check(path.c_str()))
  186. return IMPORTER_FILE_NOT_RECOGNISED;
  187. BPtr<char> file_data = os_quick_read_utf8_file(path.c_str());
  188. string err;
  189. Json d = Json::parse(file_data, err);
  190. if (err != "")
  191. return IMPORTER_ERROR_DURING_CONVERSION;
  192. QDir dir(path.c_str());
  193. TranslateOSStudio(d);
  194. TranslatePaths(d, QDir::cleanPath(dir.filePath("..")).toStdString());
  195. Json::object obj = d.object_items();
  196. if (name != "")
  197. obj["name"] = name;
  198. else
  199. obj["name"] = "OBS Studio Import";
  200. res = obj;
  201. return IMPORTER_SUCCESS;
  202. }