我计划在react-native中使用jwplayer。截至目前,Github上没有可用的jwplayer react-native插件,因此我正在开发一个Native模块,该模块将在react-native中呈现jwplayer。
我能够使用本机模块在react-native中渲染视频,还能够播放视频并能够接收播放信息,并在react-native中暂停其他事件。
但是我在全屏模式下有问题(在非全屏模式下可以正常工作)当我单击JwPlayer全屏按钮时,应用程序屏幕变黑,并在视频播放完成后返回。在停电期间,我可以听到音频,但是在模式下看不到视频。
这是一个代码:
JavascriptBridgeJsFile
import React, { Component } from 'react'
import { requireNativeComponent } from 'react-native'
export default class JwPlayerWrapperView extends Component {
setNativeProps = nativeProps => {
if (this._root) {
this._root.setNativeProps(nativeProps);
}
}
render() {
return <JwPlayerWrapper
ref={e => (this._root = e)}
{...this.props}
onFullScreen={event =>
this.props.onFullScreen && this.props.onFullScreen(event.nativeEvent)
}
/>
}
}
const JwPlayerWrapper = requireNativeComponent('JwPlayerWrapper', JwPlayerWrapperView)
JwPlayerWrapper.h
#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import <JWPlayer_iOS_SDK/JWPlayerController.h>
#import <React/UIView+React.h>
@class RCTEventDispatcher;
@interface JwPlayerWrapper : UIView
// Define view properties here with @property
@property(nonatomic, strong) JWPlayerController *player;
@property(nonatomic, assign) NSString *playList;
@property (nonatomic, assign) NSString *exampleProp;
@property (nonatomic, copy) RCTDirectEventBlock onFullScreen;
// Initializing with the event dispatcher allows us to communicate with JS
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
@end
JwPlayerWrapper.m
#import <Foundation/Foundation.h>
#import "JwPlayerWrapper.h"
#import <JWPlayer_iOS_SDK/JWPlayerController.h>
// import RCTEventDispatcher
#if __has_include(<React/RCTEventDispatcher.h>)
#import <React/RCTEventDispatcher.h>
#elif __has_include("RCTEventDispatcher.h")
#import "RCTEventDispatcher.h"
#else
//#import "React/RCTEventDispatcher.h" // Required when used as a Pod in a Swift project
#endif
@interface JwPlayerWrapper () <JWPlayerDelegate>
@end
@implementation JwPlayerWrapper : UIView {
RCTEventDispatcher *_eventDispatcher;
JWConfig *config;
}
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
if ((self = [super init])) {
_eventDispatcher = eventDispatcher;
config = [[JWConfig alloc] init];
config.file = @"https://content.jwplatform.com/manifests/yp34SRmf.m3u8";
config.controls = YES; //default
config.playbackRateControls = TRUE;
config.audioSwitchingEnabled = TRUE;
config.stretching = TRUE;
config.displayDescription = @"This is sample video description";
config.displayTitle = @"Cycling is good for health";
self.player = [[JWPlayerController alloc] initWithConfig:config];
self.player.delegate = self;
}
return self;
}
-(void)layoutSubviews
{
[super layoutSubviews];
self.player.forceFullScreenOnLandscape = YES;
self.player.forceLandscapeOnFullScreen = YES;
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth;
self.player.view.frame = self.bounds;
self.player.view.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
[self setAutoresizesSubviews:TRUE];
[self addSubview:self.player.view];
}
- (void)onFullscreen:(JWEvent<JWFullscreenEvent> *)event
{
// NSLog(@"-=======================================ON FULLSCREEN x EVENT '%d'---------------------", event.fullscreen);
if(self.onFullScreen)
{
self.onFullScreen(@{@"fullScreen":@(event.fullscreen)});
}
}
@end
JwPlayerWrapperManager.h
// import RCTViewManager
#if __has_include(<React/RCTViewManager.h>)
#import <React/RCTViewManager.h>
#elif __has_include(“RCTViewManager.h”)
#import “RCTViewManager.h”
#else
#import “React/RCTViewManager.h” // Required when used as a Pod in a Swift project
#endif
// Subclass your view manager off the RCTViewManager
// http://facebook.github.io/react-native/docs/native-components-ios.html#ios-mapview-example
@interface JwPlayerWrapperManager : RCTViewManager
@end
JwPlayerWrapperManager.m
#import <Foundation/Foundation.h>
#import "JwPlayerWrapper.h"
#import "JwPlayerWrapperManager.h"
#import <React/RCTUIManager.h>
// import RCTBridge
#if __has_include(<React/RCTBridge.h>)
#import <React/RCTBridge.h>
#elif __has_include(“RCTBridge.h”)
#import “RCTBridge.h”
#else
#import “React/RCTBridge.h” // Required when used as a Pod in a Swift project
#endif
@implementation JwPlayerWrapperManager
@synthesize bridge = _bridge;
// Export a native module
// https://facebook.github.io/react-native/docs/native-modules-ios.html
RCT_EXPORT_MODULE();
// Return the native view that represents your React component
- (UIView *)view
{
return [[JwPlayerWrapper alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
}
- (dispatch_queue_t)methodQueue {
return _bridge.uiManager.methodQueue;
}
RCT_EXPORT_VIEW_PROPERTY(exampleProp, NSString)
RCT_EXPORT_VIEW_PROPERTY(onFullScreen, RCTDirectEventBlock);
// Export constants
// https://facebook.github.io/react-native/releases/next/docs/native-modules-ios.html#exporting-constants
- (NSDictionary *)constantsToExport
{
return @{
@"EXAMPLE": @"example"
};
}
@end
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"JwPlayerDemo"
initialProperties:nil
launchOptions:launchOptions];
// rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
rootView.backgroundColor = [UIColor colorWithRed:0.00 green:0.00 blue:0.00 alpha:1.0];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
app.js
import React, { Component } from 'react';
import { StyleSheet, View, Dimensions } from 'react-native';
import JwPlayerWrapperView from './JwPlayerWrapper/JwPlayerWrapperNativeView'
let {
width,
height
} = Dimensions.get("window");
const videoWidth = width
const videoHeight = width / (16 / 9)
export default class App extends Component {
state = {
widthX: videoWidth,
heightX: videoHeight,
fullScreen: false
}
onFullScreen = (event) => {
console.log('onFullScreen: ', event.fullScreen)
this.setState({ fullScreen: event.fullScreen })
if (event.fullScreen) {
this.setState({
heightX: width,
widthX: height,
fullScreen: true
})
} else {
this.setState({
heightX: videoHeight,
widthX: videoWidth,
fullScreen: false
})
}
}
render() {
const { heightX, widthX } = this.state
return (
<View style={styles.container}>
<JwPlayerWrapperView
ref={ref => (this.player = ref)}
style={{ height: heightX, width: widthX }}
onFullScreen={this.onFullScreen}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
当应用程序处于纵向模式时,如果您单击播放器的全屏按钮,则该应用程序将黑屏。我不需要做任何事情就可以全屏显示,我没有任何ios本机开发经验。
版本详细信息
react-native:0.55.1
PODS: -JWPlayer-SDK(3.1.4)
以下是显示正在发生的事情的视频链接: LINK
谢谢。