Skip to content

Commit

Permalink
fix(📸): load video metadata on dedicated thread (#2473)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon committed Jun 12, 2024
1 parent 1443332 commit 7d391ae
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
7 changes: 4 additions & 3 deletions package/android/cpp/jni/JniPlatformContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ TSelf JniPlatformContext::initHybrid(jni::alias_ref<jhybridobject> jThis,

jni::global_ref<jobject>
JniPlatformContext::createVideo(const std::string &url) {
jni::Environment::ensureCurrentThreadIsAttached();

jni::ThreadScope ts; // Manages JNI thread attachment/detachment

// Get the JNI environment
Expand All @@ -85,14 +87,13 @@ JniPlatformContext::createVideo(const std::string &url) {
// Convert std::string to jstring
jstring jUrl = env->NewStringUTF(url.c_str());

// Get the method ID for the createVideo method
// Replace "Lcom/yourpackage/RNSkVideo;" with the actual return type
// descriptor
static auto method =
javaPart_->getClass()->getMethod<jobject(jstring)>("createVideo");

// Call the method and receive a local reference to the video object
auto videoObject = method(javaPart_.get(), jUrl);
env->DeleteLocalRef(jUrl);

// Clean up the jstring local reference
auto result = jni::make_global(videoObject);
return result;
Expand Down
31 changes: 28 additions & 3 deletions package/src/external/reanimated/useVideo.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { SharedValue, FrameInfo } from "react-native-reanimated";
import { useEffect, useMemo } from "react";
import {
type SharedValue,
type FrameInfo,
createWorkletRuntime,
runOnJS,
runOnRuntime,
} from "react-native-reanimated";
import { useEffect, useMemo, useState } from "react";

import { Skia } from "../../skia/Skia";
import type { SkImage, Video } from "../../skia/types";
Expand Down Expand Up @@ -53,11 +59,30 @@ const disposeVideo = (video: Video | null) => {
video?.dispose();
};

const runtime = createWorkletRuntime("video-metadata-runtime");

type VideoSource = string | null;

const useVideoLoading = (source: VideoSource) => {
const [video, setVideo] = useState<Video | null>(null);
const cb = (src: string) => {
"worklet";
const vid = Skia.Video(src);
runOnJS(setVideo)(vid);
};
useEffect(() => {
if (source) {
runOnRuntime(runtime, cb)(source);
}
}, [source]);
return video;
};

export const useVideo = (
source: string | null,
userOptions?: Partial<PlaybackOptions>
) => {
const video = useMemo(() => (source ? Skia.Video(source) : null), [source]);
const video = useVideoLoading(source);
const isPaused = useOption(userOptions?.paused ?? defaultOptions.paused);
const looping = useOption(userOptions?.looping ?? defaultOptions.looping);
const seek = useOption(userOptions?.seek ?? defaultOptions.seek);
Expand Down

0 comments on commit 7d391ae

Please sign in to comment.