Cleanup source handling

This commit is contained in:
2026-04-10 19:20:45 +02:00
parent 7a5f495b39
commit fd40915bc9
26 changed files with 415 additions and 450 deletions
@@ -2,7 +2,7 @@ package dev.zoriya.omni
import android.net.Uri
import com.margelo.nitro.NitroModules
import com.margelo.nitro.omni.HybridOmniPlayerPropsSpec
import com.margelo.nitro.omni.Source
import com.margelo.nitro.omni.HybridOmniPlayerSpec
import com.margelo.nitro.omni.PlayerStatus
import com.margelo.nitro.omni.Rendition
@@ -17,7 +17,7 @@ class OmniPlayer() : HybridOmniPlayerSpec() {
val vlc = LibVLC(NitroModules.applicationContext ?: throw Error("No Context available!"))
val player = MediaPlayer(vlc)
var source: HybridOmniPlayerPropsSpec by deferredObservable { _, _, new ->
override var source: Source by deferredObservable { _, _, new ->
val src = new.src.firstOrNull()?.uri ?: return@deferredObservable
player.media = Media(vlc, Uri.parse(src))
new.startTime?.let { start ->
+13
View File
@@ -18,6 +18,19 @@
"recommended": true,
"style": {
"noNonNullAssertion": "off"
},
"correctness": {
"useExhaustiveDependencies": {
"level": "warn",
"options": {
"hooks": [
{
"name": "useLazyRef",
"stableResult": true
}
]
}
}
}
}
},
-2
View File
@@ -33,13 +33,11 @@ target_sources(
# Autolinking Setup
../nitrogen/generated/android/OmniOnLoad.cpp
# Shared Nitrogen C++ sources
../nitrogen/generated/shared/c++/HybridOmniPlayerPropsSpec.cpp
../nitrogen/generated/shared/c++/HybridOmniPlayerSpec.cpp
../nitrogen/generated/shared/c++/HybridOmniPlayerFactorySpec.cpp
../nitrogen/generated/shared/c++/HybridOmniViewSpec.cpp
../nitrogen/generated/shared/c++/views/HybridOmniViewComponent.cpp
# Android-specific Nitrogen C++ sources
../nitrogen/generated/android/c++/JHybridOmniPlayerPropsSpec.cpp
../nitrogen/generated/android/c++/JHybridOmniPlayerSpec.cpp
../nitrogen/generated/android/c++/JHybridOmniPlayerFactorySpec.cpp
../nitrogen/generated/android/c++/JHybridOmniViewSpec.cpp
-2
View File
@@ -15,7 +15,6 @@
#include <fbjni/fbjni.h>
#include <NitroModules/HybridObjectRegistry.hpp>
#include "JHybridOmniPlayerPropsSpec.hpp"
#include "JHybridOmniPlayerSpec.hpp"
#include "JHybridOmniPlayerFactorySpec.hpp"
#include "JHybridOmniViewSpec.hpp"
@@ -52,7 +51,6 @@ void registerAllNatives() {
using namespace margelo::nitro::omni;
// Register native JNI methods
margelo::nitro::omni::JHybridOmniPlayerPropsSpec::CxxPart::registerNatives();
margelo::nitro::omni::JHybridOmniPlayerSpec::CxxPart::registerNatives();
margelo::nitro::omni::JHybridOmniPlayerFactorySpec::CxxPart::registerNatives();
margelo::nitro::omni::JHybridOmniViewSpec::CxxPart::registerNatives();
@@ -9,14 +9,34 @@
// Forward declaration of `HybridOmniPlayerSpec` to properly resolve imports.
namespace margelo::nitro::omni { class HybridOmniPlayerSpec; }
// Forward declaration of `HybridOmniPlayerPropsSpec` to properly resolve imports.
namespace margelo::nitro::omni { class HybridOmniPlayerPropsSpec; }
// Forward declaration of `Source` to properly resolve imports.
namespace margelo::nitro::omni { struct Source; }
// Forward declaration of `VideoSrc` to properly resolve imports.
namespace margelo::nitro::omni { struct VideoSrc; }
// Forward declaration of `Subtitle` to properly resolve imports.
namespace margelo::nitro::omni { struct Subtitle; }
// Forward declaration of `Metadata` to properly resolve imports.
namespace margelo::nitro::omni { struct Metadata; }
// Forward declaration of `MixAudioMode` to properly resolve imports.
namespace margelo::nitro::omni { enum class MixAudioMode; }
#include <memory>
#include "HybridOmniPlayerSpec.hpp"
#include "JHybridOmniPlayerSpec.hpp"
#include "HybridOmniPlayerPropsSpec.hpp"
#include "JHybridOmniPlayerPropsSpec.hpp"
#include "Source.hpp"
#include "JSource.hpp"
#include "VideoSrc.hpp"
#include <vector>
#include "JVideoSrc.hpp"
#include <string>
#include <optional>
#include <unordered_map>
#include "Subtitle.hpp"
#include "JSubtitle.hpp"
#include "Metadata.hpp"
#include "JMetadata.hpp"
#include "MixAudioMode.hpp"
#include "JMixAudioMode.hpp"
namespace margelo::nitro::omni {
@@ -51,9 +71,9 @@ namespace margelo::nitro::omni {
// Methods
std::shared_ptr<HybridOmniPlayerSpec> JHybridOmniPlayerFactorySpec::createPlayer(const std::shared_ptr<HybridOmniPlayerPropsSpec>& props) {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JHybridOmniPlayerSpec::JavaPart>(jni::alias_ref<JHybridOmniPlayerPropsSpec::JavaPart> /* props */)>("createPlayer");
auto __result = method(_javaPart, std::dynamic_pointer_cast<JHybridOmniPlayerPropsSpec>(props)->getJavaPart());
std::shared_ptr<HybridOmniPlayerSpec> JHybridOmniPlayerFactorySpec::createPlayer(const Source& props) {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JHybridOmniPlayerSpec::JavaPart>(jni::alias_ref<JSource> /* props */)>("createPlayer");
auto __result = method(_javaPart, JSource::fromCpp(props));
return __result->getJHybridOmniPlayerSpec();
}
@@ -54,7 +54,7 @@ namespace margelo::nitro::omni {
public:
// Methods
std::shared_ptr<HybridOmniPlayerSpec> createPlayer(const std::shared_ptr<HybridOmniPlayerPropsSpec>& props) override;
std::shared_ptr<HybridOmniPlayerSpec> createPlayer(const Source& props) override;
private:
jni::global_ref<JHybridOmniPlayerFactorySpec::JavaPart> _javaPart;
@@ -1,147 +0,0 @@
///
/// JHybridOmniPlayerPropsSpec.cpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#include "JHybridOmniPlayerPropsSpec.hpp"
// Forward declaration of `VideoSrc` to properly resolve imports.
namespace margelo::nitro::omni { struct VideoSrc; }
// Forward declaration of `Subtitle` to properly resolve imports.
namespace margelo::nitro::omni { struct Subtitle; }
// Forward declaration of `Metadata` to properly resolve imports.
namespace margelo::nitro::omni { struct Metadata; }
// Forward declaration of `MixAudioMode` to properly resolve imports.
namespace margelo::nitro::omni { enum class MixAudioMode; }
#include "VideoSrc.hpp"
#include <vector>
#include "JVideoSrc.hpp"
#include <string>
#include <optional>
#include <unordered_map>
#include "Subtitle.hpp"
#include "JSubtitle.hpp"
#include "Metadata.hpp"
#include "JMetadata.hpp"
#include "MixAudioMode.hpp"
#include "JMixAudioMode.hpp"
namespace margelo::nitro::omni {
std::shared_ptr<JHybridOmniPlayerPropsSpec> JHybridOmniPlayerPropsSpec::JavaPart::getJHybridOmniPlayerPropsSpec() {
auto hybridObject = JHybridObject::JavaPart::getJHybridObject();
auto castHybridObject = std::dynamic_pointer_cast<JHybridOmniPlayerPropsSpec>(hybridObject);
if (castHybridObject == nullptr) [[unlikely]] {
throw std::runtime_error("Failed to downcast JHybridObject to JHybridOmniPlayerPropsSpec!");
}
return castHybridObject;
}
jni::local_ref<JHybridOmniPlayerPropsSpec::CxxPart::jhybriddata> JHybridOmniPlayerPropsSpec::CxxPart::initHybrid(jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
}
std::shared_ptr<JHybridObject> JHybridOmniPlayerPropsSpec::CxxPart::createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) {
auto castJavaPart = jni::dynamic_ref_cast<JHybridOmniPlayerPropsSpec::JavaPart>(javaPart);
if (castJavaPart == nullptr) [[unlikely]] {
throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridOmniPlayerPropsSpec::JavaPart!");
}
return std::make_shared<JHybridOmniPlayerPropsSpec>(castJavaPart);
}
void JHybridOmniPlayerPropsSpec::CxxPart::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", JHybridOmniPlayerPropsSpec::CxxPart::initHybrid),
});
}
// Properties
std::vector<VideoSrc> JHybridOmniPlayerPropsSpec::getSrc() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JVideoSrc>>()>("getSrc");
auto __result = method(_javaPart);
return [&]() {
size_t __size = __result->size();
std::vector<VideoSrc> __vector;
__vector.reserve(__size);
for (size_t __i = 0; __i < __size; __i++) {
auto __element = __result->getElement(__i);
__vector.push_back(__element->toCpp());
}
return __vector;
}();
}
void JHybridOmniPlayerPropsSpec::setSrc(const std::vector<VideoSrc>& src) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JVideoSrc>> /* src */)>("setSrc");
method(_javaPart, [&]() {
size_t __size = src.size();
jni::local_ref<jni::JArrayClass<JVideoSrc>> __array = jni::JArrayClass<JVideoSrc>::newArray(__size);
for (size_t __i = 0; __i < __size; __i++) {
const auto& __element = src[__i];
auto __elementJni = JVideoSrc::fromCpp(__element);
__array->setElement(__i, *__elementJni);
}
return __array;
}());
}
std::optional<double> JHybridOmniPlayerPropsSpec::getStartTime() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getStartTime");
auto __result = method(_javaPart);
return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
}
void JHybridOmniPlayerPropsSpec::setStartTime(std::optional<double> startTime) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* startTime */)>("setStartTime");
method(_javaPart, startTime.has_value() ? jni::JDouble::valueOf(startTime.value()) : nullptr);
}
std::vector<Subtitle> JHybridOmniPlayerPropsSpec::getSubtitles() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JSubtitle>>()>("getSubtitles");
auto __result = method(_javaPart);
return [&]() {
size_t __size = __result->size();
std::vector<Subtitle> __vector;
__vector.reserve(__size);
for (size_t __i = 0; __i < __size; __i++) {
auto __element = __result->getElement(__i);
__vector.push_back(__element->toCpp());
}
return __vector;
}();
}
void JHybridOmniPlayerPropsSpec::setSubtitles(const std::vector<Subtitle>& subtitles) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JSubtitle>> /* subtitles */)>("setSubtitles");
method(_javaPart, [&]() {
size_t __size = subtitles.size();
jni::local_ref<jni::JArrayClass<JSubtitle>> __array = jni::JArrayClass<JSubtitle>::newArray(__size);
for (size_t __i = 0; __i < __size; __i++) {
const auto& __element = subtitles[__i];
auto __elementJni = JSubtitle::fromCpp(__element);
__array->setElement(__i, *__elementJni);
}
return __array;
}());
}
std::optional<Metadata> JHybridOmniPlayerPropsSpec::getMetadata() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JMetadata>()>("getMetadata");
auto __result = method(_javaPart);
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
}
void JHybridOmniPlayerPropsSpec::setMetadata(const std::optional<Metadata>& metadata) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JMetadata> /* metadata */)>("setMetadata");
method(_javaPart, metadata.has_value() ? JMetadata::fromCpp(metadata.value()) : nullptr);
}
std::optional<MixAudioMode> JHybridOmniPlayerPropsSpec::getMixAudio() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JMixAudioMode>()>("getMixAudio");
auto __result = method(_javaPart);
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
}
void JHybridOmniPlayerPropsSpec::setMixAudio(std::optional<MixAudioMode> mixAudio) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JMixAudioMode> /* mixAudio */)>("setMixAudio");
method(_javaPart, mixAudio.has_value() ? JMixAudioMode::fromCpp(mixAudio.value()) : nullptr);
}
// Methods
} // namespace margelo::nitro::omni
@@ -1,72 +0,0 @@
///
/// HybridOmniPlayerPropsSpec.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#pragma once
#include <NitroModules/JHybridObject.hpp>
#include <fbjni/fbjni.h>
#include "HybridOmniPlayerPropsSpec.hpp"
namespace margelo::nitro::omni {
using namespace facebook;
class JHybridOmniPlayerPropsSpec: public virtual HybridOmniPlayerPropsSpec, public virtual JHybridObject {
public:
struct JavaPart: public jni::JavaClass<JavaPart, JHybridObject::JavaPart> {
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/HybridOmniPlayerPropsSpec;";
std::shared_ptr<JHybridOmniPlayerPropsSpec> getJHybridOmniPlayerPropsSpec();
};
struct CxxPart: public jni::HybridClass<CxxPart, JHybridObject::CxxPart> {
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/HybridOmniPlayerPropsSpec$CxxPart;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static void registerNatives();
using HybridBase::HybridBase;
protected:
std::shared_ptr<JHybridObject> createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) override;
};
public:
explicit JHybridOmniPlayerPropsSpec(const jni::local_ref<JHybridOmniPlayerPropsSpec::JavaPart>& javaPart):
HybridObject(HybridOmniPlayerPropsSpec::TAG),
JHybridObject(javaPart),
_javaPart(jni::make_global(javaPart)) {}
~JHybridOmniPlayerPropsSpec() override {
// Hermes GC can destroy JS objects on a non-JNI Thread.
jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); });
}
public:
inline const jni::global_ref<JHybridOmniPlayerPropsSpec::JavaPart>& getJavaPart() const noexcept {
return _javaPart;
}
public:
// Properties
std::vector<VideoSrc> getSrc() override;
void setSrc(const std::vector<VideoSrc>& src) override;
std::optional<double> getStartTime() override;
void setStartTime(std::optional<double> startTime) override;
std::vector<Subtitle> getSubtitles() override;
void setSubtitles(const std::vector<Subtitle>& subtitles) override;
std::optional<Metadata> getMetadata() override;
void setMetadata(const std::optional<Metadata>& metadata) override;
std::optional<MixAudioMode> getMixAudio() override;
void setMixAudio(std::optional<MixAudioMode> mixAudio) override;
public:
// Methods
private:
jni::global_ref<JHybridOmniPlayerPropsSpec::JavaPart> _javaPart;
};
} // namespace margelo::nitro::omni
+33 -3
View File
@@ -7,6 +7,16 @@
#include "JHybridOmniPlayerSpec.hpp"
// Forward declaration of `Source` to properly resolve imports.
namespace margelo::nitro::omni { struct Source; }
// Forward declaration of `VideoSrc` to properly resolve imports.
namespace margelo::nitro::omni { struct VideoSrc; }
// Forward declaration of `Subtitle` to properly resolve imports.
namespace margelo::nitro::omni { struct Subtitle; }
// Forward declaration of `Metadata` to properly resolve imports.
namespace margelo::nitro::omni { struct Metadata; }
// Forward declaration of `MixAudioMode` to properly resolve imports.
namespace margelo::nitro::omni { enum class MixAudioMode; }
// Forward declaration of `PlayerStatus` to properly resolve imports.
namespace margelo::nitro::omni { enum class PlayerStatus; }
// Forward declaration of `Track` to properly resolve imports.
@@ -14,13 +24,24 @@ namespace margelo::nitro::omni { struct Track; }
// Forward declaration of `Rendition` to properly resolve imports.
namespace margelo::nitro::omni { struct Rendition; }
#include "Source.hpp"
#include "JSource.hpp"
#include "VideoSrc.hpp"
#include <vector>
#include "JVideoSrc.hpp"
#include <string>
#include <optional>
#include <unordered_map>
#include "Subtitle.hpp"
#include "JSubtitle.hpp"
#include "Metadata.hpp"
#include "JMetadata.hpp"
#include "MixAudioMode.hpp"
#include "JMixAudioMode.hpp"
#include "PlayerStatus.hpp"
#include "JPlayerStatus.hpp"
#include "Track.hpp"
#include <vector>
#include "JTrack.hpp"
#include <string>
#include <optional>
#include "Rendition.hpp"
#include "JRendition.hpp"
@@ -54,6 +75,15 @@ namespace margelo::nitro::omni {
}
// Properties
Source JHybridOmniPlayerSpec::getSource() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JSource>()>("getSource");
auto __result = method(_javaPart);
return __result->toCpp();
}
void JHybridOmniPlayerSpec::setSource(const Source& source) {
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JSource> /* source */)>("setSource");
method(_javaPart, JSource::fromCpp(source));
}
bool JHybridOmniPlayerSpec::getHasPrev() {
static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("getHasPrev");
auto __result = method(_javaPart);
@@ -50,6 +50,8 @@ namespace margelo::nitro::omni {
public:
// Properties
Source getSource() override;
void setSource(const Source& source) override;
bool getHasPrev() override;
bool getHasNext() override;
PlayerStatus getStatus() override;
+120
View File
@@ -0,0 +1,120 @@
///
/// JSource.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#pragma once
#include <fbjni/fbjni.h>
#include "Source.hpp"
#include "JMetadata.hpp"
#include "JMixAudioMode.hpp"
#include "JSubtitle.hpp"
#include "JVideoSrc.hpp"
#include "Metadata.hpp"
#include "MixAudioMode.hpp"
#include "Subtitle.hpp"
#include "VideoSrc.hpp"
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
namespace margelo::nitro::omni {
using namespace facebook;
/**
* The C++ JNI bridge between the C++ struct "Source" and the the Kotlin data class "Source".
*/
struct JSource final: public jni::JavaClass<JSource> {
public:
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/Source;";
public:
/**
* Convert this Java/Kotlin-based struct to the C++ struct Source by copying all values to C++.
*/
[[maybe_unused]]
[[nodiscard]]
Source toCpp() const {
static const auto clazz = javaClassStatic();
static const auto fieldSrc = clazz->getField<jni::JArrayClass<JVideoSrc>>("src");
jni::local_ref<jni::JArrayClass<JVideoSrc>> src = this->getFieldValue(fieldSrc);
static const auto fieldStartTime = clazz->getField<jni::JDouble>("startTime");
jni::local_ref<jni::JDouble> startTime = this->getFieldValue(fieldStartTime);
static const auto fieldSubtitles = clazz->getField<jni::JArrayClass<JSubtitle>>("subtitles");
jni::local_ref<jni::JArrayClass<JSubtitle>> subtitles = this->getFieldValue(fieldSubtitles);
static const auto fieldMetadata = clazz->getField<JMetadata>("metadata");
jni::local_ref<JMetadata> metadata = this->getFieldValue(fieldMetadata);
static const auto fieldMixAudio = clazz->getField<JMixAudioMode>("mixAudio");
jni::local_ref<JMixAudioMode> mixAudio = this->getFieldValue(fieldMixAudio);
return Source(
[&]() {
size_t __size = src->size();
std::vector<VideoSrc> __vector;
__vector.reserve(__size);
for (size_t __i = 0; __i < __size; __i++) {
auto __element = src->getElement(__i);
__vector.push_back(__element->toCpp());
}
return __vector;
}(),
startTime != nullptr ? std::make_optional(startTime->value()) : std::nullopt,
[&]() {
size_t __size = subtitles->size();
std::vector<Subtitle> __vector;
__vector.reserve(__size);
for (size_t __i = 0; __i < __size; __i++) {
auto __element = subtitles->getElement(__i);
__vector.push_back(__element->toCpp());
}
return __vector;
}(),
metadata != nullptr ? std::make_optional(metadata->toCpp()) : std::nullopt,
mixAudio != nullptr ? std::make_optional(mixAudio->toCpp()) : std::nullopt
);
}
public:
/**
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
*/
[[maybe_unused]]
static jni::local_ref<JSource::javaobject> fromCpp(const Source& value) {
using JSignature = JSource(jni::alias_ref<jni::JArrayClass<JVideoSrc>>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JArrayClass<JSubtitle>>, jni::alias_ref<JMetadata>, jni::alias_ref<JMixAudioMode>);
static const auto clazz = javaClassStatic();
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
return create(
clazz,
[&]() {
size_t __size = value.src.size();
jni::local_ref<jni::JArrayClass<JVideoSrc>> __array = jni::JArrayClass<JVideoSrc>::newArray(__size);
for (size_t __i = 0; __i < __size; __i++) {
const auto& __element = value.src[__i];
auto __elementJni = JVideoSrc::fromCpp(__element);
__array->setElement(__i, *__elementJni);
}
return __array;
}(),
value.startTime.has_value() ? jni::JDouble::valueOf(value.startTime.value()) : nullptr,
[&]() {
size_t __size = value.subtitles.size();
jni::local_ref<jni::JArrayClass<JSubtitle>> __array = jni::JArrayClass<JSubtitle>::newArray(__size);
for (size_t __i = 0; __i < __size; __i++) {
const auto& __element = value.subtitles[__i];
auto __elementJni = JSubtitle::fromCpp(__element);
__array->setElement(__i, *__elementJni);
}
return __array;
}(),
value.metadata.has_value() ? JMetadata::fromCpp(value.metadata.value()) : nullptr,
value.mixAudio.has_value() ? JMixAudioMode::fromCpp(value.mixAudio.value()) : nullptr
);
}
};
} // namespace margelo::nitro::omni
@@ -30,7 +30,7 @@ abstract class HybridOmniPlayerFactorySpec: HybridObject() {
// Methods
@DoNotStrip
@Keep
abstract fun createPlayer(props: HybridOmniPlayerPropsSpec): HybridOmniPlayerSpec
abstract fun createPlayer(props: Source): HybridOmniPlayerSpec
// Default implementation of `HybridObject.toString()`
override fun toString(): String {
@@ -1,80 +0,0 @@
///
/// HybridOmniPlayerPropsSpec.kt
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
package com.margelo.nitro.omni
import androidx.annotation.Keep
import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip
import com.margelo.nitro.core.HybridObject
/**
* A Kotlin class representing the OmniPlayerProps HybridObject.
* Implement this abstract class to create Kotlin-based instances of OmniPlayerProps.
*/
@DoNotStrip
@Keep
@Suppress(
"KotlinJniMissingFunction", "unused",
"RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet",
"LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName"
)
abstract class HybridOmniPlayerPropsSpec: HybridObject() {
// Properties
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var src: Array<VideoSrc>
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var startTime: Double?
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var subtitles: Array<Subtitle>
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var metadata: Metadata?
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var mixAudio: MixAudioMode?
// Methods
// Default implementation of `HybridObject.toString()`
override fun toString(): String {
return "[HybridObject OmniPlayerProps]"
}
// C++ backing class
@DoNotStrip
@Keep
protected open class CxxPart(javaPart: HybridOmniPlayerPropsSpec): HybridObject.CxxPart(javaPart) {
// C++ JHybridOmniPlayerPropsSpec::CxxPart::initHybrid(...)
external override fun initHybrid(): HybridData
}
override fun createCxxPart(): CxxPart {
return CxxPart(this)
}
companion object {
protected const val TAG = "HybridOmniPlayerPropsSpec"
}
}
@@ -25,6 +25,12 @@ import com.margelo.nitro.core.HybridObject
)
abstract class HybridOmniPlayerSpec: HybridObject() {
// Properties
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var source: Source
@get:DoNotStrip
@get:Keep
abstract val hasPrev: Boolean
@@ -0,0 +1,50 @@
///
/// Source.kt
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
package com.margelo.nitro.omni
import androidx.annotation.Keep
import com.facebook.proguard.annotations.DoNotStrip
/**
* Represents the JavaScript object/struct "Source".
*/
@DoNotStrip
@Keep
data class Source(
@DoNotStrip
@Keep
val src: Array<VideoSrc>,
@DoNotStrip
@Keep
val startTime: Double?,
@DoNotStrip
@Keep
val subtitles: Array<Subtitle>,
@DoNotStrip
@Keep
val metadata: Metadata?,
@DoNotStrip
@Keep
val mixAudio: MixAudioMode?
) {
/* primary constructor */
companion object {
/**
* Constructor called from C++
*/
@DoNotStrip
@Keep
@Suppress("unused")
@JvmStatic
private fun fromCpp(src: Array<VideoSrc>, startTime: Double?, subtitles: Array<Subtitle>, metadata: Metadata?, mixAudio: MixAudioMode?): Source {
return Source(src, startTime, subtitles, metadata, mixAudio)
}
}
}
@@ -15,12 +15,12 @@
// Forward declaration of `HybridOmniPlayerSpec` to properly resolve imports.
namespace margelo::nitro::omni { class HybridOmniPlayerSpec; }
// Forward declaration of `HybridOmniPlayerPropsSpec` to properly resolve imports.
namespace margelo::nitro::omni { class HybridOmniPlayerPropsSpec; }
// Forward declaration of `Source` to properly resolve imports.
namespace margelo::nitro::omni { struct Source; }
#include <memory>
#include "HybridOmniPlayerSpec.hpp"
#include "HybridOmniPlayerPropsSpec.hpp"
#include "Source.hpp"
namespace margelo::nitro::omni {
@@ -53,7 +53,7 @@ namespace margelo::nitro::omni {
public:
// Methods
virtual std::shared_ptr<HybridOmniPlayerSpec> createPlayer(const std::shared_ptr<HybridOmniPlayerPropsSpec>& props) = 0;
virtual std::shared_ptr<HybridOmniPlayerSpec> createPlayer(const Source& props) = 0;
protected:
// Hybrid Setup
@@ -1,30 +0,0 @@
///
/// HybridOmniPlayerPropsSpec.cpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#include "HybridOmniPlayerPropsSpec.hpp"
namespace margelo::nitro::omni {
void HybridOmniPlayerPropsSpec::loadHybridMethods() {
// load base methods/properties
HybridObject::loadHybridMethods();
// load custom methods/properties
registerHybrids(this, [](Prototype& prototype) {
prototype.registerHybridGetter("src", &HybridOmniPlayerPropsSpec::getSrc);
prototype.registerHybridSetter("src", &HybridOmniPlayerPropsSpec::setSrc);
prototype.registerHybridGetter("startTime", &HybridOmniPlayerPropsSpec::getStartTime);
prototype.registerHybridSetter("startTime", &HybridOmniPlayerPropsSpec::setStartTime);
prototype.registerHybridGetter("subtitles", &HybridOmniPlayerPropsSpec::getSubtitles);
prototype.registerHybridSetter("subtitles", &HybridOmniPlayerPropsSpec::setSubtitles);
prototype.registerHybridGetter("metadata", &HybridOmniPlayerPropsSpec::getMetadata);
prototype.registerHybridSetter("metadata", &HybridOmniPlayerPropsSpec::setMetadata);
prototype.registerHybridGetter("mixAudio", &HybridOmniPlayerPropsSpec::getMixAudio);
prototype.registerHybridSetter("mixAudio", &HybridOmniPlayerPropsSpec::setMixAudio);
});
}
} // namespace margelo::nitro::omni
@@ -1,83 +0,0 @@
///
/// HybridOmniPlayerPropsSpec.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#pragma once
#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
// Forward declaration of `VideoSrc` to properly resolve imports.
namespace margelo::nitro::omni { struct VideoSrc; }
// Forward declaration of `Subtitle` to properly resolve imports.
namespace margelo::nitro::omni { struct Subtitle; }
// Forward declaration of `Metadata` to properly resolve imports.
namespace margelo::nitro::omni { struct Metadata; }
// Forward declaration of `MixAudioMode` to properly resolve imports.
namespace margelo::nitro::omni { enum class MixAudioMode; }
#include "VideoSrc.hpp"
#include <vector>
#include <optional>
#include "Subtitle.hpp"
#include "Metadata.hpp"
#include "MixAudioMode.hpp"
namespace margelo::nitro::omni {
using namespace margelo::nitro;
/**
* An abstract base class for `OmniPlayerProps`
* Inherit this class to create instances of `HybridOmniPlayerPropsSpec` in C++.
* You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
* @example
* ```cpp
* class HybridOmniPlayerProps: public HybridOmniPlayerPropsSpec {
* public:
* HybridOmniPlayerProps(...): HybridObject(TAG) { ... }
* // ...
* };
* ```
*/
class HybridOmniPlayerPropsSpec: public virtual HybridObject {
public:
// Constructor
explicit HybridOmniPlayerPropsSpec(): HybridObject(TAG) { }
// Destructor
~HybridOmniPlayerPropsSpec() override = default;
public:
// Properties
virtual std::vector<VideoSrc> getSrc() = 0;
virtual void setSrc(const std::vector<VideoSrc>& src) = 0;
virtual std::optional<double> getStartTime() = 0;
virtual void setStartTime(std::optional<double> startTime) = 0;
virtual std::vector<Subtitle> getSubtitles() = 0;
virtual void setSubtitles(const std::vector<Subtitle>& subtitles) = 0;
virtual std::optional<Metadata> getMetadata() = 0;
virtual void setMetadata(const std::optional<Metadata>& metadata) = 0;
virtual std::optional<MixAudioMode> getMixAudio() = 0;
virtual void setMixAudio(std::optional<MixAudioMode> mixAudio) = 0;
public:
// Methods
protected:
// Hybrid Setup
void loadHybridMethods() override;
protected:
// Tag for logging
static constexpr auto TAG = "OmniPlayerProps";
};
} // namespace margelo::nitro::omni
+2
View File
@@ -14,6 +14,8 @@ namespace margelo::nitro::omni {
HybridObject::loadHybridMethods();
// load custom methods/properties
registerHybrids(this, [](Prototype& prototype) {
prototype.registerHybridGetter("source", &HybridOmniPlayerSpec::getSource);
prototype.registerHybridSetter("source", &HybridOmniPlayerSpec::setSource);
prototype.registerHybridGetter("hasPrev", &HybridOmniPlayerSpec::getHasPrev);
prototype.registerHybridGetter("hasNext", &HybridOmniPlayerSpec::getHasNext);
prototype.registerHybridGetter("status", &HybridOmniPlayerSpec::getStatus);
+5
View File
@@ -13,6 +13,8 @@
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
// Forward declaration of `Source` to properly resolve imports.
namespace margelo::nitro::omni { struct Source; }
// Forward declaration of `PlayerStatus` to properly resolve imports.
namespace margelo::nitro::omni { enum class PlayerStatus; }
// Forward declaration of `Track` to properly resolve imports.
@@ -20,6 +22,7 @@ namespace margelo::nitro::omni { struct Track; }
// Forward declaration of `Rendition` to properly resolve imports.
namespace margelo::nitro::omni { struct Rendition; }
#include "Source.hpp"
#include "PlayerStatus.hpp"
#include "Track.hpp"
#include <vector>
@@ -53,6 +56,8 @@ namespace margelo::nitro::omni {
public:
// Properties
virtual Source getSource() = 0;
virtual void setSource(const Source& source) = 0;
virtual bool getHasPrev() = 0;
virtual bool getHasNext() = 0;
virtual PlayerStatus getStatus() = 0;
+111
View File
@@ -0,0 +1,111 @@
///
/// Source.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///
#pragma once
#if __has_include(<NitroModules/JSIConverter.hpp>)
#include <NitroModules/JSIConverter.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
#if __has_include(<NitroModules/NitroDefines.hpp>)
#include <NitroModules/NitroDefines.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
#if __has_include(<NitroModules/JSIHelpers.hpp>)
#include <NitroModules/JSIHelpers.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
#include <NitroModules/PropNameIDCache.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif
// Forward declaration of `VideoSrc` to properly resolve imports.
namespace margelo::nitro::omni { struct VideoSrc; }
// Forward declaration of `Subtitle` to properly resolve imports.
namespace margelo::nitro::omni { struct Subtitle; }
// Forward declaration of `Metadata` to properly resolve imports.
namespace margelo::nitro::omni { struct Metadata; }
// Forward declaration of `MixAudioMode` to properly resolve imports.
namespace margelo::nitro::omni { enum class MixAudioMode; }
#include "VideoSrc.hpp"
#include <vector>
#include <optional>
#include "Subtitle.hpp"
#include "Metadata.hpp"
#include "MixAudioMode.hpp"
namespace margelo::nitro::omni {
/**
* A struct which can be represented as a JavaScript object (Source).
*/
struct Source final {
public:
std::vector<VideoSrc> src SWIFT_PRIVATE;
std::optional<double> startTime SWIFT_PRIVATE;
std::vector<Subtitle> subtitles SWIFT_PRIVATE;
std::optional<Metadata> metadata SWIFT_PRIVATE;
std::optional<MixAudioMode> mixAudio SWIFT_PRIVATE;
public:
Source() = default;
explicit Source(std::vector<VideoSrc> src, std::optional<double> startTime, std::vector<Subtitle> subtitles, std::optional<Metadata> metadata, std::optional<MixAudioMode> mixAudio): src(src), startTime(startTime), subtitles(subtitles), metadata(metadata), mixAudio(mixAudio) {}
public:
friend bool operator==(const Source& lhs, const Source& rhs) = default;
};
} // namespace margelo::nitro::omni
namespace margelo::nitro {
// C++ Source <> JS Source (object)
template <>
struct JSIConverter<margelo::nitro::omni::Source> final {
static inline margelo::nitro::omni::Source fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
jsi::Object obj = arg.asObject(runtime);
return margelo::nitro::omni::Source(
JSIConverter<std::vector<margelo::nitro::omni::VideoSrc>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "src"))),
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "startTime"))),
JSIConverter<std::vector<margelo::nitro::omni::Subtitle>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "subtitles"))),
JSIConverter<std::optional<margelo::nitro::omni::Metadata>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata"))),
JSIConverter<std::optional<margelo::nitro::omni::MixAudioMode>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mixAudio")))
);
}
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::omni::Source& arg) {
jsi::Object obj(runtime);
obj.setProperty(runtime, PropNameIDCache::get(runtime, "src"), JSIConverter<std::vector<margelo::nitro::omni::VideoSrc>>::toJSI(runtime, arg.src));
obj.setProperty(runtime, PropNameIDCache::get(runtime, "startTime"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.startTime));
obj.setProperty(runtime, PropNameIDCache::get(runtime, "subtitles"), JSIConverter<std::vector<margelo::nitro::omni::Subtitle>>::toJSI(runtime, arg.subtitles));
obj.setProperty(runtime, PropNameIDCache::get(runtime, "metadata"), JSIConverter<std::optional<margelo::nitro::omni::Metadata>>::toJSI(runtime, arg.metadata));
obj.setProperty(runtime, PropNameIDCache::get(runtime, "mixAudio"), JSIConverter<std::optional<margelo::nitro::omni::MixAudioMode>>::toJSI(runtime, arg.mixAudio));
return obj;
}
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
if (!value.isObject()) {
return false;
}
jsi::Object obj = value.getObject(runtime);
if (!nitro::isPlainObject(runtime, obj)) {
return false;
}
if (!JSIConverter<std::vector<margelo::nitro::omni::VideoSrc>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "src")))) return false;
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "startTime")))) return false;
if (!JSIConverter<std::vector<margelo::nitro::omni::Subtitle>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "subtitles")))) return false;
if (!JSIConverter<std::optional<margelo::nitro::omni::Metadata>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "metadata")))) return false;
if (!JSIConverter<std::optional<margelo::nitro::omni::MixAudioMode>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mixAudio")))) return false;
return true;
}
};
} // namespace margelo::nitro
+18 -9
View File
@@ -1,10 +1,9 @@
import { createContext, type ReactNode, useContext } from "react";
import { createContext, type ReactNode, useContext, useEffect } from "react";
import { NitroModules } from "react-native-nitro-modules";
import type {
OmniPlayerFactory,
OmniPlayerProps,
} from "./specs/omni-player.nitro";
import type { OmniPlayerFactory } from "./specs/omni-player.nitro";
import type { OmniPlayer } from "./types/player";
import type { Source } from "./types/source";
import { useLazyRef } from "./utils/lazy-ref";
const ProviderFactory = NitroModules.createHybridObject<OmniPlayerFactory>(
"OmniProviderFactory",
@@ -14,10 +13,20 @@ const PlayerCtx = createContext<OmniPlayer>(null!);
export const OmniProvider = ({
children,
...props
}: OmniPlayerProps & { children: ReactNode }) => {
const player = ProviderFactory.createPlayer(props);
return <PlayerCtx.Provider value={player}>{children}</PlayerCtx.Provider>;
source,
}: {
source: Source;
children: ReactNode;
}) => {
const player = useLazyRef(() => ProviderFactory.createPlayer(source));
useEffect(() => {
player.current.source = source;
}, [source]);
return (
<PlayerCtx.Provider value={player.current}>{children}</PlayerCtx.Provider>
);
};
export const usePlayer = () => {
+2 -6
View File
@@ -1,15 +1,11 @@
import type { HybridObject } from "react-native-nitro-modules";
import type { OmniPlayer as OmniPlayerT } from "../types/player";
import type { OmniPlayerProps as OmniPlayerPropsT } from "../types/provider";
export interface OmniPlayerProps
extends HybridObject<{ android: "kotlin" }>,
OmniPlayerPropsT {}
import type { Source } from "../types/source";
export interface OmniPlayer
extends HybridObject<{ android: "kotlin" }>,
OmniPlayerT {}
export interface OmniPlayerFactory extends HybridObject<{ android: "kotlin" }> {
createPlayer(props: OmniPlayerProps): OmniPlayer;
createPlayer(props: Source): OmniPlayer;
}
+4
View File
@@ -1,4 +1,8 @@
import type { Source } from "./source";
export interface OmniPlayer {
source: Source;
play(): void;
pause(): void;
seekBy(offset: number): void;
@@ -1,4 +1,4 @@
export interface OmniPlayerProps {
export interface Source {
src: VideoSrc[];
startTime?: number;
subtitles: Subtitle[];
+13
View File
@@ -0,0 +1,13 @@
import { type RefObject, useRef } from "react";
const empty = Symbol("useLazyRef empty value");
export const useLazyRef = <T>(init: () => T): RefObject<T> => {
const resultRef = useRef<T | typeof empty>(empty);
if (resultRef.current === empty) {
resultRef.current = init();
}
return resultRef as RefObject<T>;
};