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.
- package/LICENSE +21 -0
- package/README.md +949 -2
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/android/src/main/AndroidManifest.xml +9 -0
- package/android/src/main/cpp/CMakeLists.txt +41 -0
- package/android/src/main/cpp/alphavideogpu_jni.cpp +1168 -0
- package/android/src/main/cpp/astc_decomp.cpp +1550 -0
- package/android/src/main/cpp/astc_decomp.h +41 -0
- package/android/src/main/cpp/source_jni.cpp +242 -0
- package/android/src/main/cpp/source_jni.h +13 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuNative.java +43 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuReader.java +209 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuSource.java +328 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/AlphaVideoGpuView.java +2126 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/Fetcher.java +37 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/HttpFetcher.java +156 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/Ktx2Metadata.java +78 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/RangeSourceLink.java +54 -0
- package/android/src/main/java/dev/mediacache/alphavideo/gpu/ZstdSeekTable.java +120 -0
- package/android/src/rangesource/java/dev/mediacache/alphavideo/gpu/AppDataSource.java +50 -0
- package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuSource.h +63 -0
- package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuSource.mm +522 -0
- package/ios/Sources/AlphaVideoGPU/AlphaVideoGpuView.mm +2722 -0
- package/ios/Sources/AlphaVideoGPU/astc_decomp.cpp +1550 -0
- package/ios/Sources/AlphaVideoGPU/astc_decomp.h +41 -0
- package/ios/Sources/AlphaVideoGPU/include/AlphaVideoGPU.h +110 -0
- package/ios/Sources/AlphaVideoGPU/zstd_seek.h +250 -0
- package/package.json +77 -4
- package/react-native/android/build.gradle +92 -0
- package/react-native/android/src/main/AndroidManifest.xml +9 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuPackage.java +26 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManager.java +187 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/gpu/reactnative/PlayerEventForwarder.java +107 -0
- package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManagerSpec.java +23 -0
- package/react-native/android/src/norangesource/java/dev/mediacache/alphavideo/gpu/AppDataSource.java +15 -0
- package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/gpu/reactnative/AlphaVideoGpuViewManagerSpec.java +56 -0
- package/react-native/ios/RNAlphaVideoGpuViewComponentView.mm +176 -0
- package/react-native/ios/RNAlphaVideoGpuViewManager.mm +175 -0
- package/react-native/src/AlphaVideoGpuView.js +2 -0
- package/react-native/src/AlphaVideoGpuView.web.tsx +264 -0
- package/react-native/src/AlphaVideoGpuViewNativeComponent.ts +128 -0
- package/react-native/src/AlphaVideoGpuViewNativeComponent.web.ts +2 -0
- package/react-native/src/index.d.ts +95 -0
- package/react-native/src/index.js +162 -0
- package/react-native-alpha-video-gpu.podspec +37 -0
- package/react-native.config.js +12 -0
- package/third_party/licenses/Apache-2.0.txt +208 -0
- package/third_party/range-source/LICENSE +21 -0
- package/third_party/range-source/README.md +10 -0
- package/third_party/range-source/include/range_source.h +395 -0
- package/third_party/range-source/include/range_source_download.h +309 -0
- package/third_party/zstd/LICENSE +30 -0
- package/third_party/zstd/zstd.c +38717 -0
- 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
|
+
}
|
package/react-native/android/src/norangesource/java/dev/mediacache/alphavideo/gpu/AppDataSource.java
ADDED
|
@@ -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
|