react-native-skia 3.0.3 → 3.0.5

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 (210) hide show
  1. package/android/CMakeLists.txt +0 -2
  2. package/android/build.gradle +15 -7
  3. package/android/cpp/jni/JniPlatformContext.cpp +0 -24
  4. package/android/cpp/jni/include/JniPlatformContext.h +0 -2
  5. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +0 -140
  6. package/android/src/main/java/com/reactnative/skia/BackingViewKind.java +24 -0
  7. package/android/src/main/java/com/reactnative/skia/FrameScheduler.java +104 -0
  8. package/android/src/main/java/com/reactnative/skia/PlatformContext.java +0 -5
  9. package/android/src/main/java/com/reactnative/skia/SkiaView.java +55 -44
  10. package/android/src/test/java/com/reactnative/skia/FrameSchedulerTest.java +186 -0
  11. package/apple/RNSkApplePlatformContext.h +0 -10
  12. package/apple/RNSkApplePlatformContext.mm +0 -182
  13. package/cpp/api/JsiGPUTexture.h +48 -0
  14. package/cpp/api/JsiSkApi.h +1 -16
  15. package/cpp/api/JsiSkImage.h +0 -12
  16. package/cpp/api/JsiSkImageFactory.h +36 -57
  17. package/cpp/api/JsiSkSurface.h +3 -10
  18. package/cpp/api/JsiSkSurfaceFactory.h +13 -18
  19. package/cpp/rnskia/RNDawnContext.h +5 -113
  20. package/cpp/rnskia/RNDawnUtils.h +33 -0
  21. package/cpp/rnskia/RNSkPlatformContext.h +0 -54
  22. package/cpp/rnskia/RNSkView.h +10 -7
  23. package/lib/commonjs/external/reanimated/index.d.ts +0 -1
  24. package/lib/commonjs/external/reanimated/index.js +0 -11
  25. package/lib/commonjs/external/reanimated/index.js.map +1 -1
  26. package/lib/commonjs/mock/index.js +1 -2
  27. package/lib/commonjs/mock/index.js.map +1 -1
  28. package/lib/commonjs/skia/types/GPUTexture.d.ts +11 -0
  29. package/lib/commonjs/skia/types/GPUTexture.js +2 -0
  30. package/lib/commonjs/skia/types/GPUTexture.js.map +1 -0
  31. package/lib/commonjs/skia/types/Image/Image.d.ts +0 -10
  32. package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
  33. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +25 -48
  34. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  35. package/lib/commonjs/skia/types/Skia.d.ts +0 -4
  36. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  37. package/lib/commonjs/skia/types/Surface/Surface.d.ts +3 -14
  38. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  39. package/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +10 -9
  40. package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
  41. package/lib/commonjs/skia/types/index.d.ts +1 -2
  42. package/lib/commonjs/skia/types/index.js +11 -22
  43. package/lib/commonjs/skia/types/index.js.map +1 -1
  44. package/lib/commonjs/skia/web/JsiSkImage.d.ts +0 -1
  45. package/lib/commonjs/skia/web/JsiSkImage.js +0 -4
  46. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  47. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +4 -5
  48. package/lib/commonjs/skia/web/JsiSkImageFactory.js +6 -10
  49. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  50. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +0 -1
  51. package/lib/commonjs/skia/web/JsiSkSurface.js +0 -4
  52. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  53. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.d.ts +2 -2
  54. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js +1 -1
  55. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  56. package/lib/commonjs/skia/web/JsiSkia.js +0 -4
  57. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  58. package/lib/module/external/reanimated/index.d.ts +0 -1
  59. package/lib/module/external/reanimated/index.js +0 -1
  60. package/lib/module/external/reanimated/index.js.map +1 -1
  61. package/lib/module/mock/index.js +1 -2
  62. package/lib/module/mock/index.js.map +1 -1
  63. package/lib/module/skia/types/GPUTexture.d.ts +11 -0
  64. package/lib/module/skia/types/GPUTexture.js +2 -0
  65. package/lib/module/skia/types/GPUTexture.js.map +1 -0
  66. package/lib/module/skia/types/Image/Image.d.ts +0 -10
  67. package/lib/module/skia/types/Image/Image.js.map +1 -1
  68. package/lib/module/skia/types/Image/ImageFactory.d.ts +25 -48
  69. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  70. package/lib/module/skia/types/Skia.d.ts +0 -4
  71. package/lib/module/skia/types/Skia.js.map +1 -1
  72. package/lib/module/skia/types/Surface/Surface.d.ts +3 -14
  73. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  74. package/lib/module/skia/types/Surface/SurfaceFactory.d.ts +10 -9
  75. package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
  76. package/lib/module/skia/types/index.d.ts +1 -2
  77. package/lib/module/skia/types/index.js +1 -2
  78. package/lib/module/skia/types/index.js.map +1 -1
  79. package/lib/module/skia/web/JsiSkImage.d.ts +0 -1
  80. package/lib/module/skia/web/JsiSkImage.js +0 -4
  81. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  82. package/lib/module/skia/web/JsiSkImageFactory.d.ts +4 -5
  83. package/lib/module/skia/web/JsiSkImageFactory.js +6 -10
  84. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  85. package/lib/module/skia/web/JsiSkSurface.d.ts +0 -1
  86. package/lib/module/skia/web/JsiSkSurface.js +0 -4
  87. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  88. package/lib/module/skia/web/JsiSkSurfaceFactory.d.ts +2 -2
  89. package/lib/module/skia/web/JsiSkSurfaceFactory.js +1 -1
  90. package/lib/module/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  91. package/lib/module/skia/web/JsiSkia.js +0 -4
  92. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  93. package/lib/typescript/src/external/reanimated/index.d.ts +0 -1
  94. package/lib/typescript/src/skia/types/GPUTexture.d.ts +11 -0
  95. package/lib/typescript/src/skia/types/Image/Image.d.ts +0 -10
  96. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +25 -48
  97. package/lib/typescript/src/skia/types/Skia.d.ts +0 -4
  98. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +3 -14
  99. package/lib/typescript/src/skia/types/Surface/SurfaceFactory.d.ts +10 -9
  100. package/lib/typescript/src/skia/types/index.d.ts +1 -2
  101. package/lib/typescript/src/skia/web/JsiSkImage.d.ts +0 -1
  102. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +4 -5
  103. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +0 -1
  104. package/lib/typescript/src/skia/web/JsiSkSurfaceFactory.d.ts +2 -2
  105. package/package.json +1 -1
  106. package/src/external/reanimated/index.ts +0 -1
  107. package/src/mock/index.ts +0 -1
  108. package/src/skia/types/GPUTexture.ts +9 -0
  109. package/src/skia/types/Image/Image.ts +0 -11
  110. package/src/skia/types/Image/ImageFactory.ts +25 -55
  111. package/src/skia/types/Skia.ts +0 -4
  112. package/src/skia/types/Surface/Surface.ts +3 -15
  113. package/src/skia/types/Surface/SurfaceFactory.ts +11 -9
  114. package/src/skia/types/index.ts +1 -2
  115. package/src/skia/web/JsiSkImage.ts +0 -5
  116. package/src/skia/web/JsiSkImageFactory.ts +16 -16
  117. package/src/skia/web/JsiSkSurface.ts +0 -5
  118. package/src/skia/web/JsiSkSurfaceFactory.ts +2 -2
  119. package/src/skia/web/JsiSkia.ts +0 -4
  120. package/android/cpp/rnskia-android/AHardwareBufferUtils.cpp +0 -31
  121. package/android/cpp/rnskia-android/AHardwareBufferUtils.h +0 -13
  122. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +0 -200
  123. package/android/cpp/rnskia-android/RNSkAndroidVideo.h +0 -44
  124. package/android/src/main/java/com/reactnative/skia/RNSkVideo.java +0 -320
  125. package/apple/RNSkAppleVideo.h +0 -78
  126. package/apple/RNSkAppleVideo.mm +0 -292
  127. package/cpp/api/JsiNativeBuffer.h +0 -56
  128. package/cpp/api/JsiTextureInfo.h +0 -53
  129. package/cpp/api/JsiVideo.h +0 -101
  130. package/cpp/rnskia/RNSkVideo.h +0 -31
  131. package/lib/commonjs/external/reanimated/useVideo.d.ts +0 -21
  132. package/lib/commonjs/external/reanimated/useVideo.js +0 -150
  133. package/lib/commonjs/external/reanimated/useVideo.js.map +0 -1
  134. package/lib/commonjs/external/reanimated/useVideoLoading.d.ts +0 -4
  135. package/lib/commonjs/external/reanimated/useVideoLoading.js +0 -40
  136. package/lib/commonjs/external/reanimated/useVideoLoading.js.map +0 -1
  137. package/lib/commonjs/external/reanimated/useVideoLoading.web.d.ts +0 -4
  138. package/lib/commonjs/external/reanimated/useVideoLoading.web.js +0 -20
  139. package/lib/commonjs/external/reanimated/useVideoLoading.web.js.map +0 -1
  140. package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.d.ts +0 -29
  141. package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js +0 -15
  142. package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js.map +0 -1
  143. package/lib/commonjs/skia/types/NativeBuffer/index.d.ts +0 -1
  144. package/lib/commonjs/skia/types/NativeBuffer/index.js +0 -17
  145. package/lib/commonjs/skia/types/NativeBuffer/index.js.map +0 -1
  146. package/lib/commonjs/skia/types/Video/Video.d.ts +0 -20
  147. package/lib/commonjs/skia/types/Video/Video.js +0 -6
  148. package/lib/commonjs/skia/types/Video/Video.js.map +0 -1
  149. package/lib/commonjs/skia/types/Video/index.d.ts +0 -1
  150. package/lib/commonjs/skia/types/Video/index.js +0 -17
  151. package/lib/commonjs/skia/types/Video/index.js.map +0 -1
  152. package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.d.ts +0 -9
  153. package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.js +0 -30
  154. package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.js.map +0 -1
  155. package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.d.ts +0 -9
  156. package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.js +0 -48
  157. package/lib/commonjs/skia/web/JsiSkNativeBufferFactory.js.map +0 -1
  158. package/lib/commonjs/skia/web/JsiVideo.d.ts +0 -28
  159. package/lib/commonjs/skia/web/JsiVideo.js +0 -96
  160. package/lib/commonjs/skia/web/JsiVideo.js.map +0 -1
  161. package/lib/module/external/reanimated/useVideo.d.ts +0 -21
  162. package/lib/module/external/reanimated/useVideo.js +0 -142
  163. package/lib/module/external/reanimated/useVideo.js.map +0 -1
  164. package/lib/module/external/reanimated/useVideoLoading.d.ts +0 -4
  165. package/lib/module/external/reanimated/useVideoLoading.js +0 -33
  166. package/lib/module/external/reanimated/useVideoLoading.js.map +0 -1
  167. package/lib/module/external/reanimated/useVideoLoading.web.d.ts +0 -4
  168. package/lib/module/external/reanimated/useVideoLoading.web.js +0 -13
  169. package/lib/module/external/reanimated/useVideoLoading.web.js.map +0 -1
  170. package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.d.ts +0 -29
  171. package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js +0 -5
  172. package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js.map +0 -1
  173. package/lib/module/skia/types/NativeBuffer/index.d.ts +0 -1
  174. package/lib/module/skia/types/NativeBuffer/index.js +0 -2
  175. package/lib/module/skia/types/NativeBuffer/index.js.map +0 -1
  176. package/lib/module/skia/types/Video/Video.d.ts +0 -20
  177. package/lib/module/skia/types/Video/Video.js +0 -2
  178. package/lib/module/skia/types/Video/Video.js.map +0 -1
  179. package/lib/module/skia/types/Video/index.d.ts +0 -1
  180. package/lib/module/skia/types/Video/index.js +0 -2
  181. package/lib/module/skia/types/Video/index.js.map +0 -1
  182. package/lib/module/skia/web/CanvasKitWebGLBufferImpl.d.ts +0 -9
  183. package/lib/module/skia/web/CanvasKitWebGLBufferImpl.js +0 -23
  184. package/lib/module/skia/web/CanvasKitWebGLBufferImpl.js.map +0 -1
  185. package/lib/module/skia/web/JsiSkNativeBufferFactory.d.ts +0 -9
  186. package/lib/module/skia/web/JsiSkNativeBufferFactory.js +0 -41
  187. package/lib/module/skia/web/JsiSkNativeBufferFactory.js.map +0 -1
  188. package/lib/module/skia/web/JsiVideo.d.ts +0 -28
  189. package/lib/module/skia/web/JsiVideo.js +0 -88
  190. package/lib/module/skia/web/JsiVideo.js.map +0 -1
  191. package/lib/typescript/src/external/reanimated/useVideo.d.ts +0 -21
  192. package/lib/typescript/src/external/reanimated/useVideoLoading.d.ts +0 -4
  193. package/lib/typescript/src/external/reanimated/useVideoLoading.web.d.ts +0 -4
  194. package/lib/typescript/src/skia/types/NativeBuffer/NativeBufferFactory.d.ts +0 -29
  195. package/lib/typescript/src/skia/types/NativeBuffer/index.d.ts +0 -1
  196. package/lib/typescript/src/skia/types/Video/Video.d.ts +0 -20
  197. package/lib/typescript/src/skia/types/Video/index.d.ts +0 -1
  198. package/lib/typescript/src/skia/web/CanvasKitWebGLBufferImpl.d.ts +0 -9
  199. package/lib/typescript/src/skia/web/JsiSkNativeBufferFactory.d.ts +0 -9
  200. package/lib/typescript/src/skia/web/JsiVideo.d.ts +0 -28
  201. package/src/external/reanimated/useVideo.ts +0 -161
  202. package/src/external/reanimated/useVideoLoading.ts +0 -39
  203. package/src/external/reanimated/useVideoLoading.web.ts +0 -17
  204. package/src/skia/types/NativeBuffer/NativeBufferFactory.ts +0 -52
  205. package/src/skia/types/NativeBuffer/index.ts +0 -1
  206. package/src/skia/types/Video/Video.ts +0 -19
  207. package/src/skia/types/Video/index.ts +0 -1
  208. package/src/skia/web/CanvasKitWebGLBufferImpl.ts +0 -25
  209. package/src/skia/web/JsiSkNativeBufferFactory.ts +0 -51
  210. package/src/skia/web/JsiVideo.ts +0 -113
