mirror of
https://github.com/zoriya/react-native-omni.git
synced 2026-08-05 21:58:54 +00:00
fix(web): make source a listenable state, fixes the view
This commit is contained in:
@@ -15,6 +15,7 @@ import androidx.media3.common.Player.STATE_BUFFERING
|
||||
import androidx.media3.common.Player.STATE_ENDED
|
||||
import androidx.media3.common.Player.STATE_IDLE
|
||||
import androidx.media3.common.Player.STATE_READY
|
||||
import androidx.media3.common.Timeline
|
||||
import androidx.media3.common.Tracks
|
||||
import androidx.media3.common.VideoSize
|
||||
import com.margelo.nitro.omni.BoolProperty
|
||||
@@ -23,6 +24,7 @@ import com.margelo.nitro.omni.HybridOmniEventMapSpec
|
||||
import com.margelo.nitro.omni.NumberProperty
|
||||
import com.margelo.nitro.omni.PlayerStatus
|
||||
import com.margelo.nitro.omni.Rendition
|
||||
import com.margelo.nitro.omni.Source
|
||||
import com.margelo.nitro.omni.Track
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
@@ -40,6 +42,7 @@ class EventMap() : HybridOmniEventMapSpec(), Player.Listener {
|
||||
private val stateBoolListeners = mutableMapOf<BoolProperty, MutableSet<(Boolean) -> Unit>>()
|
||||
private val playerStatusListeners = mutableSetOf<(PlayerStatus) -> Unit>()
|
||||
private val castStatusListeners = mutableSetOf<(CastStatus) -> Unit>()
|
||||
private val sourceListeners = mutableSetOf<(Source?) -> Unit>()
|
||||
|
||||
private var lastMediaItemIndex = 0
|
||||
private var lastRendition: Rendition? = null
|
||||
@@ -92,6 +95,10 @@ class EventMap() : HybridOmniEventMapSpec(), Player.Listener {
|
||||
castStatusListeners.forEach { it(status) }
|
||||
}
|
||||
|
||||
fun emitSource(source: Source?) {
|
||||
sourceListeners.forEach { it(source) }
|
||||
}
|
||||
|
||||
private fun selectedTrack(trackType: Int): Track? {
|
||||
val groups = player.currentTracks.groups.filter { it.type == trackType }
|
||||
for (group in groups) {
|
||||
@@ -300,6 +307,14 @@ class EventMap() : HybridOmniEventMapSpec(), Player.Listener {
|
||||
castStatusListeners.remove(cb)
|
||||
}
|
||||
|
||||
override fun addSourceListener(cb: (value: Source?) -> Unit) {
|
||||
sourceListeners.add(cb)
|
||||
}
|
||||
|
||||
override fun removeSourceListener(cb: (value: Source?) -> Unit) {
|
||||
sourceListeners.remove(cb)
|
||||
}
|
||||
|
||||
override fun addOnEndListener(cb: () -> Unit) {
|
||||
onEndListeners.add(cb)
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ class OmniPlayer(
|
||||
override var source: Source? = null
|
||||
set(value) {
|
||||
field = value
|
||||
eventMap.emitSource(value)
|
||||
if (value == null) {
|
||||
runOnMainThreadSync {
|
||||
player.clearMediaItems()
|
||||
|
||||
+2
@@ -20,6 +20,7 @@
|
||||
#include "JFunc_void_bool.hpp"
|
||||
#include "JFunc_void_PlayerStatus.hpp"
|
||||
#include "JFunc_void_CastStatus.hpp"
|
||||
#include "JFunc_void_std__optional_Source_.hpp"
|
||||
#include "JFunc_void.hpp"
|
||||
#include "JFunc_void_std__string_std__string.hpp"
|
||||
#include "JFunc_void_std__string.hpp"
|
||||
@@ -67,6 +68,7 @@ void registerAllNatives() {
|
||||
margelo::nitro::omni::JFunc_void_bool_cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_PlayerStatus_cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_CastStatus_cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_std__optional_Source__cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_std__string_std__string_cxx::registerNatives();
|
||||
margelo::nitro::omni::JFunc_void_std__string_cxx::registerNatives();
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
///
|
||||
/// JFunc_void_std__optional_Source_.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 <functional>
|
||||
|
||||
#include "Source.hpp"
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <NitroModules/JNICallable.hpp>
|
||||
#include "JSource.hpp"
|
||||
#include "VideoSrc.hpp"
|
||||
#include "JVideoSrc.hpp"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "Subtitle.hpp"
|
||||
#include <vector>
|
||||
#include "JSubtitle.hpp"
|
||||
#include "Metadata.hpp"
|
||||
#include "JMetadata.hpp"
|
||||
#include "MixAudioMode.hpp"
|
||||
#include "JMixAudioMode.hpp"
|
||||
|
||||
namespace margelo::nitro::omni {
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
/**
|
||||
* Represents the Java/Kotlin callback `(value: Source?) -> Unit`.
|
||||
* This can be passed around between C++ and Java/Kotlin.
|
||||
*/
|
||||
struct JFunc_void_std__optional_Source_: public jni::JavaClass<JFunc_void_std__optional_Source_> {
|
||||
public:
|
||||
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/Func_void_std__optional_Source_;";
|
||||
|
||||
public:
|
||||
/**
|
||||
* Invokes the function this `JFunc_void_std__optional_Source_` instance holds through JNI.
|
||||
*/
|
||||
void invoke(const std::optional<Source>& value) const {
|
||||
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JSource> /* value */)>("invoke");
|
||||
method(self(), value.has_value() ? JSource::fromCpp(value.value()) : nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An implementation of Func_void_std__optional_Source_ that is backed by a C++ implementation (using `std::function<...>`)
|
||||
*/
|
||||
class JFunc_void_std__optional_Source__cxx final: public jni::HybridClass<JFunc_void_std__optional_Source__cxx, JFunc_void_std__optional_Source_> {
|
||||
public:
|
||||
static jni::local_ref<JFunc_void_std__optional_Source_::javaobject> fromCpp(const std::function<void(const std::optional<Source>& /* value */)>& func) {
|
||||
return JFunc_void_std__optional_Source__cxx::newObjectCxxArgs(func);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Invokes the C++ `std::function<...>` this `JFunc_void_std__optional_Source__cxx` instance holds.
|
||||
*/
|
||||
void invoke_cxx(jni::alias_ref<JSource> value) {
|
||||
_func(value != nullptr ? std::make_optional(value->toCpp()) : std::nullopt);
|
||||
}
|
||||
|
||||
public:
|
||||
[[nodiscard]]
|
||||
inline const std::function<void(const std::optional<Source>& /* value */)>& getFunction() const {
|
||||
return _func;
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/omni/Func_void_std__optional_Source__cxx;";
|
||||
static void registerNatives() {
|
||||
registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_std__optional_Source__cxx::invoke_cxx)});
|
||||
}
|
||||
|
||||
private:
|
||||
explicit JFunc_void_std__optional_Source__cxx(const std::function<void(const std::optional<Source>& /* value */)>& func): _func(func) { }
|
||||
|
||||
private:
|
||||
friend HybridBase;
|
||||
std::function<void(const std::optional<Source>& /* value */)> _func;
|
||||
};
|
||||
|
||||
} // namespace margelo::nitro::omni
|
||||
+33
-2
@@ -15,6 +15,16 @@ namespace margelo::nitro::omni { enum class BoolProperty; }
|
||||
namespace margelo::nitro::omni { enum class PlayerStatus; }
|
||||
// Forward declaration of `CastStatus` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { enum class CastStatus; }
|
||||
// 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 `Track` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Track; }
|
||||
// Forward declaration of `Rendition` to properly resolve imports.
|
||||
@@ -34,14 +44,27 @@ namespace margelo::nitro::omni { struct Rendition; }
|
||||
#include "CastStatus.hpp"
|
||||
#include "JFunc_void_CastStatus.hpp"
|
||||
#include "JCastStatus.hpp"
|
||||
#include "JFunc_void.hpp"
|
||||
#include "Source.hpp"
|
||||
#include <optional>
|
||||
#include "JFunc_void_std__optional_Source_.hpp"
|
||||
#include "JSource.hpp"
|
||||
#include "VideoSrc.hpp"
|
||||
#include "JVideoSrc.hpp"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "Subtitle.hpp"
|
||||
#include <vector>
|
||||
#include "JSubtitle.hpp"
|
||||
#include "Metadata.hpp"
|
||||
#include "JMetadata.hpp"
|
||||
#include "MixAudioMode.hpp"
|
||||
#include "JMixAudioMode.hpp"
|
||||
#include "JFunc_void.hpp"
|
||||
#include "JFunc_void_std__string_std__string.hpp"
|
||||
#include "JFunc_void_std__string.hpp"
|
||||
#include "Track.hpp"
|
||||
#include "JFunc_void_Track.hpp"
|
||||
#include "JTrack.hpp"
|
||||
#include <optional>
|
||||
#include "JFunc_void_std__optional_Track_.hpp"
|
||||
#include "Rendition.hpp"
|
||||
#include "JFunc_void_Rendition.hpp"
|
||||
@@ -112,6 +135,14 @@ namespace margelo::nitro::omni {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_CastStatus::javaobject> /* cb */)>("removeCastStatusListener_cxx");
|
||||
method(_javaPart, JFunc_void_CastStatus_cxx::fromCpp(cb));
|
||||
}
|
||||
void JHybridOmniEventMapSpec::addSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_std__optional_Source_::javaobject> /* cb */)>("addSourceListener_cxx");
|
||||
method(_javaPart, JFunc_void_std__optional_Source__cxx::fromCpp(cb));
|
||||
}
|
||||
void JHybridOmniEventMapSpec::removeSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_std__optional_Source_::javaobject> /* cb */)>("removeSourceListener_cxx");
|
||||
method(_javaPart, JFunc_void_std__optional_Source__cxx::fromCpp(cb));
|
||||
}
|
||||
void JHybridOmniEventMapSpec::addOnEndListener(const std::function<void()>& cb) {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void::javaobject> /* cb */)>("addOnEndListener_cxx");
|
||||
method(_javaPart, JFunc_void_cxx::fromCpp(cb));
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace margelo::nitro::omni {
|
||||
void removePlayerStatusListener(const std::function<void(PlayerStatus /* value */)>& cb) override;
|
||||
void addCastStatusListener(const std::function<void(CastStatus /* value */)>& cb) override;
|
||||
void removeCastStatusListener(const std::function<void(CastStatus /* value */)>& cb) override;
|
||||
void addSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) override;
|
||||
void removeSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) override;
|
||||
void addOnEndListener(const std::function<void()>& cb) override;
|
||||
void removeOnEndListener(const std::function<void()>& cb) override;
|
||||
void addOnPrevListener(const std::function<void()>& cb) override;
|
||||
|
||||
+19
-19
@@ -9,6 +9,10 @@
|
||||
|
||||
// Forward declaration of `HybridOmniEventMapSpec` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { class HybridOmniEventMapSpec; }
|
||||
// Forward declaration of `Track` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Track; }
|
||||
// Forward declaration of `Rendition` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Rendition; }
|
||||
// Forward declaration of `Source` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Source; }
|
||||
// Forward declaration of `VideoSrc` to properly resolve imports.
|
||||
@@ -19,10 +23,6 @@ namespace margelo::nitro::omni { struct Subtitle; }
|
||||
namespace margelo::nitro::omni { struct Metadata; }
|
||||
// Forward declaration of `MixAudioMode` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { enum class MixAudioMode; }
|
||||
// Forward declaration of `Track` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Track; }
|
||||
// Forward declaration of `Rendition` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Rendition; }
|
||||
// Forward declaration of `PlayerStatus` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { enum class PlayerStatus; }
|
||||
// Forward declaration of `CastStatus` to properly resolve imports.
|
||||
@@ -32,23 +32,23 @@ namespace margelo::nitro::omni { enum class CastStatus; }
|
||||
#include "HybridOmniEventMapSpec.hpp"
|
||||
#include "JHybridOmniEventMapSpec.hpp"
|
||||
#include <optional>
|
||||
#include "Track.hpp"
|
||||
#include <vector>
|
||||
#include "JTrack.hpp"
|
||||
#include <string>
|
||||
#include "Rendition.hpp"
|
||||
#include "JRendition.hpp"
|
||||
#include "Source.hpp"
|
||||
#include "JSource.hpp"
|
||||
#include "VideoSrc.hpp"
|
||||
#include "JVideoSrc.hpp"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "Subtitle.hpp"
|
||||
#include <vector>
|
||||
#include "JSubtitle.hpp"
|
||||
#include "Metadata.hpp"
|
||||
#include "JMetadata.hpp"
|
||||
#include "MixAudioMode.hpp"
|
||||
#include "JMixAudioMode.hpp"
|
||||
#include "Track.hpp"
|
||||
#include "JTrack.hpp"
|
||||
#include "Rendition.hpp"
|
||||
#include "JRendition.hpp"
|
||||
#include "PlayerStatus.hpp"
|
||||
#include "JPlayerStatus.hpp"
|
||||
#include "CastStatus.hpp"
|
||||
@@ -98,15 +98,6 @@ namespace margelo::nitro::omni {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JBoolean> /* showNotification */)>("setShowNotification");
|
||||
method(_javaPart, showNotification.has_value() ? jni::JBoolean::valueOf(showNotification.value()) : nullptr);
|
||||
}
|
||||
std::optional<Source> JHybridOmniPlayerSpec::getSource() {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JSource>()>("getSource");
|
||||
auto __result = method(_javaPart);
|
||||
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
|
||||
}
|
||||
void JHybridOmniPlayerSpec::setSource(const std::optional<Source>& source) {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JSource> /* source */)>("setSource");
|
||||
method(_javaPart, source.has_value() ? JSource::fromCpp(source.value()) : nullptr);
|
||||
}
|
||||
bool JHybridOmniPlayerSpec::getHasPrev() {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("getHasPrev");
|
||||
auto __result = method(_javaPart);
|
||||
@@ -173,6 +164,15 @@ namespace margelo::nitro::omni {
|
||||
return __vector;
|
||||
}(__result);
|
||||
}
|
||||
std::optional<Source> JHybridOmniPlayerSpec::getSource() {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JSource>()>("getSource");
|
||||
auto __result = method(_javaPart);
|
||||
return __result != nullptr ? std::make_optional(__result->toCpp()) : std::nullopt;
|
||||
}
|
||||
void JHybridOmniPlayerSpec::setSource(const std::optional<Source>& source) {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JSource> /* source */)>("setSource");
|
||||
method(_javaPart, source.has_value() ? JSource::fromCpp(source.value()) : nullptr);
|
||||
}
|
||||
PlayerStatus JHybridOmniPlayerSpec::getStatus() {
|
||||
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPlayerStatus>()>("getStatus");
|
||||
auto __result = method(_javaPart);
|
||||
|
||||
+2
-2
@@ -53,14 +53,14 @@ namespace margelo::nitro::omni {
|
||||
std::shared_ptr<HybridOmniEventMapSpec> getEventMap() override;
|
||||
std::optional<bool> getShowNotification() override;
|
||||
void setShowNotification(std::optional<bool> showNotification) override;
|
||||
std::optional<Source> getSource() override;
|
||||
void setSource(const std::optional<Source>& source) override;
|
||||
bool getHasPrev() override;
|
||||
bool getHasNext() override;
|
||||
std::vector<Track> getVideos() override;
|
||||
std::vector<Track> getAudios() override;
|
||||
std::vector<Track> getSubtitles() override;
|
||||
std::vector<Rendition> getRendition() override;
|
||||
std::optional<Source> getSource() override;
|
||||
void setSource(const std::optional<Source>& source) override;
|
||||
PlayerStatus getStatus() override;
|
||||
bool getIsPlaying() override;
|
||||
double getCurrentTime() override;
|
||||
|
||||
Generated
+80
@@ -0,0 +1,80 @@
|
||||
///
|
||||
/// Func_void_std__optional_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.jni.HybridData
|
||||
import com.facebook.proguard.annotations.DoNotStrip
|
||||
import dalvik.annotation.optimization.FastNative
|
||||
|
||||
|
||||
/**
|
||||
* Represents the JavaScript callback `(value: optional) => void`.
|
||||
* This can be either implemented in C++ (in which case it might be a callback coming from JS),
|
||||
* or in Kotlin/Java (in which case it is a native callback).
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
@Suppress("ClassName", "RedundantUnitReturnType")
|
||||
fun interface Func_void_std__optional_Source_: (Source?) -> Unit {
|
||||
/**
|
||||
* Call the given JS callback.
|
||||
* @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
override fun invoke(value: Source?): Unit
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the JavaScript callback `(value: optional) => void`.
|
||||
* This is implemented in C++, via a `std::function<...>`.
|
||||
* The callback might be coming from JS.
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
@Suppress(
|
||||
"KotlinJniMissingFunction", "unused",
|
||||
"RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
|
||||
"ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
|
||||
)
|
||||
class Func_void_std__optional_Source__cxx: Func_void_std__optional_Source_ {
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
private val mHybridData: HybridData
|
||||
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
private constructor(hybridData: HybridData) {
|
||||
mHybridData = hybridData
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
override fun invoke(value: Source?): Unit
|
||||
= invoke_cxx(value)
|
||||
|
||||
@FastNative
|
||||
private external fun invoke_cxx(value: Source?): Unit
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the JavaScript callback `(value: optional) => void`.
|
||||
* This is implemented in Java/Kotlin, via a `(Source?) -> Unit`.
|
||||
* The callback is always coming from native.
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
@Suppress("ClassName", "RedundantUnitReturnType", "unused")
|
||||
class Func_void_std__optional_Source__java(private val function: (Source?) -> Unit): Func_void_std__optional_Source_ {
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
override fun invoke(value: Source?): Unit {
|
||||
return this.function(value)
|
||||
}
|
||||
}
|
||||
+18
@@ -100,6 +100,24 @@ abstract class HybridOmniEventMapSpec: HybridObject() {
|
||||
return __result
|
||||
}
|
||||
|
||||
abstract fun addSourceListener(cb: (value: Source?) -> Unit): Unit
|
||||
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
private fun addSourceListener_cxx(cb: Func_void_std__optional_Source_): Unit {
|
||||
val __result = addSourceListener(cb)
|
||||
return __result
|
||||
}
|
||||
|
||||
abstract fun removeSourceListener(cb: (value: Source?) -> Unit): Unit
|
||||
|
||||
@DoNotStrip
|
||||
@Keep
|
||||
private fun removeSourceListener_cxx(cb: Func_void_std__optional_Source_): Unit {
|
||||
val __result = removeSourceListener(cb)
|
||||
return __result
|
||||
}
|
||||
|
||||
abstract fun addOnEndListener(cb: () -> Unit): Unit
|
||||
|
||||
@DoNotStrip
|
||||
|
||||
+6
-6
@@ -35,12 +35,6 @@ abstract class HybridOmniPlayerSpec: HybridObject() {
|
||||
@set:Keep
|
||||
abstract var showNotification: Boolean?
|
||||
|
||||
@get:DoNotStrip
|
||||
@get:Keep
|
||||
@set:DoNotStrip
|
||||
@set:Keep
|
||||
abstract var source: Source?
|
||||
|
||||
@get:DoNotStrip
|
||||
@get:Keep
|
||||
abstract val hasPrev: Boolean
|
||||
@@ -65,6 +59,12 @@ abstract class HybridOmniPlayerSpec: HybridObject() {
|
||||
@get:Keep
|
||||
abstract val rendition: Array<Rendition>
|
||||
|
||||
@get:DoNotStrip
|
||||
@get:Keep
|
||||
@set:DoNotStrip
|
||||
@set:Keep
|
||||
abstract var source: Source?
|
||||
|
||||
@get:DoNotStrip
|
||||
@get:Keep
|
||||
abstract val status: PlayerStatus
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace margelo::nitro::omni {
|
||||
prototype.registerHybridMethod("removePlayerStatusListener", &HybridOmniEventMapSpec::removePlayerStatusListener);
|
||||
prototype.registerHybridMethod("addCastStatusListener", &HybridOmniEventMapSpec::addCastStatusListener);
|
||||
prototype.registerHybridMethod("removeCastStatusListener", &HybridOmniEventMapSpec::removeCastStatusListener);
|
||||
prototype.registerHybridMethod("addSourceListener", &HybridOmniEventMapSpec::addSourceListener);
|
||||
prototype.registerHybridMethod("removeSourceListener", &HybridOmniEventMapSpec::removeSourceListener);
|
||||
prototype.registerHybridMethod("addOnEndListener", &HybridOmniEventMapSpec::addOnEndListener);
|
||||
prototype.registerHybridMethod("removeOnEndListener", &HybridOmniEventMapSpec::removeOnEndListener);
|
||||
prototype.registerHybridMethod("addOnPrevListener", &HybridOmniEventMapSpec::addOnPrevListener);
|
||||
|
||||
+6
-1
@@ -21,6 +21,8 @@ namespace margelo::nitro::omni { enum class BoolProperty; }
|
||||
namespace margelo::nitro::omni { enum class PlayerStatus; }
|
||||
// Forward declaration of `CastStatus` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { enum class CastStatus; }
|
||||
// Forward declaration of `Source` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Source; }
|
||||
// Forward declaration of `Track` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Track; }
|
||||
// Forward declaration of `Rendition` to properly resolve imports.
|
||||
@@ -31,9 +33,10 @@ namespace margelo::nitro::omni { struct Rendition; }
|
||||
#include "BoolProperty.hpp"
|
||||
#include "PlayerStatus.hpp"
|
||||
#include "CastStatus.hpp"
|
||||
#include "Source.hpp"
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include "Track.hpp"
|
||||
#include <optional>
|
||||
#include "Rendition.hpp"
|
||||
|
||||
namespace margelo::nitro::omni {
|
||||
@@ -75,6 +78,8 @@ namespace margelo::nitro::omni {
|
||||
virtual void removePlayerStatusListener(const std::function<void(PlayerStatus /* value */)>& cb) = 0;
|
||||
virtual void addCastStatusListener(const std::function<void(CastStatus /* value */)>& cb) = 0;
|
||||
virtual void removeCastStatusListener(const std::function<void(CastStatus /* value */)>& cb) = 0;
|
||||
virtual void addSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) = 0;
|
||||
virtual void removeSourceListener(const std::function<void(const std::optional<Source>& /* value */)>& cb) = 0;
|
||||
virtual void addOnEndListener(const std::function<void()>& cb) = 0;
|
||||
virtual void removeOnEndListener(const std::function<void()>& cb) = 0;
|
||||
virtual void addOnPrevListener(const std::function<void()>& cb) = 0;
|
||||
|
||||
+2
-2
@@ -17,14 +17,14 @@ namespace margelo::nitro::omni {
|
||||
prototype.registerHybridGetter("eventMap", &HybridOmniPlayerSpec::getEventMap);
|
||||
prototype.registerHybridGetter("showNotification", &HybridOmniPlayerSpec::getShowNotification);
|
||||
prototype.registerHybridSetter("showNotification", &HybridOmniPlayerSpec::setShowNotification);
|
||||
prototype.registerHybridGetter("source", &HybridOmniPlayerSpec::getSource);
|
||||
prototype.registerHybridSetter("source", &HybridOmniPlayerSpec::setSource);
|
||||
prototype.registerHybridGetter("hasPrev", &HybridOmniPlayerSpec::getHasPrev);
|
||||
prototype.registerHybridGetter("hasNext", &HybridOmniPlayerSpec::getHasNext);
|
||||
prototype.registerHybridGetter("videos", &HybridOmniPlayerSpec::getVideos);
|
||||
prototype.registerHybridGetter("audios", &HybridOmniPlayerSpec::getAudios);
|
||||
prototype.registerHybridGetter("subtitles", &HybridOmniPlayerSpec::getSubtitles);
|
||||
prototype.registerHybridGetter("rendition", &HybridOmniPlayerSpec::getRendition);
|
||||
prototype.registerHybridGetter("source", &HybridOmniPlayerSpec::getSource);
|
||||
prototype.registerHybridSetter("source", &HybridOmniPlayerSpec::setSource);
|
||||
prototype.registerHybridGetter("status", &HybridOmniPlayerSpec::getStatus);
|
||||
prototype.registerHybridGetter("isPlaying", &HybridOmniPlayerSpec::getIsPlaying);
|
||||
prototype.registerHybridGetter("currentTime", &HybridOmniPlayerSpec::getCurrentTime);
|
||||
|
||||
+5
-5
@@ -15,12 +15,12 @@
|
||||
|
||||
// Forward declaration of `HybridOmniEventMapSpec` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { class HybridOmniEventMapSpec; }
|
||||
// Forward declaration of `Source` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Source; }
|
||||
// Forward declaration of `Track` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Track; }
|
||||
// Forward declaration of `Rendition` to properly resolve imports.
|
||||
namespace margelo::nitro::omni { struct Rendition; }
|
||||
// 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 `CastStatus` to properly resolve imports.
|
||||
@@ -29,10 +29,10 @@ namespace margelo::nitro::omni { enum class CastStatus; }
|
||||
#include <memory>
|
||||
#include "HybridOmniEventMapSpec.hpp"
|
||||
#include <optional>
|
||||
#include "Source.hpp"
|
||||
#include "Track.hpp"
|
||||
#include <vector>
|
||||
#include "Rendition.hpp"
|
||||
#include "Source.hpp"
|
||||
#include "PlayerStatus.hpp"
|
||||
#include "CastStatus.hpp"
|
||||
|
||||
@@ -66,14 +66,14 @@ namespace margelo::nitro::omni {
|
||||
virtual std::shared_ptr<HybridOmniEventMapSpec> getEventMap() = 0;
|
||||
virtual std::optional<bool> getShowNotification() = 0;
|
||||
virtual void setShowNotification(std::optional<bool> showNotification) = 0;
|
||||
virtual std::optional<Source> getSource() = 0;
|
||||
virtual void setSource(const std::optional<Source>& source) = 0;
|
||||
virtual bool getHasPrev() = 0;
|
||||
virtual bool getHasNext() = 0;
|
||||
virtual std::vector<Track> getVideos() = 0;
|
||||
virtual std::vector<Track> getAudios() = 0;
|
||||
virtual std::vector<Track> getSubtitles() = 0;
|
||||
virtual std::vector<Rendition> getRendition() = 0;
|
||||
virtual std::optional<Source> getSource() = 0;
|
||||
virtual void setSource(const std::optional<Source>& source) = 0;
|
||||
virtual PlayerStatus getStatus() = 0;
|
||||
virtual bool getIsPlaying() = 0;
|
||||
virtual double getCurrentTime() = 0;
|
||||
|
||||
@@ -55,6 +55,9 @@ export function usePlayerState<Key extends keyof OmniPlayerState>(
|
||||
case "castStatus":
|
||||
em.addCastStatusListener(setState);
|
||||
return () => em.removeCastStatusListener(setState);
|
||||
case "source":
|
||||
em.addSourceListener(setState);
|
||||
return () => em.removeSourceListener(setState);
|
||||
}
|
||||
}, [player, key]);
|
||||
|
||||
|
||||
+14
-3
@@ -12,7 +12,7 @@ import {
|
||||
selectVolume,
|
||||
usePlayer as useStoreSelector,
|
||||
} from "@videojs/react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useEffect, useRef, useSyncExternalStore } from "react";
|
||||
import type { WebOmniPlayer } from "./player.web";
|
||||
import { usePlayer } from "./provider.web";
|
||||
import type { OmniEvents } from "./types/events";
|
||||
@@ -204,6 +204,7 @@ export const stateMapper = {
|
||||
}),
|
||||
};
|
||||
|
||||
// biome-ignore-start lint/correctness/useHookAtTopLevel: key must be const
|
||||
export function usePlayerState<Key extends keyof OmniPlayerState>(
|
||||
key: Key,
|
||||
): OmniPlayerState[Key];
|
||||
@@ -215,8 +216,18 @@ export function usePlayerState<Key extends keyof OmniPlayerState>(
|
||||
key: Key,
|
||||
_refresh?: number,
|
||||
): OmniPlayerState[Key] {
|
||||
const config = stateMapper[key];
|
||||
if (key === "source") {
|
||||
const player = usePlayer() as WebOmniPlayer;
|
||||
const source = useSyncExternalStore(
|
||||
player.subscribeSource,
|
||||
() => player.source,
|
||||
() => player.source,
|
||||
);
|
||||
return source as OmniPlayerState[Key];
|
||||
}
|
||||
const config = stateMapper[key as keyof Omit<OmniPlayerState, "source">];
|
||||
const ret = useStoreSelector(config?.selector as Selector<any, any>);
|
||||
if (!config) throw new Error(`No mapper for ${key}`);
|
||||
const ret = useStoreSelector(config.selector as Selector<any, any>);
|
||||
return config.mapper(ret) as OmniPlayerState[Key];
|
||||
}
|
||||
// biome-ignore-end lint/correctness/useHookAtTopLevel: key must be const
|
||||
|
||||
@@ -70,6 +70,13 @@ export class WebOmniPlayer implements OmniPlayer {
|
||||
private overlaySubtitle: Subtitle | null = null;
|
||||
private overlayListeners = new Set<() => void>();
|
||||
|
||||
private sourceListeners = new Set<() => void>();
|
||||
subscribeSource = (callback: () => void): (() => void) => {
|
||||
this.sourceListeners.add(callback);
|
||||
return () => this.sourceListeners.delete(callback);
|
||||
};
|
||||
|
||||
|
||||
get source(): Source | undefined {
|
||||
return this._source;
|
||||
}
|
||||
@@ -84,6 +91,7 @@ export class WebOmniPlayer implements OmniPlayer {
|
||||
this.setOverlaySubtitle(null);
|
||||
}
|
||||
this.updateMediaSession();
|
||||
for (const listener of this.sourceListeners) listener();
|
||||
}
|
||||
|
||||
get showNotification(): boolean {
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { CastOptions, Source } from "../types/source";
|
||||
|
||||
export type NumberProperty = Exclude<
|
||||
keyof OmniPlayerState,
|
||||
"status" | "isPlaying" | "muted"
|
||||
"status" | "isPlaying" | "muted" | "source"
|
||||
>;
|
||||
export type BoolProperty = "isPlaying" | "muted" | "isAutoQuality";
|
||||
|
||||
@@ -29,6 +29,9 @@ export interface OmniEventMap extends HybridObject<{ android: "kotlin" }> {
|
||||
addCastStatusListener(cb: (value: CastStatus) => void): void;
|
||||
removeCastStatusListener(cb: (value: CastStatus) => void): void;
|
||||
|
||||
addSourceListener(cb: (value?: Source) => void): void;
|
||||
removeSourceListener(cb: (value?: Source) => void): void;
|
||||
|
||||
addOnEndListener(cb: OmniEvents["end"]): void;
|
||||
removeOnEndListener(cb: OmniEvents["end"]): void;
|
||||
|
||||
|
||||
+1
-2
@@ -3,8 +3,6 @@ import type { Source } from "./source";
|
||||
export interface OmniPlayer extends OmniPlayerState {
|
||||
showNotification?: boolean;
|
||||
|
||||
source?: Source;
|
||||
|
||||
play(): void;
|
||||
pause(): void;
|
||||
seekBy(offset: number): void;
|
||||
@@ -28,6 +26,7 @@ export interface OmniPlayer extends OmniPlayerState {
|
||||
}
|
||||
|
||||
export interface OmniPlayerState {
|
||||
source?: Source;
|
||||
readonly status: PlayerStatus;
|
||||
readonly isPlaying: boolean;
|
||||
currentTime: number;
|
||||
|
||||
+11
-11
@@ -109,18 +109,18 @@ export const OmniView = ({
|
||||
const player = usePlayer() as WebOmniPlayer;
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const ref = useRef<HTMLVideoElement>(undefined!);
|
||||
const source = usePlayerState("source");
|
||||
|
||||
const src = player.source?.src;
|
||||
const isHls =
|
||||
src?.mimeType?.toLowerCase().includes("mpegurl") ||
|
||||
src?.uri.split(/[?#]/)[0]?.toLowerCase().endsWith(".m3u8") ||
|
||||
source?.src?.mimeType?.toLowerCase().includes("mpegurl") ||
|
||||
source?.src?.uri.split(/[?#]/)[0]?.toLowerCase().endsWith(".m3u8") ||
|
||||
false;
|
||||
const Tech = isHls ? HlsJsVideo : Video;
|
||||
|
||||
const headersRef = useRef(src?.headers);
|
||||
headersRef.current = src?.headers;
|
||||
const castId = player.source?.castId;
|
||||
const castData = player.source?.castData;
|
||||
const headersRef = useRef(source?.src?.headers);
|
||||
headersRef.current = source?.src?.headers;
|
||||
const castId = source?.castId;
|
||||
const castData = source?.castData;
|
||||
|
||||
const config = useMemo<HlsMediaConfig>(
|
||||
() => ({
|
||||
@@ -151,17 +151,17 @@ export const OmniView = ({
|
||||
ref={containerRef}
|
||||
style={{ position: "relative", ...style }}
|
||||
>
|
||||
{src && (
|
||||
{source?.src && (
|
||||
<Tech
|
||||
ref={ref}
|
||||
src={src.uri}
|
||||
src={source?.src.uri}
|
||||
config={config}
|
||||
autoPlay={autoplay}
|
||||
playsInline
|
||||
crossOrigin="anonymous"
|
||||
style={{ width: "100%", height: "100%", objectFit: "contain" }}
|
||||
>
|
||||
{(player.source?.subtitles ?? []).map((subtitle) => (
|
||||
{(source?.subtitles ?? []).map((subtitle) => (
|
||||
<track
|
||||
key={subtitle.id}
|
||||
id={subtitle.id}
|
||||
@@ -177,7 +177,7 @@ export const OmniView = ({
|
||||
<SubtitleOverlay
|
||||
video={ref}
|
||||
assets={subtitleAssets}
|
||||
fonts={player.source?.fonts}
|
||||
fonts={source?.fonts}
|
||||
/>
|
||||
)}
|
||||
</VideoPlayer.Container>
|
||||
|
||||
Reference in New Issue
Block a user