vlc-video-plugin.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #ifdef _WIN32
  2. #include <windows.h>
  3. #endif
  4. #include <util/platform.h>
  5. #include "vlc-video-plugin.h"
  6. OBS_DECLARE_MODULE()
  7. OBS_MODULE_USE_DEFAULT_LOCALE("vlc-video", "en-US")
  8. MODULE_EXPORT const char *obs_module_description(void)
  9. {
  10. return "VLC playlist source";
  11. }
  12. /* libvlc core */
  13. LIBVLC_NEW libvlc_new_;
  14. LIBVLC_RELEASE libvlc_release_;
  15. LIBVLC_GET_VERSION libvlc_get_version_;
  16. LIBVLC_CLOCK libvlc_clock_;
  17. LIBVLC_EVENT_ATTACH libvlc_event_attach_;
  18. /* libvlc media */
  19. LIBVLC_MEDIA_NEW_PATH libvlc_media_new_path_;
  20. LIBVLC_MEDIA_NEW_LOCATION libvlc_media_new_location_;
  21. LIBVLC_MEDIA_ADD_OPTION libvlc_media_add_option_;
  22. LIBVLC_MEDIA_RELEASE libvlc_media_release_;
  23. LIBVLC_MEDIA_RETAIN libvlc_media_retain_;
  24. LIBVLC_MEDIA_GET_META libvlc_media_get_meta_;
  25. LIBVLC_MEDIA_TRACKS_GET libvlc_media_tracks_get_;
  26. LIBVLC_MEDIA_TRACKS_RELEASE libvlc_media_tracks_release_;
  27. /* libvlc media player */
  28. LIBVLC_MEDIA_PLAYER_NEW libvlc_media_player_new_;
  29. LIBVLC_MEDIA_PLAYER_NEW_FROM_MEDIA libvlc_media_player_new_from_media_;
  30. LIBVLC_MEDIA_PLAYER_RELEASE libvlc_media_player_release_;
  31. LIBVLC_VIDEO_SET_CALLBACKS libvlc_video_set_callbacks_;
  32. LIBVLC_VIDEO_SET_FORMAT_CALLBACKS libvlc_video_set_format_callbacks_;
  33. LIBVLC_AUDIO_SET_CALLBACKS libvlc_audio_set_callbacks_;
  34. LIBVLC_AUDIO_SET_FORMAT_CALLBACKS libvlc_audio_set_format_callbacks_;
  35. LIBVLC_MEDIA_PLAYER_PLAY libvlc_media_player_play_;
  36. LIBVLC_MEDIA_PLAYER_STOP libvlc_media_player_stop_;
  37. LIBVLC_MEDIA_PLAYER_GET_TIME libvlc_media_player_get_time_;
  38. LIBVLC_MEDIA_PLAYER_SET_TIME libvlc_media_player_set_time_;
  39. LIBVLC_VIDEO_GET_SIZE libvlc_video_get_size_;
  40. LIBVLC_MEDIA_PLAYER_EVENT_MANAGER libvlc_media_player_event_manager_;
  41. LIBVLC_MEDIA_PLAYER_GET_STATE libvlc_media_player_get_state_;
  42. LIBVLC_MEDIA_PLAYER_GET_LENGTH libvlc_media_player_get_length_;
  43. LIBVLC_MEDIA_PLAYER_GET_MEDIA libvlc_media_player_get_media_;
  44. /* libvlc media list */
  45. LIBVLC_MEDIA_LIST_NEW libvlc_media_list_new_;
  46. LIBVLC_MEDIA_LIST_RELEASE libvlc_media_list_release_;
  47. LIBVLC_MEDIA_LIST_ADD_MEDIA libvlc_media_list_add_media_;
  48. LIBVLC_MEDIA_LIST_LOCK libvlc_media_list_lock_;
  49. LIBVLC_MEDIA_LIST_UNLOCK libvlc_media_list_unlock_;
  50. LIBVLC_MEDIA_LIST_EVENT_MANAGER libvlc_media_list_event_manager_;
  51. /* libvlc media list player */
  52. LIBVLC_MEDIA_LIST_PLAYER_NEW libvlc_media_list_player_new_;
  53. LIBVLC_MEDIA_LIST_PLAYER_RELEASE libvlc_media_list_player_release_;
  54. LIBVLC_MEDIA_LIST_PLAYER_PLAY libvlc_media_list_player_play_;
  55. LIBVLC_MEDIA_LIST_PLAYER_PAUSE libvlc_media_list_player_pause_;
  56. LIBVLC_MEDIA_LIST_PLAYER_STOP libvlc_media_list_player_stop_;
  57. LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_PLAYER
  58. libvlc_media_list_player_set_media_player_;
  59. LIBVLC_MEDIA_LIST_PLAYER_SET_MEDIA_LIST libvlc_media_list_player_set_media_list_;
  60. LIBVLC_MEDIA_LIST_PLAYER_EVENT_MANAGER libvlc_media_list_player_event_manager_;
  61. LIBVLC_MEDIA_LIST_PLAYER_SET_PLAYBACK_MODE
  62. libvlc_media_list_player_set_playback_mode_;
  63. LIBVLC_MEDIA_LIST_PLAYER_NEXT libvlc_media_list_player_next_;
  64. LIBVLC_MEDIA_LIST_PLAYER_PREVIOUS libvlc_media_list_player_previous_;
  65. void *libvlc_module = NULL;
  66. #ifdef __APPLE__
  67. void *libvlc_core_module = NULL;
  68. #endif
  69. libvlc_instance_t *libvlc = NULL;
  70. uint64_t time_start = 0;
  71. static bool load_vlc_funcs(void)
  72. {
  73. #define LOAD_VLC_FUNC(func) \
  74. do { \
  75. func##_ = os_dlsym(libvlc_module, #func); \
  76. if (!func##_) { \
  77. blog(LOG_WARNING, \
  78. "[vlc-video]: Could not func VLC " \
  79. "function %s, VLC loading failed", \
  80. #func); \
  81. return false; \
  82. } \
  83. } while (false)
  84. /* libvlc core */
  85. LOAD_VLC_FUNC(libvlc_new);
  86. LOAD_VLC_FUNC(libvlc_release);
  87. LOAD_VLC_FUNC(libvlc_get_version);
  88. LOAD_VLC_FUNC(libvlc_clock);
  89. LOAD_VLC_FUNC(libvlc_event_attach);
  90. /* libvlc media */
  91. LOAD_VLC_FUNC(libvlc_media_new_path);
  92. LOAD_VLC_FUNC(libvlc_media_new_location);
  93. LOAD_VLC_FUNC(libvlc_media_add_option);
  94. LOAD_VLC_FUNC(libvlc_media_release);
  95. LOAD_VLC_FUNC(libvlc_media_retain);
  96. LOAD_VLC_FUNC(libvlc_media_get_meta);
  97. LOAD_VLC_FUNC(libvlc_media_tracks_get);
  98. LOAD_VLC_FUNC(libvlc_media_tracks_release);
  99. /* libvlc media player */
  100. LOAD_VLC_FUNC(libvlc_media_player_new);
  101. LOAD_VLC_FUNC(libvlc_media_player_new_from_media);
  102. LOAD_VLC_FUNC(libvlc_media_player_release);
  103. LOAD_VLC_FUNC(libvlc_video_set_callbacks);
  104. LOAD_VLC_FUNC(libvlc_video_set_format_callbacks);
  105. LOAD_VLC_FUNC(libvlc_audio_set_callbacks);
  106. LOAD_VLC_FUNC(libvlc_audio_set_format_callbacks);
  107. LOAD_VLC_FUNC(libvlc_media_player_play);
  108. LOAD_VLC_FUNC(libvlc_media_player_stop);
  109. LOAD_VLC_FUNC(libvlc_media_player_get_time);
  110. LOAD_VLC_FUNC(libvlc_media_player_set_time);
  111. LOAD_VLC_FUNC(libvlc_video_get_size);
  112. LOAD_VLC_FUNC(libvlc_media_player_event_manager);
  113. LOAD_VLC_FUNC(libvlc_media_player_get_state);
  114. LOAD_VLC_FUNC(libvlc_media_player_get_length);
  115. LOAD_VLC_FUNC(libvlc_media_player_get_media);
  116. /* libvlc media list */
  117. LOAD_VLC_FUNC(libvlc_media_list_new);
  118. LOAD_VLC_FUNC(libvlc_media_list_release);
  119. LOAD_VLC_FUNC(libvlc_media_list_add_media);
  120. LOAD_VLC_FUNC(libvlc_media_list_lock);
  121. LOAD_VLC_FUNC(libvlc_media_list_unlock);
  122. LOAD_VLC_FUNC(libvlc_media_list_event_manager);
  123. /* libvlc media list player */
  124. LOAD_VLC_FUNC(libvlc_media_list_player_new);
  125. LOAD_VLC_FUNC(libvlc_media_list_player_release);
  126. LOAD_VLC_FUNC(libvlc_media_list_player_play);
  127. LOAD_VLC_FUNC(libvlc_media_list_player_pause);
  128. LOAD_VLC_FUNC(libvlc_media_list_player_stop);
  129. LOAD_VLC_FUNC(libvlc_media_list_player_set_media_player);
  130. LOAD_VLC_FUNC(libvlc_media_list_player_set_media_list);
  131. LOAD_VLC_FUNC(libvlc_media_list_player_event_manager);
  132. LOAD_VLC_FUNC(libvlc_media_list_player_set_playback_mode);
  133. LOAD_VLC_FUNC(libvlc_media_list_player_next);
  134. LOAD_VLC_FUNC(libvlc_media_list_player_previous);
  135. return true;
  136. }
  137. static bool load_libvlc_module(void)
  138. {
  139. #ifdef _WIN32
  140. char *path_utf8 = NULL;
  141. wchar_t path[1024];
  142. LSTATUS status;
  143. DWORD size;
  144. HKEY key;
  145. memset(path, 0, 1024 * sizeof(wchar_t));
  146. status = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\VideoLAN\\VLC", &key);
  147. if (status != ERROR_SUCCESS)
  148. return false;
  149. size = 1024;
  150. status = RegQueryValueExW(key, L"InstallDir", NULL, NULL, (LPBYTE)path, &size);
  151. if (status == ERROR_SUCCESS) {
  152. wcscat(path, L"\\libvlc.dll");
  153. os_wcs_to_utf8_ptr(path, 0, &path_utf8);
  154. libvlc_module = os_dlopen(path_utf8);
  155. bfree(path_utf8);
  156. }
  157. RegCloseKey(key);
  158. #else
  159. /* According to otoolo -L, this is what libvlc.dylib wants. */
  160. #ifdef __APPLE__
  161. #define LIBVLC_DIR "/Applications/VLC.app/Contents/MacOS/"
  162. #define LIBVLC_CORE_FILE LIBVLC_DIR "lib/libvlccore.dylib"
  163. #define LIBVLC_FILE LIBVLC_DIR "lib/libvlc.5.dylib"
  164. setenv("VLC_PLUGIN_PATH", LIBVLC_DIR "plugins", false);
  165. libvlc_core_module = os_dlopen(LIBVLC_CORE_FILE);
  166. if (!libvlc_core_module)
  167. return false;
  168. #else
  169. #define LIBVLC_FILE "libvlc.so.5"
  170. #endif
  171. libvlc_module = os_dlopen(LIBVLC_FILE);
  172. #endif
  173. return libvlc_module != NULL;
  174. }
  175. extern struct obs_source_info vlc_source_info;
  176. bool load_libvlc(void)
  177. {
  178. if (libvlc)
  179. return true;
  180. libvlc = libvlc_new_(0, 0);
  181. if (!libvlc) {
  182. blog(LOG_INFO, "[vlc-video]: Couldn't create libvlc instance");
  183. return false;
  184. }
  185. time_start = (uint64_t)libvlc_clock_() * 1000ULL;
  186. return true;
  187. }
  188. bool obs_module_load(void)
  189. {
  190. if (!load_libvlc_module()) {
  191. blog(LOG_INFO, "[vlc-video]: Couldn't find VLC installation, "
  192. "VLC video source disabled");
  193. return true;
  194. }
  195. if (!load_vlc_funcs())
  196. return true;
  197. blog(LOG_INFO, "[vlc-video]: VLC %s found, VLC video source enabled", libvlc_get_version_());
  198. obs_register_source(&vlc_source_info);
  199. return true;
  200. }
  201. void obs_module_unload(void)
  202. {
  203. if (libvlc)
  204. libvlc_release_(libvlc);
  205. #ifdef __APPLE__
  206. if (libvlc_core_module)
  207. os_dlclose(libvlc_core_module);
  208. #endif
  209. if (libvlc_module)
  210. os_dlclose(libvlc_module);
  211. }