@@ -1,200 +0,0 @@
1
- #include <memory>
2
- #include <string>
3
-
4
- #if __ANDROID_API__ >= 26
5
- #include <android/hardware_buffer_jni.h>
6
- #endif
7
-
8
- #include "RNSkLog.h"
9
-
10
- #include "RNDawnContext.h"
11
-
12
- #pragma clang diagnostic push
13
- #pragma clang diagnostic ignored "-Wdocumentation"
14
-
15
- #include "include/core/SkImage.h"
16
- #include "include/core/SkSize.h"
17
-
18
- #pragma clang diagnostic pop
19
-
20
- #include "RNSkAndroidVideo.h"
21
-
22
- namespace RNSkia {
23
-
24
- namespace jsi = facebook::jsi;
25
- namespace jni = facebook::jni;
26
-
27
- RNSkAndroidVideo::RNSkAndroidVideo(jni::global_ref<jobject> jniVideo)
28
- : _jniVideo(jniVideo) {
29
- #if __ANDROID_API__ < 26
30
- throw std::runtime_error("Skia Videos are only support on API 26 and above");
31
- #endif
32
- }
33
-
34
- RNSkAndroidVideo::~RNSkAndroidVideo() = default;
35
-
36
- sk_sp<SkImage> RNSkAndroidVideo::nextImage(double *timeStamp) {
37
- #if __ANDROID_API__ >= 26
38
- JNIEnv *env = facebook::jni::Environment::current();
39
- // Get the Java class and method ID
40
- jclass cls = env->GetObjectClass(_jniVideo.get());
41
- jmethodID mid =
42
- env->GetMethodID(cls, "nextImage", "()Landroid/hardware/HardwareBuffer;");
43
- if (mid == nullptr) {
44
- // Method not found, handle error
45
- RNSkLogger::logToConsole("nextImage method not found");
46
- return nullptr;
47
- }
48
- // Call the Java method
49
- jobject jHardwareBuffer = env->CallObjectMethod(_jniVideo.get(), mid);
50
- if (jHardwareBuffer == nullptr) {
51
- RNSkLogger::logToConsole("Buffer not found");
52
- // Null return, handle error
53
- return nullptr;
54
- }
55
- // Convert jobject to AHardwareBuffer
56
- AHardwareBuffer *buffer =
57
- AHardwareBuffer_fromHardwareBuffer(env, jHardwareBuffer);
58
- return DawnContext::getInstance().MakeImageFromBuffer(buffer);
59
- #else
60
- return nullptr;
61
- #endif
62
- }
63
-
64
- double RNSkAndroidVideo::duration() {
65
- JNIEnv *env = facebook::jni::Environment::current();
66
- jclass cls = env->GetObjectClass(_jniVideo.get());
67
- jmethodID mid = env->GetMethodID(cls, "getDuration", "()D");
68
- if (!mid) {
69
- RNSkLogger::logToConsole("getDuration method not found");
70
- return 0.0;
71
- }
72
- return env->CallDoubleMethod(_jniVideo.get(), mid);
73
- }
74
-
75
- double RNSkAndroidVideo::framerate() {
76
- JNIEnv *env = facebook::jni::Environment::current();
77
- jclass cls = env->GetObjectClass(_jniVideo.get());
78
- jmethodID mid = env->GetMethodID(cls, "getFrameRate", "()D");
79
- if (!mid) {
80
- RNSkLogger::logToConsole("getFrameRate method not found");
81
- return 0.0;
82
- }
83
- return env->CallDoubleMethod(_jniVideo.get(), mid);
84
- }
85
-
86
- void RNSkAndroidVideo::seek(double timestamp) {
87
- JNIEnv *env = facebook::jni::Environment::current();
88
- jclass cls = env->GetObjectClass(_jniVideo.get());
89
- jmethodID mid = env->GetMethodID(cls, "seek", "(D)V");
90
- if (!mid) {
91
- RNSkLogger::logToConsole("seek method not found");
92
- return;
93
- }
94
- env->CallVoidMethod(_jniVideo.get(), mid, static_cast<jdouble>(timestamp));
95
- }
96
-
97
- float RNSkAndroidVideo::getRotationInDegrees() {
98
- JNIEnv *env = facebook::jni::Environment::current();
99
- jclass cls = env->GetObjectClass(_jniVideo.get());
100
- jmethodID mid = env->GetMethodID(cls, "getRotationDegrees", "()I");
101
- if (!mid) {
102
- RNSkLogger::logToConsole("getRotationDegrees method not found");
103
- return 0;
104
- }
105
- auto rotation = env->CallIntMethod(_jniVideo.get(), mid);
106
- return static_cast<float>(rotation);
107
- }
108
-
109
- SkISize RNSkAndroidVideo::getSize() {
110
- JNIEnv *env = facebook::jni::Environment::current();
111
- jclass cls = env->GetObjectClass(_jniVideo.get());
112
- jmethodID mid =
113
- env->GetMethodID(cls, "getSize", "()Landroid/graphics/Point;");
114
- if (!mid) {
115
- RNSkLogger::logToConsole("getSize method not found");
116
- return SkISize::Make(0, 0);
117
- }
118
- jobject jPoint = env->CallObjectMethod(_jniVideo.get(), mid);
119
- jclass pointCls = env->GetObjectClass(jPoint);
120
-
121
- jfieldID xFid = env->GetFieldID(pointCls, "x", "I");
122
- jfieldID yFid = env->GetFieldID(pointCls, "y", "I");
123
- if (!xFid || !yFid) {
124
- RNSkLogger::logToConsole("Point class fields not found");
125
- return SkISize::Make(0, 0);
126
- }
127
-
128
- jint width = env->GetIntField(jPoint, xFid);
129
- jint height = env->GetIntField(jPoint, yFid);
130
-
131
- return SkISize::Make(width, height);
132
- }
133
-
134
- void RNSkAndroidVideo::play() {
135
- JNIEnv *env = facebook::jni::Environment::current();
136
- jclass cls = env->GetObjectClass(_jniVideo.get());
137
- jmethodID mid = env->GetMethodID(cls, "play", "()V");
138
- if (!mid) {
139
- RNSkLogger::logToConsole("play method not found");
140
- return;
141
- }
142
- env->CallVoidMethod(_jniVideo.get(), mid);
143
- }
144
-
145
- void RNSkAndroidVideo::pause() {
146
- JNIEnv *env = facebook::jni::Environment::current();
147
- jclass cls = env->GetObjectClass(_jniVideo.get());
148
- jmethodID mid = env->GetMethodID(cls, "pause", "()V");
149
- if (!mid) {
150
- RNSkLogger::logToConsole("pause method not found");
151
- return;
152
- }
153
- env->CallVoidMethod(_jniVideo.get(), mid);
154
- }
155
-
156
- void RNSkAndroidVideo::setVolume(float volume) {
157
- JNIEnv *env = facebook::jni::Environment::current();
158
- jclass cls = env->GetObjectClass(_jniVideo.get());
159
- jmethodID mid = env->GetMethodID(cls, "setVolume", "(F)V");
160
- if (!mid) {
161
- RNSkLogger::logToConsole("setVolume method not found");
162
- return;
163
- }
164
- env->CallVoidMethod(_jniVideo.get(), mid, volume);
165
- }
166
-
167
- double RNSkAndroidVideo::currentTime() {
168
- JNIEnv *env = facebook::jni::Environment::current();
169
- jclass cls = env->GetObjectClass(_jniVideo.get());
170
- jmethodID mid = env->GetMethodID(cls, "getCurrentTime", "()D");
171
- if (!mid) {
172
- RNSkLogger::logToConsole("getCurrentTime method not found");
173
- return 0.0;
174
- }
175
- return env->CallDoubleMethod(_jniVideo.get(), mid);
176
- }
177
-
178
- void RNSkAndroidVideo::setLooping(bool looping) {
179
- JNIEnv *env = facebook::jni::Environment::current();
180
- jclass cls = env->GetObjectClass(_jniVideo.get());
181
- jmethodID mid = env->GetMethodID(cls, "setLooping", "(Z)V");
182
- if (!mid) {
183
- RNSkLogger::logToConsole("setLooping method not found");
184
- return;
185
- }
186
- env->CallVoidMethod(_jniVideo.get(), mid, static_cast<jboolean>(looping));
187
- }
188
-
189
- bool RNSkAndroidVideo::isPlaying() {
190
- JNIEnv *env = facebook::jni::Environment::current();
191
- jclass cls = env->GetObjectClass(_jniVideo.get());
192
- jmethodID mid = env->GetMethodID(cls, "getIsPlaying", "()Z");
193
- if (!mid) {
194
- RNSkLogger::logToConsole("getIsPlaying method not found");
195
- return false;
196
- }
197
- return env->CallBooleanMethod(_jniVideo.get(), mid);
198
- }
199
-
200
- } // namespace RNSkia
@@ -1,44 +0,0 @@
1
- #pragma once
2
-
3
- #include <string>
4
-
5
- #include <fbjni/fbjni.h>
6
- #include <jni.h>
7
- #include <jsi/jsi.h>
8
-
9
- #pragma clang diagnostic push
10
- #pragma clang diagnostic ignored "-Wdocumentation"
11
-
12
- #include "include/core/SkImage.h"
13
-
14
- #pragma clang diagnostic pop
15
-
16
- #include "RNSkVideo.h"
17
-
18
- namespace RNSkia {
19
-
20
- namespace jsi = facebook::jsi;
21
- namespace jni = facebook::jni;
22
-
23
- class RNSkAndroidVideo : public RNSkVideo {
24
- private:
25
- jni::global_ref<jobject> _jniVideo;
26
-
27
- public:
28
- explicit RNSkAndroidVideo(jni::global_ref<jobject> jniVideo);
29
- ~RNSkAndroidVideo() override;
30
- sk_sp<SkImage> nextImage(double *timeStamp = nullptr) override;
31
- double duration() override;
32
- double framerate() override;
33
- double currentTime() override;
34
- void seek(double timestamp) override;
35
- float getRotationInDegrees() override;
36
- SkISize getSize() override;
37
- void play() override;
38
- void pause() override;
39
- void setVolume(float volume) override;
40
- void setLooping(bool looping) override;
41
- bool isPlaying() override;
42
- };
43
-
44
- } // namespace RNSkia
@@ -1,320 +0,0 @@
1
- package com.reactnative.skia;
2
-
3
- import android.content.Context;
4
- import android.graphics.ImageFormat;
5
- import android.hardware.HardwareBuffer;
6
- import android.media.AudioAttributes;
7
- import android.media.AudioManager;
8
- import android.media.MediaCodec;
9
- import android.media.MediaExtractor;
10
- import android.media.MediaFormat;
11
- import android.media.MediaPlayer;
12
- import android.media.MediaSync;
13
- import android.media.Image;
14
- import android.media.ImageReader;
15
- import android.net.Uri;
16
- import android.os.Build;
17
- import android.view.Surface;
18
- import android.graphics.Point;
19
-
20
- import androidx.annotation.RequiresApi;
21
-
22
- import com.facebook.jni.annotations.DoNotStrip;
23
-
24
- import java.io.IOException;
25
- import java.nio.ByteBuffer;
26
-
27
- public class RNSkVideo {
28
- private final Uri uri;
29
- private final Context context;
30
-
31
- private MediaExtractor extractor;
32
- private MediaCodec decoder;
33
- private ImageReader imageReader;
34
- private Surface outputSurface;
35
- private MediaPlayer mediaPlayer;
36
- private MediaSync mediaSync;
37
- private double durationMs;
38
- private double frameRate;
39
- private int rotationDegrees = 0;
40
- private int width = 0;
41
- private int height = 0;
42
-
43
- private boolean isPlaying = false;
44
- private boolean isLooping = false;
45
- private boolean isPrepared = false;
46
- private boolean playWhenReady = false;
47
- private HardwareBuffer lastBuffer = null;
48
- private boolean pendingSeek = false;
49
- private double lastFrameTimeMs = 0;
50
-
51
- RNSkVideo(Context context, String localUri) {
52
- this.uri = Uri.parse(localUri);
53
- this.context = context;
54
- this.initializeReader();
55
- }
56
-
57
- private void initializeReader() {
58
- extractor = new MediaExtractor();
59
- try {
60
- extractor.setDataSource(context, this.uri, null);
61
- int trackIndex = selectVideoTrack(extractor);
62
- if (trackIndex < 0) {
63
- throw new RuntimeException("No video track found in " + this.uri);
64
- }
65
- extractor.selectTrack(trackIndex);
66
- MediaFormat format = extractor.getTrackFormat(trackIndex);
67
-
68
- // Initialize MediaPlayer
69
- mediaPlayer = new MediaPlayer();
70
- mediaPlayer.setDataSource(context, uri);
71
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
72
- mediaPlayer.setOnPreparedListener(mp -> {
73
- durationMs = mp.getDuration();
74
- isPrepared = true;
75
- // Apply looping setting
76
- mp.setLooping(isLooping);
77
- // Start playing if play() was called before preparation completed
78
- if (playWhenReady) {
79
- mp.start();
80
- isPlaying = true;
81
- playWhenReady = false;
82
- }
83
- });
84
- // Note: When setLooping(true) is used, this listener won't fire as
85
- // MediaPlayer handles looping automatically. This only handles the
86
- // non-looping case to update playback state.
87
- mediaPlayer.setOnCompletionListener(mp -> {
88
- isPlaying = false;
89
- });
90
- mediaPlayer.prepareAsync();
91
-
92
- // Retrieve and store video properties
93
- if (format.containsKey(MediaFormat.KEY_DURATION)) {
94
- durationMs = format.getLong(MediaFormat.KEY_DURATION) / 1000; // Convert microseconds to milliseconds
95
- }
96
- if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
97
- frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
98
- }
99
- if (format.containsKey(MediaFormat.KEY_ROTATION)) {
100
- rotationDegrees = format.getInteger(MediaFormat.KEY_ROTATION);
101
- }
102
- width = format.getInteger(MediaFormat.KEY_WIDTH);
103
- height = format.getInteger(MediaFormat.KEY_HEIGHT);
104
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
105
- imageReader = ImageReader.newInstance(
106
- width,
107
- height,
108
- ImageFormat.PRIVATE,
109
- 2,
110
- HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
111
- );
112
- } else {
113
- imageReader = ImageReader.newInstance(width, height,
114
- ImageFormat.PRIVATE, 2);
115
- }
116
- outputSurface = imageReader.getSurface();
117
-
118
- // Create a decoder for the format
119
- String mime = format.getString(MediaFormat.KEY_MIME);
120
- decoder = MediaCodec.createDecoderByType(mime);
121
-
122
- // Note: Use an output Surface for rendering if necessary, otherwise handle buffers
123
- decoder.configure(format, outputSurface, null, 0);
124
- decoder.start();
125
- } catch (IOException e) {
126
- throw new RuntimeException("Failed to initialize extractor or decoder", e);
127
- }
128
- }
129
-
130
- @DoNotStrip
131
- public double getDuration() {
132
- return durationMs;
133
- }
134
-
135
- @DoNotStrip
136
- public double getFrameRate() {
137
- return frameRate;
138
- }
139
-
140
- @DoNotStrip
141
- public int getRotationDegrees() {
142
- return rotationDegrees;
143
- }
144
-
145
- @DoNotStrip
146
- public HardwareBuffer nextImage() {
147
- // If paused and not seeking, return cached buffer
148
- if (!isPlaying && !pendingSeek && lastBuffer != null) {
149
- return lastBuffer;
150
- }
151
-
152
- // Decode new frame if needed
153
- if (!decoderOutputAvailable()) {
154
- decodeFrame();
155
- }
156
-
157
- Image image = imageReader.acquireLatestImage();
158
- if (image != null) {
159
- HardwareBuffer hardwareBuffer = image.getHardwareBuffer();
160
- image.close(); // Make sure to close the Image to free up the buffer
161
- // Cache the buffer
162
- lastBuffer = hardwareBuffer;
163
- // Clear pending seek flag after getting frame
164
- if (pendingSeek) {
165
- pendingSeek = false;
166
- }
167
- return hardwareBuffer;
168
- }
169
- // Return cached buffer if no new frame available
170
- return lastBuffer;
171
- }
172
-
173
- @DoNotStrip
174
- public void seek(double timestamp) {
175
- long timestampUs = (long)(timestamp * 1000); // Convert milliseconds to microseconds
176
-
177
- extractor.seekTo(timestampUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
178
- if (mediaPlayer != null && isPrepared) {
179
- int timestampMs = (int) timestamp; // Convert to milliseconds
180
- mediaPlayer.seekTo(timestampMs, MediaPlayer.SEEK_CLOSEST);
181
- }
182
-
183
- // Flush the codec to reset internal state and prepare for new position
184
- if (decoder != null) {
185
- decoder.flush();
186
- }
187
-
188
- // Signal that we need to decode a new frame (for seek while paused)
189
- pendingSeek = true;
190
- // Decode a frame immediately so it's ready
191
- decodeFrame();
192
- }
193
-
194
- @DoNotStrip
195
- public Point getSize() {
196
- return new Point(width, height);
197
- }
198
-
199
- private int selectVideoTrack(MediaExtractor extractor) {
200
- int numTracks = extractor.getTrackCount();
201
- for (int i = 0; i < numTracks; i++) {
202
- MediaFormat format = extractor.getTrackFormat(i);
203
- String mime = format.getString(MediaFormat.KEY_MIME);
204
- if (mime.startsWith("video/")) {
205
- return i;
206
- }
207
- }
208
- return -1;
209
- }
210
-
211
- private boolean decoderOutputAvailable() {
212
- MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
213
- int outputBufferId = decoder.dequeueOutputBuffer(info, 0);
214
- if (outputBufferId >= 0) {
215
- // If a buffer is available, release it immediately back since we are just checking
216
- decoder.releaseOutputBuffer(outputBufferId, true);
217
- return true;
218
- }
219
- return false;
220
- }
221
-
222
- private void decodeFrame() {
223
- MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
224
- long timeoutUs = 10000;
225
- boolean isEOS = false;
226
-
227
- int inputBufferId = decoder.dequeueInputBuffer(timeoutUs);
228
- if (inputBufferId >= 0) {
229
- ByteBuffer inputBuffer = decoder.getInputBuffer(inputBufferId);
230
- int sampleSize = extractor.readSampleData(inputBuffer, 0);
231
- if (sampleSize < 0) {
232
- // End of stream, make sure to send this information to the decoder
233
- decoder.queueInputBuffer(inputBufferId, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
234
- isEOS = true;
235
- } else {
236
- long presentationTimeUs = extractor.getSampleTime();
237
- decoder.queueInputBuffer(inputBufferId, 0, sampleSize, presentationTimeUs, 0);
238
- extractor.advance();
239
- }
240
- }
241
-
242
- int outputBufferId = decoder.dequeueOutputBuffer(info, timeoutUs);
243
- if (outputBufferId >= 0) {
244
- // Store the frame's presentation timestamp for accurate time reporting
245
- lastFrameTimeMs = info.presentationTimeUs / 1000.0;
246
- // If we have a valid buffer, release it to make it available to the ImageReader's surface
247
- decoder.releaseOutputBuffer(outputBufferId, true);
248
-
249
- if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
250
- isEOS = true;
251
- }
252
- }
253
- }
254
-
255
- @DoNotStrip
256
- public void play() {
257
- if (mediaPlayer == null || isPlaying) {
258
- return;
259
- }
260
- if (isPrepared) {
261
- mediaPlayer.start();
262
- isPlaying = true;
263
- } else {
264
- // Queue the play request for when preparation completes
265
- playWhenReady = true;
266
- }
267
- }
268
-
269
- @DoNotStrip
270
- public void pause() {
271
- playWhenReady = false;
272
- if (mediaPlayer != null && isPlaying) {
273
- mediaPlayer.pause();
274
- isPlaying = false;
275
- }
276
- }
277
-
278
- @DoNotStrip
279
- public void setVolume(float volume) {
280
- if (mediaPlayer != null) {
281
- mediaPlayer.setVolume(volume, volume);
282
- }
283
- }
284
-
285
- @DoNotStrip
286
- public double getCurrentTime() {
287
- // Return the timestamp of the last decoded frame for accurate synchronization
288
- return lastFrameTimeMs;
289
- }
290
-
291
- @DoNotStrip
292
- public void setLooping(boolean looping) {
293
- isLooping = looping;
294
- if (mediaPlayer != null && isPrepared) {
295
- mediaPlayer.setLooping(looping);
296
- }
297
- }
298
-
299
- @DoNotStrip
300
- public boolean getIsPlaying() {
301
- return isPlaying;
302
- }
303
-
304
- public void release() {
305
- lastBuffer = null;
306
- if (mediaPlayer != null) {
307
- mediaPlayer.release();
308
- mediaPlayer = null;
309
- }
310
- if (decoder != null) {
311
- decoder.stop();
312
- decoder.release();
313
- decoder = null;
314
- }
315
- if (extractor != null) {
316
- extractor.release();
317
- extractor = null;
318
- }
319
- }
320
- }
@@ -1,78 +0,0 @@
1
- #pragma once
2
-
3
- #include <string>
4
-
5
- #include <AVFoundation/AVFoundation.h>
6
- #include <CoreVideo/CoreVideo.h>
7
-
8
- #pragma clang diagnostic push
9
- #pragma clang diagnostic ignored "-Wdocumentation"
10
-
11
- #include "include/core/SkImage.h"
12
- #include "include/core/SkSize.h"
13
-
14
- #pragma clang diagnostic pop
15
-
16
- #include "RNSkPlatformContext.h"
17
- #include "RNSkVideo.h"
18
-
19
- namespace RNSkia {
20
-
21
- class RNSkAppleVideo : public RNSkVideo {
22
- private:
23
- std::string _url;
24
- AVPlayer *_player = nullptr;
25
- AVPlayerItem *_playerItem = nullptr;
26
- AVPlayerItemVideoOutput *_videoOutput = nullptr;
27
- #if !TARGET_OS_OSX
28
- CADisplayLink *_displayLink = nullptr;
29
- id _displayLinkTarget = nullptr;
30
- #else
31
- CVDisplayLinkRef _displayLink = nullptr;
32
- bool _displayLinkRunning = false;
33
- #endif
34
- RNSkPlatformContext *_context;
35
- double _duration = 0;
36
- double _framerate = 0;
37
- float _videoWidth = 0;
38
- float _videoHeight = 0;
39
- CGAffineTransform _preferredTransform;
40
- bool _isPlaying = false;
41
- bool _isLooping = false;
42
- bool _waitingForFrame = false;
43
- id _endObserver = nullptr;
44
- sk_sp<SkImage> _lastImage = nullptr;
45
- double _lastFrameTimeMs = 0;
46
- void setupPlayer();
47
- void setupDisplayLink();
48
- NSDictionary *getOutputSettings();
49
- #if TARGET_OS_OSX
50
- void startDisplayLink();
51
- void stopDisplayLink();
52
- static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,
53
- const CVTimeStamp *now,
54
- const CVTimeStamp *outputTime,
55
- CVOptionFlags flagsIn,
56
- CVOptionFlags *flagsOut, void *context);
57
- #endif
58
-
59
- public:
60
- void onDisplayLink();
61
- void expectFrame();
62
- RNSkAppleVideo(std::string url, RNSkPlatformContext *context);
63
- ~RNSkAppleVideo();
64
- sk_sp<SkImage> nextImage(double *timeStamp = nullptr) override;
65
- double duration() override;
66
- double framerate() override;
67
- double currentTime() override;
68
- void seek(double timestamp) override;
69
- void play() override;
70
- void pause() override;
71
- float getRotationInDegrees() override;
72
- SkISize getSize() override;
73
- void setVolume(float volume) override;
74
- void setLooping(bool looping) override;
75
- bool isPlaying() override;
76
- };
77
-
78
- } // namespace RNSkia