Created
October 19, 2020 11:15
-
-
Save AndreiCalazans/e7c537687c0c5d7d6016688a67be99a9 to your computer and use it in GitHub Desktop.
Player with own ShadowView and concrete implementation for a WebPlayer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import { | |
requireNativeComponent, | |
UIManager, | |
findNodeHandle, | |
NativeModules, | |
} from "react-native"; | |
const MKPlayerView = requireNativeComponent("MKPlayerView"); | |
const MKPlayerManager = NativeModules.MKPlayerManager; | |
type NativeEvent<T extends {}> = { | |
nativeEvent: T; | |
}; | |
type MKPlayerProps = { | |
src: string; | |
onStateChange: (event: NativeEvent<any>) => void; | |
onPositionChange: (event: NativeEvent<any>) => void; | |
onError: (event: NativeEvent<any>) => void; | |
}; | |
export class MKPlayer extends Component<MKPlayerProps> { | |
play() { | |
MKPlayerManager.play(); | |
} | |
pause() { | |
MKPlayerManager.pause(); | |
} | |
stop() { | |
MKPlayerManager.stop(); | |
} | |
preload() { | |
MKPlayerManager.preload(); | |
} | |
seek(positionInSeconds: number) { | |
MKPlayerManager.seek(positionInSeconds); | |
} | |
liveNow() { | |
MKPlayerManager.liveNow(); | |
} | |
setMaxBandwidth(maxBandwidthKbps: number) { | |
MKPlayerManager.setMaxBandwidth(maxBandwidthKbps); | |
} | |
getVideoPosition(): Promise<any> { | |
return MKPlayerManager.getVideoPosition(); | |
} | |
getVideoDuration(): Promise<any> { | |
return MKPlayerManager.getVideoDuration(); | |
} | |
getProgramInfo(): Promise<any> { | |
return MKPlayerManager.getProgramInfo(); | |
} | |
enableClosedCaptions(enabled: boolean) { | |
MKPlayerManager.enableClosedCaptions(enabled); | |
} | |
getClosedCaptionsState(): Promise<any> { | |
return MKPlayerManager.getClosedCaptionsState(); | |
} | |
getSubtitleTracks(): Promise<any> { | |
return MKPlayerManager.getSubtitleTracks(); | |
} | |
getCurrentSubtitleTrack(): Promise<any> { | |
return MKPlayerManager.getCurrentSubtitleTrack(); | |
} | |
setSubtitleTrack(subtitleTrack: string) { | |
MKPlayerManager.setSubtitleTrack(subtitleTrack); | |
} | |
setAudioTrack(audioTrack: string) { | |
MKPlayerManager.setAudioTrack(audioTrack); | |
} | |
getAudioTracks(): Promise<any> { | |
return MKPlayerManager.getAudioTracks(); | |
} | |
getCurrentAudioTrack(): Promise<any> { | |
return MKPlayerManager.getCurrentAudioTrack(); | |
} | |
getTimeshiftEnabled(): Promise<any> { | |
return MKPlayerManager.getTimeshiftEnabled(); | |
} | |
getFFEnabled(): Promise<any> { | |
return MKPlayerManager.getFFEnabled(); | |
} | |
getRWEnabled(): Promise<any> { | |
return MKPlayerManager.getFFEnabled(); | |
} | |
render() { | |
return <MKPlayerView {...this.props} />; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <youireact/modules/components/AbstractComponentManagerModule.h> | |
#include <youireact/modules/components/IViewManager.h> | |
#include <platform/YiWebBridgeLocator.h> | |
#include <youireact/nodes/ReactComponent.h> | |
using namespace yi::react; | |
class YI_RN_MODULE(MKPlayerManager, AbstractComponentManagerModule), public IViewManager | |
{ | |
public: | |
YI_RN_EXPORT_NAME(MKPlayerManager); | |
~MKPlayerManager(); | |
ReactComponent * reactInstance; | |
void handleRectangleUpdate(const YI_RECT_REL &rVideoRectangle); | |
// Add methods that will be available to JSX: | |
YI_RN_EXPORT_METHOD(play)(); | |
YI_RN_EXPORT_METHOD(pause)(); | |
YI_RN_EXPORT_METHOD(stop)(); | |
YI_RN_EXPORT_METHOD(preload)(); | |
YI_RN_EXPORT_METHOD(seek)(uint64_t secondsPosition); | |
YI_RN_EXPORT_METHOD(liveNow)(); | |
YI_RN_EXPORT_METHOD(setMaxBandwidth)(uint64_t maxBandwidthKbps); | |
YI_RN_EXPORT_METHOD(getVideoPosition)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getVideoDuration)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getProgramInfo)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(enableClosedCaptions)(bool enabled); | |
YI_RN_EXPORT_METHOD(getClosedCaptionsState)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getSubtitleTracks)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getCurrentSubtitleTrack)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(setSubtitleTrack)(const std::string& subtitleTrack); | |
YI_RN_EXPORT_METHOD(setAudioTrack)(const std::string& audioTrack); | |
YI_RN_EXPORT_METHOD(getAudioTracks)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getCurrentAudioTrack)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getTimeshiftEnabled)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getFFEnabled)(Callback resolve, Callback reject); | |
YI_RN_EXPORT_METHOD(getRWEnabled)(Callback resolve, Callback reject); | |
YI_RN_DEFINE_COMPONENT_MODULE(); | |
// @TODO In the future when we move to more platforms we can overload these | |
void onStateChange(const yi::rapidjson::Value &eventValue); | |
void onPlayerError(const yi::rapidjson::Value &eventValue); | |
void onPositionChange(const yi::rapidjson::Value &eventValue); | |
YI_RECT_REL m_previousVideoRectangle; | |
// @TODO In the future when we move to more platforms we can decide if this will be used only by Tizen. | |
std::vector<uint64_t> registeredEvents; | |
bool messageHandlersRegistered; | |
uint64_t registerEventHandler(const CYIString &eventName, CYIWebMessagingBridge::EventCallback &&eventCallback); | |
void unregisterEventHandler(uint64_t &eventHandlerId); | |
void registerEventHandlers(); | |
void unregisterEventHandlers(); | |
protected: | |
virtual void SetupProperties() override; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mk_player/MKPlayerManager.h" | |
#include "mk_player/MKPlayerView.h" | |
#include <youireact/NativeModuleRegistry.h> | |
#include <folly/dynamic.h> | |
/* | |
* MKPlayerManager implements handles the entire bridge. | |
* It is responsible for: | |
* - Receiving props from JSX. | |
* - Emitting events to JSX. | |
* - Implementing the JSX MKVideo methods | |
* - And communicating with Tizen via the WebMessaging module. | |
* | |
* WARNING: The PlayerManager naively assumes there can only ever be one Player at once. Further work needs to | |
* be put into handling multiple players. | |
* | |
* HOW TO ADD JSX PROPS? | |
* - FOR DATA | |
* Add the prop definition in MKPlayerManager::GetNativeProps() and define a callback to handle it in MKPlayerManager::SetupProperties(), | |
* notice YI_RN_DEFINE_PROPERTY is used to define the callback to handle the setter. | |
* | |
* | |
* - FOR ON EVENT PROPS: | |
* In MKPlayerView.h define both the direct event plus its name, i.e., | |
YI_RN_EXPORT_DIRECT_EVENT(onStateChange); | |
YI_RN_EXPORT_DIRECT_EVENT_NAME(onStateChangeName); | |
Then in MKPlayerView.cpp define the YI_RN_DEFINE_DIRECT_EVENT_NAME & call | |
the SetDirectEvent(MKPlayerView::onStateChangeName, onStateChange); in the constructor MKPlayerView::MKPlyerView. | |
With the above you have defined a prop event that can used in JSX as <MKPlayer onStateChange={this.handleOnStateChange} .../> | |
To trigget the above event in React Native, you can call the reactInstance.EmitDirectEvent function. This function holds a pointer to | |
the SetDirectEvent function from MKPlayerView. | |
* | |
* | |
* | |
* HOW TO ADD A METHOD TO CALL IN REACT NATIVE JSX? | |
* Define a export method in MKPlayerManager.h like: | |
* YI_RN_EXPORT_METHOD(play)(); | |
* Then in the MKPlayerManager_WebPlayer implement the method by using: | |
* YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, play)() | |
* | |
* HOW TO CALL FUNCTION IN TIZEN JS SCOPE? | |
* Use functions callTizenWithArgs or callTizenWithoutArgs for this. See how it is being used in the methods below. | |
* | |
* HOW TO CALL C++ LAYER FROM TIZEN JS SCOPE? | |
* To call a method in this C++ class from Tizen's JS scope you must first register a call event as follow: | |
registeredEvents.push_back(registerEventHandler("onPlayerError", std::bind(&MKPlayerManager::onPlayerError, this, std::placeholders::_1))); | |
noticy OnPlayerError is a method in MKPlayerManager to handle this call. | |
In Tizen's JS scope you can use CYIMessaging.sendEvent to send the event to C++ as follow: | |
CYIMessaging.sendEvent({ | |
context: "CustomVideoPlayer", | |
name: "onPlayerError", | |
data: data, | |
}); | |
* */ | |
using namespace yi::react; | |
#define TAG "MKPlayerManager" | |
#define TIZEN_CLASS_NAME "CustomVideoPlayer" | |
typedef std::function<void(std::vector<folly::dynamic>)> JsCallback; | |
void callTizenWithoutArgs(const std::string& methodName) { | |
CYIWebMessagingBridge *pBridge = CYIWebBridgeLocator::GetWebMessagingBridge(); | |
bool messageSent = false; | |
CYIWebMessagingBridge::FutureResponse futureResponse = pBridge->CallStaticFunction(yi::rapidjson::Document(), TIZEN_CLASS_NAME, methodName, &messageSent); | |
} | |
void callTizenWithoutArgs(const std::string& methodName, JsCallback resolve, JsCallback reject) { | |
CYIWebMessagingBridge *pBridge = CYIWebBridgeLocator::GetWebMessagingBridge(); | |
bool messageSent = false; | |
CYIWebMessagingBridge::FutureResponse futureResponse = pBridge->CallStaticFunction(yi::rapidjson::Document(), TIZEN_CLASS_NAME, methodName, &messageSent); | |
if (!messageSent) | |
reject({}); | |
bool valueAssigned = false; | |
CYIWebMessagingBridge::Response response = futureResponse.Take(CYIWebMessagingBridge::DEFAULT_RESPONSE_TIMEOUT_MS, &valueAssigned); | |
if (!valueAssigned) | |
reject({}); | |
const yi::rapidjson::Value *pData = response.GetResult(); | |
resolve({ToDynamic(*pData)}); | |
} | |
struct Message { | |
yi::rapidjson::Document messageDocument; // Message Document to send Data over to tizen. | |
yi::rapidjson::Value arguments; // Arguments Arrray required for JS functions functionName(args: any[]); | |
yi::rapidjson::MemoryPoolAllocator<yi::rapidjson::CrtAllocator> &messageAllocator; // Allocated memory which rapidjson requires. | |
Message(): | |
messageDocument(yi::rapidjson::kObjectType), | |
arguments(yi::rapidjson::kArrayType), | |
messageAllocator(messageDocument.GetAllocator()) | |
{} | |
void addArgument(const yi::rapidjson::Value& arg) { | |
yi::rapidjson::Value argValue(arg, messageAllocator); | |
arguments.PushBack(argValue, messageAllocator); | |
} | |
}; | |
void callTizenWithArgs(const std::string& methodName, Message msg) { | |
CYIWebMessagingBridge *pBridge = CYIWebBridgeLocator::GetWebMessagingBridge(); | |
bool messageSent = false; | |
CYIWebMessagingBridge::FutureResponse futureResponse = pBridge->CallStaticFunctionWithArgs(std::move(msg.messageDocument), TIZEN_CLASS_NAME, methodName, std::move(msg.arguments), &messageSent); | |
} | |
YI_RN_INSTANTIATE_MODULE(MKPlayerManager, AbstractComponentManagerModule); | |
YI_RN_REGISTER_MODULE(MKPlayerManager); | |
YI_RN_OVERRIDE_OnInit(MKPlayerManager); | |
YI_RN_OVERRIDE_OnLayoutApplied(MKPlayerManager); | |
YI_RN_OVERRIDE_ApplyProps(MKPlayerManager); | |
void MKPlayerManager::DismantleCounterpart(ReactComponent *pInstance) | |
{ | |
if (pInstance) | |
{ | |
DismantleCounterpartPriv(*pInstance); \ | |
} | |
reactInstance = nullptr; | |
} | |
void MKPlayerManager::ConfigureCounterpart(ReactComponent *pInstance) | |
{ | |
if (pInstance) | |
{ | |
reactInstance = pInstance; | |
ConfigureCounterpartPriv(*pInstance); | |
} | |
} | |
MKPlayerManager::~MKPlayerManager() { | |
reactInstance = nullptr; | |
} | |
folly::dynamic MKPlayerManager::GetNativeProps() | |
{ | |
folly::dynamic superProps = IViewManager::GetNativeProps(); | |
folly::dynamic props = folly::dynamic::object("src", "string"); | |
return folly::dynamic::merge(superProps, props); | |
} | |
void MKPlayerManager::SetupProperties() | |
{ | |
IViewManager::SetupProperties(); | |
YI_RN_DEFINE_PROPERTY("src", [this](MKPlayerView &self, std::string src) { | |
registerEventHandlers(); | |
YI_LOGD(TAG, "Initialize"); | |
Message msg; | |
yi::rapidjson::Value srcValue(src.data(), msg.messageAllocator); | |
msg.addArgument(srcValue); | |
callTizenWithArgs("initialize", std::move(msg)); | |
}); | |
} | |
void MKPlayerManager::handleRectangleUpdate(const YI_RECT_REL &rVideoRectangle) { | |
// handleRectangleUpdate is called on every frame. | |
if(rVideoRectangle == m_previousVideoRectangle) { | |
return; | |
} | |
YI_LOGD(TAG, "handleRectangleUpdate"); | |
m_previousVideoRectangle = rVideoRectangle; | |
Message msg; | |
msg.addArgument(yi::rapidjson::Value().SetUint(rVideoRectangle.x)); | |
msg.addArgument(yi::rapidjson::Value().SetUint(rVideoRectangle.y)); | |
msg.addArgument(yi::rapidjson::Value().SetUint(rVideoRectangle.width)); | |
msg.addArgument(yi::rapidjson::Value().SetUint(rVideoRectangle.height)); | |
callTizenWithArgs("setVideoRectangle", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, play)(){ | |
YI_LOGD(TAG, "Play"); | |
callTizenWithoutArgs("play"); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, pause)(){ | |
YI_LOGD(TAG, "Pause"); | |
callTizenWithoutArgs("pause"); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, stop)(){ | |
YI_LOGD(TAG, "stop"); | |
// Check with Varun if we should wait for AMC to destroy then remove event listeners? Current implementation could lead to us not getting any errors if destroy goes bad. | |
unregisterEventHandlers(); | |
callTizenWithoutArgs("destroy"); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, preload)(){ | |
YI_LOGD(TAG, "Preload"); | |
callTizenWithoutArgs("preload"); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, seek)(uint64_t secondsPosition){ | |
YI_LOGD(TAG, "Preload"); | |
Message msg; | |
msg.addArgument(yi::rapidjson::Value().SetUint64(secondsPosition)); | |
callTizenWithArgs("preload", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, liveNow)(){ | |
YI_LOGD(TAG, "liveNow"); | |
callTizenWithoutArgs("liveNow"); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, setMaxBandwidth)(uint64_t maxBandwidthKbps){ | |
YI_LOGD(TAG, "setMaxBandwidth"); | |
Message msg; | |
msg.addArgument(yi::rapidjson::Value().SetUint64(maxBandwidthKbps)); | |
callTizenWithArgs("setMaxBandwidth", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getVideoPosition)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getVideoPosition"); | |
callTizenWithoutArgs("getVideoPosition", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getVideoDuration)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getVideoDuration"); | |
callTizenWithoutArgs("getVideoDuration", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getProgramInfo)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getProgramInfo"); | |
callTizenWithoutArgs("getProgramInfo", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, enableClosedCaptions)(bool enabled){ | |
YI_LOGD(TAG, "enableClosedCaptions"); | |
Message msg; | |
msg.addArgument(yi::rapidjson::Value().SetBool(enabled)); | |
callTizenWithArgs("enableClosedCaptions", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getClosedCaptionsState)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getClosedCaptionsState"); | |
callTizenWithoutArgs("getClosedCaptionsState", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getSubtitleTracks)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getSubtitleTracks"); | |
callTizenWithoutArgs("getSubtitleTracks", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getCurrentSubtitleTrack)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getCurrentSubtitleTrack"); | |
callTizenWithoutArgs("getCurrentSubtitleTrack", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, setSubtitleTrack)(const std::string& subtitleTrack){ | |
YI_LOGD(TAG, "setSubtitleTrack"); | |
Message msg; | |
yi::rapidjson::Value subtitleTrackValue(subtitleTrack.data(), msg.messageAllocator); | |
msg.addArgument(subtitleTrackValue); | |
callTizenWithArgs("setSubtitleTrack", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, setAudioTrack)(const std::string& audioTrack){ | |
YI_LOGD(TAG, "setAudioTrack"); | |
Message msg; | |
yi::rapidjson::Value audioTrackValue(audioTrack.data(), msg.messageAllocator); | |
msg.addArgument(audioTrackValue); | |
callTizenWithArgs("setAudioTrack", std::move(msg)); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getAudioTracks)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getAudioTracks"); | |
callTizenWithoutArgs("getAudioTracks", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getCurrentAudioTrack)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getCurrentAudioTrack"); | |
callTizenWithoutArgs("getCurrentAudioTrack", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getTimeshiftEnabled)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getTimeshiftEnabled"); | |
callTizenWithoutArgs("getTimeshiftEnabled", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getFFEnabled)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getFFEnabled"); | |
callTizenWithoutArgs("getFFEnabled", resolve, reject); | |
}; | |
YI_RN_DEFINE_EXPORT_METHOD(MKPlayerManager, getRWEnabled)(Callback resolve, Callback reject){ | |
YI_LOGD(TAG, "getRWEnabled"); | |
callTizenWithoutArgs("getRWEnabled", resolve, reject); | |
}; | |
void MKPlayerManager::onStateChange(const yi::rapidjson::Value &eventValue) { | |
reactInstance->EmitDirectEvent(MKPlayerView::onStateChangeName, {ToDynamic(eventValue)}); | |
} | |
void MKPlayerManager::onPlayerError(const yi::rapidjson::Value &eventValue) { | |
reactInstance->EmitDirectEvent(MKPlayerView::onErrorName, {ToDynamic(eventValue)}); | |
} | |
void MKPlayerManager::onPositionChange(const yi::rapidjson::Value &eventValue) { | |
reactInstance->EmitDirectEvent(MKPlayerView::onPositionChangeName, {ToDynamic(eventValue)}); | |
} | |
uint64_t MKPlayerManager::registerEventHandler(const CYIString &eventName, CYIWebMessagingBridge::EventCallback &&eventCallback) | |
{ | |
return CYIWebBridgeLocator::GetWebMessagingBridge()->RegisterEventHandler(TIZEN_CLASS_NAME, eventName.GetData(), std::move(eventCallback)); | |
} | |
void MKPlayerManager::unregisterEventHandler(uint64_t &eventHandlerId) | |
{ | |
CYIWebBridgeLocator::GetWebMessagingBridge()->UnregisterEventHandler(eventHandlerId); | |
eventHandlerId = 0; | |
} | |
void MKPlayerManager::registerEventHandlers() | |
{ | |
if (messageHandlersRegistered) | |
{ | |
return; | |
} | |
registeredEvents.push_back(registerEventHandler("onStateChange", std::bind(&MKPlayerManager::onStateChange, this, std::placeholders::_1))); | |
registeredEvents.push_back(registerEventHandler("onPlayerError", std::bind(&MKPlayerManager::onPlayerError, this, std::placeholders::_1))); | |
registeredEvents.push_back(registerEventHandler("onPositionChange", std::bind(&MKPlayerManager::onPositionChange, this, std::placeholders::_1))); | |
messageHandlersRegistered = true; | |
} | |
void MKPlayerManager::unregisterEventHandlers() | |
{ | |
if (!messageHandlersRegistered) | |
{ | |
return; | |
} | |
for (auto &event : registeredEvents) { | |
unregisterEventHandler(event); | |
} | |
registeredEvents.clear(); | |
messageHandlersRegistered = false; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MKPlayerView.h" | |
#include <youireact/ViewBuilder.h> | |
#include <youireact/NativeModuleRegistry.h> | |
#include <youireact/props/DirectEventTypes.h> | |
#include <youireact/IBridge.h> | |
using namespace yi::react; | |
#define LOG_TAG "MKPlayerView" | |
YI_TYPE_DEF_INST(MKPlayerView, ShadowView) | |
YI_RN_REGISTER_VIEW_MODULE(MKPlayerView); | |
YI_RN_DEFINE_DIRECT_EVENT_NAME(MKPlayerView, onStateChangeName); | |
YI_RN_DEFINE_DIRECT_EVENT_NAME(MKPlayerView, onPositionChangeName); | |
YI_RN_DEFINE_DIRECT_EVENT_NAME(MKPlayerView, onErrorName); | |
MKPlayerView::MKPlayerView() | |
: CYIVideoSurfacePlatform(CYIVideoSurface::Capabilities::Translate | CYIVideoSurface::Capabilities::Scale | CYIVideoSurface::Capabilities::Opacity) | |
{ | |
SetDirectEvent(MKPlayerView::onStateChangeName, onStateChange); | |
SetDirectEvent(MKPlayerView::onPositionChangeName, onPositionChange); | |
SetDirectEvent(MKPlayerView::onErrorName, onError); | |
} | |
MKPlayerView::~MKPlayerView() | |
{ | |
playerManager = nullptr; | |
} | |
std::unique_ptr<CYISceneNode> MKPlayerView::CreateCounterpart(CYISceneManager *pSceneManager) | |
{ | |
return ViewBuilder::CreateVideoView(pSceneManager, glm::vec3(1.0f, 1.0f, 1.0f)); | |
} | |
bool MKPlayerView::OnInit() { | |
playerManager = GetBridge().GetModule<MKPlayerManager>(); | |
GetCounterpart()->SetVideoSurface(this); | |
return true; | |
} | |
const CYIVideoSurfaceView *MKPlayerView::GetCounterpart() const | |
{ | |
return static_cast<const CYIVideoSurfaceView *>(ShadowView::GetCounterpart()); | |
} | |
CYIVideoSurfaceView *MKPlayerView::GetCounterpart() | |
{ | |
return static_cast<CYIVideoSurfaceView *>(ShadowView::GetCounterpart()); | |
} | |
void MKPlayerView::OnLayoutApplied() | |
{ | |
ShadowView::OnLayoutApplied(); | |
auto pVideoNode = GetCounterpart()->GetNode("_VideoNode"); | |
pVideoNode->SetSize(GetCounterpart()->GetSize()); | |
EmitDirectEvent(DirectEvents::onLayout); | |
} | |
void MKPlayerView::SetVideoRectangle(const YI_RECT_REL &rVideoRectangle) | |
{ | |
if (playerManager) { | |
playerManager->handleRectangleUpdate(rVideoRectangle); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <youireact/nodes/ShadowView.h> | |
#include <player/YiVideoSurfaceView.h> | |
#include <player/YiVideoSurfacePlatform.h> | |
#include <youireact/props/DirectEventTypes.h> | |
#include "MKPlayerManager.h" | |
using namespace yi::react; | |
class MKPlayerView | |
: public ShadowView, public CYIVideoSurfacePlatform | |
{ | |
public: | |
MKPlayerView(); | |
virtual ~MKPlayerView() final; | |
YI_RN_EXPORT_NAME(MKPlayerView); | |
YI_RN_DECLARE_MANAGER(MKPlayerManager); | |
virtual const CYIVideoSurfaceView *GetCounterpart() const override; | |
virtual CYIVideoSurfaceView *GetCounterpart() override; | |
virtual bool OnInit() override; | |
virtual void SetVideoRectangle(const YI_RECT_REL &rVideoRectangle) override; | |
MKPlayerManager * playerManager; | |
YI_RN_EXPORT_DIRECT_EVENT(onStateChange); | |
YI_RN_EXPORT_DIRECT_EVENT_NAME(onStateChangeName); | |
YI_RN_EXPORT_DIRECT_EVENT(onPositionChange); | |
YI_RN_EXPORT_DIRECT_EVENT_NAME(onPositionChangeName); | |
YI_RN_EXPORT_DIRECT_EVENT(onError); | |
YI_RN_EXPORT_DIRECT_EVENT_NAME(onErrorName); | |
private: | |
virtual std::unique_ptr<CYISceneNode> CreateCounterpart(CYISceneManager *pSceneManager) final; | |
virtual void OnLayoutApplied() final; | |
YI_TYPE_BASES(MKPlayerView, ShadowView); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment