react-native-alpha-video-gpu 0.0.0-stage → 1.0.0

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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +949 -2
  3. package/THIRD_PARTY_NOTICES.md +14 -0
  4. package/android/src/main/AndroidManifest.xml +9 -0
  5. package/android/src/main/cpp/CMakeLists.txt +41 -0
  6. package/android/src/main/cpp/alphavideogpu_jni.cpp +1168 -0
  7. package/android/src/main/cpp/astc_decomp.cpp +1550 -0
  8. package/android/src/main/cpp/astc_decomp.h +41 -0
  9. package/android/src/main/cpp/source_jni.cpp +242 -0
  10. package/android/src/main/cpp/source_jni.h +13 -0
  11. package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuNative.java +43 -0
  12. package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuReader.java +209 -0
  13. package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuSource.java +328 -0
  14. package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuView.java +2126 -0
  15. package/android/src/main/java/dev/mediacache/alphavideo/gpu/Fetcher.java +37 -0
  16. package/android/src/main/java/dev/mediacache/alphavideo/gpu/HttpFetcher.java +156 -0
  17. package/android/src/main/java/dev/mediacache/alphavideo/gpu/Ktx2Metadata.java +78 -0
  18. package/android/src/main/java/dev/mediacache/alphavideo/gpu/RangeSourceLink.java +54 -0
  19. package/android/src/main/java/dev/mediacache/alphavideo/gpu/ZstdSeekTable.java +120 -0
  20. package/android/src/rangesource/java/dev/mediacache/alphavideo/gpu/AppDataSource.java +50 -0
  21. package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuSource.h +63 -0
  22. package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuSource.mm +522 -0
  23. package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuView.mm +2722 -0
  24. package/ios/Sources/AlphaVideoGPU/astc_decomp.cpp +1550 -0
  25. package/ios/Sources/AlphaVideoGPU/astc_decomp.h +41 -0
  26. package/ios/Sources/AlphaVideoGPU/include/AlphaVideoGPU.h +110 -0
  27. package/ios/Sources/AlphaVideoGPU/zstd_seek.h +250 -0
  28. package/package.json +77 -4
  29. package/react-native/android/build.gradle +92 -0
  30. package/react-native/android/src/main/AndroidManifest.xml +9 -0
  31. package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuPackage.java +26 -0
  32. package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManager.java +187 -0
  33. package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/PlayerEventForwarder.java +107 -0
  34. package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManagerSpec.java +23 -0
  35. package/react-native/android/src/norangesource/java/dev/mediacache/alphavideo/gpu/AppDataSource.java +15 -0
  36. package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManagerSpec.java +56 -0
  37. package/react-native/ios/RNAlphaVideoGpuViewComponentView.mm +176 -0
  38. package/react-native/ios/RNAlphaVideoGpuViewManager.mm +175 -0
  39. package/react-native/src/AlphaVideoGpuView.js +2 -0
  40. package/react-native/src/AlphaVideoGpuView.web.tsx +264 -0
  41. package/react-native/src/AlphaVideoGpuViewNativeComponent.ts +128 -0
  42. package/react-native/src/AlphaVideoGpuViewNativeComponent.web.ts +2 -0
  43. package/react-native/src/index.d.ts +95 -0
  44. package/react-native/src/index.js +162 -0
  45. package/react-native-alpha-video-gpu.podspec +37 -0
  46. package/react-native.config.js +12 -0
  47. package/third_party/licenses/Apache-2.0.txt +208 -0
  48. package/third_party/range-source/LICENSE +21 -0
  49. package/third_party/range-source/README.md +10 -0
  50. package/third_party/range-source/include/range_source.h +395 -0
  51. package/third_party/range-source/include/range_source_download.h +309 -0
  52. package/third_party/zstd/LICENSE +30 -0
  53. package/third_party/zstd/zstd.c +38717 -0
  54. package/third_party/zstd/zstd.h +2450 -0
