How to make jwplayer fullscreen in react-native
Asked Answered
E

0

2

I am planning to use jwplayer in react-native. As of now there is no working jwplayer react-native plugin available on Github, so i am working on a Native module that will render jwplayer in react-native.

I am able to render video in react-native using a native module and also able to play video and able to receive play, pause other events in react-native.

But I have a problem with fullscreen mode(it is working properly in non-fullscreen mode) When I click JwPlayer fullscreen button then app screen goes to black and come back after video complete. During the blackout, I am able to hear audio but a video is not visible on mode.

Here is a code:

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',
  }
});

When app in portrait mode and if you click a fullscreen button of player then it will blackout screen. I don't what things need to do to make is fullscreen I am not having any ios native development experience.

Version details

react-native:0.55.1

PODS: - JWPlayer-SDK (3.1.4)

Here is a video link which shows what is happening: LINK

Thanks in advance.

Eijkman answered 1/11, 2018 at 7:17 Comment(8)
There are similar problems in this regard: Maybe this can help youHullda
@DonnyMotta: Thanks for reference, it had fixed my android problem but i am not able to find solution for iosEijkman
@George : here is issue i had describe here for my ios full screen issue.Eijkman
@BhaveshJariwala Check here github.com/jwplayer/jwplayer-sdk-ios-demo/blob/master/…Courses
So in JwPlayerWrapper.m add this line try self.player. fullscreen = TRUE;Courses
@MAhipalSingh: It was there, was not working so i had removed it. It is only there to send fullscreen status to javascriptEijkman
In onFullscreen why do you set heightX: width, widthX: height,?Velda
@George: To change layout size for video, This thing is working fine in android. In ios not working. Are you using any different approach to achieve fullscreen??Eijkman

© 2022 - 2024 — McMap. All rights reserved.