@@ -0,0 +1,187 @@
1
+ package dev.mediacache.alphavideo.gpu.reactnative;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ import com.facebook.react.bridge.ReadableArray;
7
+ import com.facebook.react.bridge.ReadableMap;
8
+ import com.facebook.react.uimanager.ThemedReactContext;
9
+ import com.facebook.react.uimanager.annotations.ReactProp;
10
+
11
+ import dev.mediacache.alphavideo.gpu.AlphaVideoGpuView;
12
+
13
+ import java.util.LinkedHashMap;
14
+ import java.util.Map;
15
+
16
+ /** React Native view manager for {@link AlphaVideoGpuView}. */
17
+ public class AlphaVideoGpuViewManager extends AlphaVideoGpuViewManagerSpec<AlphaVideoGpuView> {
18
+
19
+ public static final String REACT_CLASS = "AlphaVideoGpuView";
20
+
21
+ @Override
22
+ @NonNull
23
+ public String getName() {
24
+ return REACT_CLASS;
25
+ }
26
+
27
+ @Override
28
+ @NonNull
29
+ protected AlphaVideoGpuView createViewInstance(@NonNull ThemedReactContext reactContext) {
30
+ AlphaVideoGpuView view = new AlphaVideoGpuView(reactContext);
31
+ view.setPlayerCallback(new PlayerEventForwarder(view));
32
+ return view;
33
+ }
34
+
35
+ @ReactProp(name = "source")
36
+ @Override
37
+ public void setSource(AlphaVideoGpuView view, @Nullable ReadableMap source) {
38
+ String sourceUri = null;
39
+ if (source != null && source.hasKey("uri") && !source.isNull("uri")) {
40
+ sourceUri = source.getString("uri");
41
+ }
42
+
43
+ // Adopt a cacheKey carried inside the source map before touching the source:
44
+ // setSource() starts the read that uses the key, and React gives no
45
+ // ordering guarantee between this setter and the standalone `cacheKey` one, so
46
+ // relying on that prop alone can store under the URL instead.
47
+ if (source != null && source.hasKey("cacheKey") && !source.isNull("cacheKey")) {
48
+ String sourceCacheKey = source.getString("cacheKey");
49
+ if (sourceCacheKey != null && !sourceCacheKey.isEmpty()) {
50
+ view.setCacheKey(sourceCacheKey);
51
+ }
52
+ }
53
+
54
+ Map<String, String> headers = new LinkedHashMap<>();
55
+ if (source != null && source.hasKey("headers") && !source.isNull("headers")) {
56
+ ReadableArray flat = source.getArray("headers");
57
+ for (int i = 0; flat != null && i + 1 < flat.size(); i += 2) {
58
+ headers.put(flat.getString(i), flat.getString(i + 1));
59
+ }
60
+ }
61
+ view.setHeaders(headers);
62
+ view.setDataSource(source != null && source.hasKey("dataSource") && !source.isNull("dataSource")
63
+ ? source.getString("dataSource") : null);
64
+ view.setSource(sourceUri == null || sourceUri.isEmpty() ? null : sourceUri);
65
+ }
66
+
67
+ @ReactProp(name = "autoPlay", defaultBoolean = true)
68
+ @Override
69
+ public void setAutoPlay(AlphaVideoGpuView view, boolean autoPlay) {
70
+ view.setAutoPlay(autoPlay);
71
+ }
72
+
73
+ @ReactProp(name = "loop", defaultBoolean = true)
74
+ @Override
75
+ public void setLoop(AlphaVideoGpuView view, boolean loop) {
76
+ view.setLoop(loop);
77
+ }
78
+
79
+ @ReactProp(name = "playbackSpeed", defaultFloat = 1.0f)
80
+ @Override
81
+ public void setPlaybackSpeed(AlphaVideoGpuView view, float speed) {
82
+ view.setPlaybackSpeed(speed);
83
+ }
84
+
85
+ @ReactProp(name = "cacheKey")
86
+ @Override
87
+ public void setCacheKey(AlphaVideoGpuView view, @Nullable String cacheKey) {
88
+ // Pass cacheKey directly to the View so it can use it for downloads
89
+ view.setCacheKey(cacheKey);
90
+ }
91
+
92
+ /** "auto" (default), "disk", "memory" or "none"; see AlphaVideoGpuView.setStorage. */
93
+ @ReactProp(name = "storage")
94
+ @Override
95
+ public void setStorage(AlphaVideoGpuView view, @Nullable String storage) {
96
+ view.setStorage(storage);
97
+ }
98
+
99
+ /** 0 for the default, 512 MB. */
100
+ @ReactProp(name = "maxStorageBytes", defaultDouble = 0)
101
+ @Override
102
+ public void setMaxStorageBytes(AlphaVideoGpuView view, double maxStorageBytes) {
103
+ view.setMaxStorageBytes((long) maxStorageBytes);
104
+ }
105
+
106
+ @ReactProp(name = "enableFrameEvents", defaultBoolean = false)
107
+ @Override
108
+ public void setEnableFrameEvents(AlphaVideoGpuView view, boolean enable) {
109
+ view.setEnableFrameEvents(enable);
110
+ }
111
+
112
+ @ReactProp(name = "paused", defaultBoolean = false)
113
+ @Override
114
+ public void setPaused(AlphaVideoGpuView view, boolean paused) {
115
+ view.setPaused(paused);
116
+ }
117
+
118
+ @ReactProp(name = "streamingPrefetchAhead", defaultInt = 8)
119
+ @Override
120
+ public void setStreamingPrefetchAhead(AlphaVideoGpuView view, int frames) {
121
+ view.setStreamingPrefetchAhead(frames);
122
+ }
123
+
124
+ /**
125
+ * Memory strategy for frame storage.
126
+ * - "vram" (default): Store frames in GPU VRAM. Best for many simultaneous players.
127
+ * - "ram": Store decoded frames in RAM, upload per-frame. Lower VRAM usage.
128
+ */
129
+ @ReactProp(name = "memoryStrategy")
130
+ @Override
131
+ public void setMemoryStrategy(AlphaVideoGpuView view, @Nullable String strategy) {
132
+ view.setMemoryStrategy(strategy != null ? strategy : "vram");
133
+ }
134
+
135
+ /**
136
+ * Enable streaming mode for texture array playback.
137
+ * When true (default): Use streaming decompression with ring buffer (constant memory usage).
138
+ * When false: Load all frames at once.
139
+ */
140
+ @ReactProp(name = "stream", defaultBoolean = true)
141
+ @Override
142
+ public void setStream(AlphaVideoGpuView view, boolean stream) {
143
+ view.setStream(stream);
144
+ }
145
+
146
+ @ReactProp(name = "verbose", defaultBoolean = false)
147
+ @Override
148
+ public void setVerbose(AlphaVideoGpuView view, boolean verbose) {
149
+ view.setVerbose(verbose);
150
+ }
151
+
152
+ @Override
153
+ public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
154
+ return PlayerEventForwarder.exportedEvents();
155
+ }
156
+
157
+ @Override
158
+ public void play(AlphaVideoGpuView view) {
159
+ view.play();
160
+ }
161
+
162
+ @Override
163
+ public void pause(AlphaVideoGpuView view) {
164
+ view.pause();
165
+ }
166
+
167
+ @Override
168
+ public void stop(AlphaVideoGpuView view) {
169
+ view.stop();
170
+ }
171
+
172
+ @Override
173
+ public void seekToFrame(AlphaVideoGpuView view, int frame) {
174
+ view.seekToFrame(frame);
175
+ }
176
+
177
+ @Override
178
+ public void seekToTime(AlphaVideoGpuView view, double seconds) {
179
+ view.seekToTime(seconds);
180
+ }
181
+
182
+ @Override
183
+ public void onDropViewInstance(@NonNull AlphaVideoGpuView view) {
184
+ super.onDropViewInstance(view);
185
+ view.destroy();
186
+ }
187
+ }
@@ -0,0 +1,107 @@
1
+ package dev.mediacache.alphavideo.gpu.reactnative;
2
+
3
+ import android.view.View;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.facebook.react.bridge.Arguments;
9
+ import com.facebook.react.bridge.ReactContext;
10
+ import com.facebook.react.bridge.WritableMap;
11
+ import com.facebook.react.common.MapBuilder;
12
+ import com.facebook.react.uimanager.UIManagerHelper;
13
+ import com.facebook.react.uimanager.events.Event;
14
+ import com.facebook.react.uimanager.events.EventDispatcher;
15
+
16
+ import dev.mediacache.alphavideo.gpu.AlphaVideoGpuView;
17
+
18
+ import java.util.Map;
19
+
20
+ /** Turns a player view's callbacks into React events on that view. */
21
+ final class PlayerEventForwarder implements AlphaVideoGpuView.PlayerCallback {
22
+
23
+ static Map<String, Object> exportedEvents() {
24
+ return MapBuilder.<String, Object>builder()
25
+ .put("onLoad", MapBuilder.of("registrationName", "onLoad"))
26
+ .put("onFrameUpdate", MapBuilder.of("registrationName", "onFrameUpdate"))
27
+ .put("onStateChange", MapBuilder.of("registrationName", "onStateChange"))
28
+ .put("onFinished", MapBuilder.of("registrationName", "onFinished"))
29
+ .put("onError", MapBuilder.of("registrationName", "onError"))
30
+ .build();
31
+ }
32
+
33
+ private final View view;
34
+
35
+ PlayerEventForwarder(View view) {
36
+ this.view = view;
37
+ }
38
+
39
+ @Override
40
+ public void onLoad(int width, int height, int frameCount, double frameRate) {
41
+ WritableMap event = Arguments.createMap();
42
+ event.putInt("width", width);
43
+ event.putInt("height", height);
44
+ event.putInt("frameCount", frameCount);
45
+ event.putDouble("frameRate", frameRate);
46
+ event.putDouble("duration", frameCount > 0 && frameRate > 0 ? frameCount / frameRate : 0);
47
+ send("onLoad", event);
48
+ }
49
+
50
+ @Override
51
+ public void onFrameUpdate(int frame, int totalFrames) {
52
+ WritableMap event = Arguments.createMap();
53
+ event.putInt("frame", frame);
54
+ event.putInt("totalFrames", totalFrames);
55
+ send("onFrameUpdate", event);
56
+ }
57
+
58
+ @Override
59
+ public void onStateChange(String state) {
60
+ WritableMap event = Arguments.createMap();
61
+ event.putString("state", state);
62
+ send("onStateChange", event);
63
+ }
64
+
65
+ @Override
66
+ public void onFinished() {
67
+ send("onFinished", Arguments.createMap());
68
+ }
69
+
70
+ @Override
71
+ public void onError(String error, @Nullable String code) {
72
+ WritableMap event = Arguments.createMap();
73
+ event.putString("error", error);
74
+ if (code != null) event.putString("code", code);
75
+ send("onError", event);
76
+ }
77
+
78
+ private void send(String eventName, WritableMap params) {
79
+ ReactContext context = (ReactContext) view.getContext();
80
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.getId());
81
+ if (dispatcher == null) return;
82
+ dispatcher.dispatchEvent(new PlayerEvent(UIManagerHelper.getSurfaceId(view), view.getId(), eventName, params));
83
+ }
84
+
85
+ private static final class PlayerEvent extends Event<PlayerEvent> {
86
+ private final String eventName;
87
+ private final WritableMap eventData;
88
+
89
+ PlayerEvent(int surfaceId, int viewTag, String eventName, WritableMap eventData) {
90
+ super(surfaceId, viewTag);
91
+ this.eventName = eventName;
92
+ this.eventData = eventData;
93
+ }
94
+
95
+ @NonNull
96
+ @Override
97
+ public String getEventName() {
98
+ return eventName;
99
+ }
100
+
101
+ @Nullable
102
+ @Override
103
+ protected WritableMap getEventData() {
104
+ return eventData;
105
+ }
106
+ }
107
+ }
@@ -0,0 +1,23 @@
1
+ package dev.mediacache.alphavideo.gpu.reactnative;
2
+
3
+ import android.view.View;
4
+
5
+ import androidx.annotation.Nullable;
6
+
7
+ import com.facebook.react.uimanager.SimpleViewManager;
8
+ import com.facebook.react.uimanager.ViewManagerDelegate;
9
+ import com.facebook.react.viewmanagers.AlphaVideoGpuViewManagerDelegate;
10
+ import com.facebook.react.viewmanagers.AlphaVideoGpuViewManagerInterface;
11
+
12
+ /** New architecture: props and commands arrive through the delegate generated from the codegen spec. */
13
+ public abstract class AlphaVideoGpuViewManagerSpec<T extends View> extends SimpleViewManager<T>
14
+ implements AlphaVideoGpuViewManagerInterface<T> {
15
+
16
+ private final ViewManagerDelegate<T> delegate = new AlphaVideoGpuViewManagerDelegate<>(this);
17
+
18
+ @Nullable
19
+ @Override
20
+ protected ViewManagerDelegate<T> getDelegate() {
21
+ return delegate;
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ package dev.mediacache.alphavideo.gpu;
2
+
3
+ /**
4
+ * Stands in for android/src/rangesource's AppDataSource when the app hasn't installed
5
+ * react-native-range-source, so the package builds without range-source's classes. Never
6
+ * reached: {@link RangeSourceLink#available()} is false without the add-on.
7
+ */
8
+ final class AppDataSource {
9
+
10
+ private AppDataSource() {}
11
+
12
+ static Fetcher create(String name) {
13
+ return null;
14
+ }
15
+ }
@@ -0,0 +1,56 @@
1
+ package dev.mediacache.alphavideo.gpu.reactnative;
2
+
3
+ import android.view.View;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.facebook.react.bridge.ReadableArray;
9
+ import com.facebook.react.bridge.ReadableMap;
10
+ import com.facebook.react.uimanager.SimpleViewManager;
11
+
12
+ /**
13
+ * Old architecture: the same methods as the interface codegen generates for the new one, so the
14
+ * manager compiles against either. Props arrive through its {@code @ReactProp} setters.
15
+ */
16
+ public abstract class AlphaVideoGpuViewManagerSpec<T extends View> extends SimpleViewManager<T> {
17
+
18
+ public abstract void setSource(T view, @Nullable ReadableMap value);
19
+ public abstract void setAutoPlay(T view, boolean value);
20
+ public abstract void setLoop(T view, boolean value);
21
+ public abstract void setPlaybackSpeed(T view, float value);
22
+ public abstract void setPaused(T view, boolean value);
23
+ public abstract void setCacheKey(T view, @Nullable String value);
24
+ public abstract void setStreamingPrefetchAhead(T view, int value);
25
+ public abstract void setMemoryStrategy(T view, @Nullable String value);
26
+ public abstract void setStream(T view, boolean value);
27
+ public abstract void setEnableFrameEvents(T view, boolean value);
28
+ public abstract void setVerbose(T view, boolean value);
29
+
30
+ public abstract void play(T view);
31
+ public abstract void pause(T view);
32
+ public abstract void stop(T view);
33
+ public abstract void seekToFrame(T view, int frame);
34
+ public abstract void seekToTime(T view, double seconds);
35
+
36
+ @Override
37
+ public void receiveCommand(@NonNull T view, String commandName, @Nullable ReadableArray args) {
38
+ switch (commandName) {
39
+ case "play":
40
+ play(view);
41
+ break;
42
+ case "pause":
43
+ pause(view);
44
+ break;
45
+ case "stop":
46
+ stop(view);
47
+ break;
48
+ case "seekToFrame":
49
+ if (args != null && args.size() > 0) seekToFrame(view, args.getInt(0));
50
+ break;
51
+ case "seekToTime":
52
+ if (args != null && args.size() > 0) seekToTime(view, args.getDouble(0));
53
+ break;
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,176 @@
1
+ //
2
+ // RNAlphaVideoGpuViewComponentView.mm
3
+ // Fabric component view for AlphaVideoGpuView (new architecture)
4
+ //
5
+
6
+ #ifdef RCT_NEW_ARCH_ENABLED
7
+
8
+ #import <React/RCTConversions.h>
9
+ #import <React/RCTViewComponentView.h>
10
+
11
+ #import <react/renderer/components/RNAlphaVideoGpuSpec/ComponentDescriptors.h>
12
+ #import <react/renderer/components/RNAlphaVideoGpuSpec/EventEmitters.h>
13
+ #import <react/renderer/components/RNAlphaVideoGpuSpec/Props.h>
14
+ #import <react/renderer/components/RNAlphaVideoGpuSpec/RCTComponentViewHelpers.h>
15
+
16
+ #import "AlphaVideoGPU.h"
17
+
18
+ using namespace facebook::react;
19
+
20
+ @interface RNAlphaVideoGpuViewComponentView : RCTViewComponentView <RCTAlphaVideoGpuViewViewProtocol>
21
+ @end
22
+
23
+ @implementation RNAlphaVideoGpuViewComponentView {
24
+ AlphaVideoGpuView *_player;
25
+ }
26
+
27
+ + (ComponentDescriptorProvider)componentDescriptorProvider
28
+ {
29
+ return concreteComponentDescriptorProvider<AlphaVideoGpuViewComponentDescriptor>();
30
+ }
31
+
32
+ // A player holds its frames and GPU resources, so each mount gets a new one.
33
+ + (BOOL)shouldBeRecycled
34
+ {
35
+ return NO;
36
+ }
37
+
38
+ - (instancetype)initWithFrame:(CGRect)frame
39
+ {
40
+ if (self = [super initWithFrame:frame]) {
41
+ static const auto defaultProps = std::make_shared<const AlphaVideoGpuViewProps>();
42
+ _props = defaultProps;
43
+ [self createPlayer];
44
+ }
45
+ return self;
46
+ }
47
+
48
+ - (void)createPlayer
49
+ {
50
+ _player = [[AlphaVideoGpuView alloc] initWithFrame:self.bounds];
51
+ [self forwardEvents];
52
+ self.contentView = _player;
53
+ }
54
+
55
+ // Older React Native versions ignore shouldBeRecycled and recycle every component view.
56
+ - (void)prepareForRecycle
57
+ {
58
+ [super prepareForRecycle];
59
+ [_player cleanup];
60
+ [self createPlayer];
61
+ }
62
+
63
+ - (void)invalidate
64
+ {
65
+ [_player cleanup];
66
+ }
67
+
68
+ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
69
+ {
70
+ const auto &newProps = *std::static_pointer_cast<const AlphaVideoGpuViewProps>(props);
71
+
72
+ _player.autoPlay = newProps.autoPlay;
73
+ _player.loop = newProps.loop;
74
+ _player.playbackSpeed = newProps.playbackSpeed;
75
+ _player.playbackPaused = newProps.paused;
76
+ _player.enableFrameEvents = newProps.enableFrameEvents;
77
+ _player.stream = newProps.stream;
78
+ _player.streamingPrefetchAhead = newProps.streamingPrefetchAhead;
79
+ _player.memoryStrategy = RCTNSStringFromString(toString(newProps.memoryStrategy));
80
+ _player.verbose = newProps.verbose;
81
+ _player.storage = RCTNSStringFromString(toString(newProps.storage));
82
+ _player.maxStorageBytes = (int64_t)newProps.maxStorageBytes;
83
+
84
+ // Setting source starts the load, which reads every other prop, the cache key included.
85
+ NSString *cacheKey = RCTNSStringFromStringNilIfEmpty(newProps.cacheKey)
86
+ ?: RCTNSStringFromStringNilIfEmpty(newProps.source.cacheKey);
87
+ _player.cacheKey = cacheKey;
88
+ NSMutableDictionary<NSString *, NSString *> *headers = [NSMutableDictionary dictionary];
89
+ for (size_t i = 0; i + 1 < newProps.source.headers.size(); i += 2) {
90
+ headers[RCTNSStringFromString(newProps.source.headers[i])] = RCTNSStringFromString(newProps.source.headers[i + 1]);
91
+ }
92
+ _player.headers = headers;
93
+ _player.dataSource = RCTNSStringFromStringNilIfEmpty(newProps.source.dataSource);
94
+ _player.source = RCTNSStringFromStringNilIfEmpty(newProps.source.uri);
95
+
96
+ [super updateProps:props oldProps:oldProps];
97
+ }
98
+
99
+ - (std::shared_ptr<const AlphaVideoGpuViewEventEmitter>)playerEventEmitter
100
+ {
101
+ return std::static_pointer_cast<const AlphaVideoGpuViewEventEmitter>(_eventEmitter);
102
+ }
103
+
104
+ - (void)forwardEvents
105
+ {
106
+ __weak RNAlphaVideoGpuViewComponentView *weakSelf = self;
107
+ _player.onLoad = ^(NSInteger width, NSInteger height, NSInteger frameCount, CGFloat frameRate) {
108
+ auto emitter = [weakSelf playerEventEmitter];
109
+ if (!emitter) return;
110
+ AlphaVideoGpuViewEventEmitter::OnLoad event;
111
+ event.width = (int)width;
112
+ event.height = (int)height;
113
+ event.frameCount = (int)frameCount;
114
+ event.frameRate = frameRate;
115
+ event.duration = frameCount > 0 && frameRate > 0 ? frameCount / frameRate : 0;
116
+ emitter->onLoad(event);
117
+ };
118
+ _player.onFrameUpdate = ^(NSInteger frame, NSInteger totalFrames) {
119
+ auto emitter = [weakSelf playerEventEmitter];
120
+ if (emitter) emitter->onFrameUpdate({.frame = (int)frame, .totalFrames = (int)totalFrames});
121
+ };
122
+ _player.onStateChange = ^(NSString *state) {
123
+ auto emitter = [weakSelf playerEventEmitter];
124
+ if (emitter) emitter->onStateChange({.state = RCTStringFromNSString(state)});
125
+ };
126
+ _player.onFinished = ^{
127
+ auto emitter = [weakSelf playerEventEmitter];
128
+ if (emitter) emitter->onFinished({});
129
+ };
130
+ _player.onError = ^(NSString *error, NSString *code) {
131
+ auto emitter = [weakSelf playerEventEmitter];
132
+ if (emitter) emitter->onError({.error = RCTStringFromNSString(error), .code = RCTStringFromNSString(code ?: @"")});
133
+ };
134
+ }
135
+
136
+ #pragma mark - Commands
137
+
138
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
139
+ {
140
+ RCTAlphaVideoGpuViewHandleCommand(self, commandName, args);
141
+ }
142
+
143
+ - (void)play
144
+ {
145
+ [_player play];
146
+ }
147
+
148
+ - (void)pause
149
+ {
150
+ [_player pause];
151
+ }
152
+
153
+ - (void)stop
154
+ {
155
+ [_player stop];
156
+ }
157
+
158
+ - (void)seekToFrame:(NSInteger)frame
159
+ {
160
+ [_player seekToFrame:frame];
161
+ }
162
+
163
+ - (void)seekToTime:(double)seconds
164
+ {
165
+ [_player seekToTime:seconds];
166
+ }
167
+
168
+ @end
169
+
170
+ // Older React Native versions look the class up by this name instead of codegenConfig.ios.componentProvider.
171
+ extern "C" Class<RCTComponentViewProtocol> AlphaVideoGpuViewCls(void)
172
+ {
173
+ return RNAlphaVideoGpuViewComponentView.class;
174
+ }
175
+
176
+ #endif