react native 实现surfaceview播放视频

本文在react native的js页面中调用android层写的surfaceview播放视频


1.我们搭建好rn环境后,创建rn项目并运行到设备上(本文省略),在项目的目录下 /android/app/src/main/java/com/项目名/ 下自定义一个surfaceview(mediaplayer也在其中)

package com.untitled;

import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

/**
 * Created by zjh on 17-7-20.
 */

public class MyPlay extends SurfaceView implements SurfaceHolder.Callback{
    private MediaPlayer player = new MediaPlayer();
    String uri="http://192.168.1.110:8080/background.mp4";//这是本人以本机搭的服务器,请务必换个url来测试
    SurfaceHolder holder;

    public MyPlay(Context context) {
        super(context);
        try {
            player.setDataSource(context, Uri.parse(uri));
            holder=this.getHolder();
            holder.addCallback(this);
            player.prepare();
            player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    player.start();
                    player.setLooping(true);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void vRestart(){
        player.start();
    }

    public void vPause(){
        player.pause();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        player.setDisplay(holder);
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}

2.在android/app/src/main/java/com/项目名/ 下新建一个ReactVideo类,继承SimpleViewManager泛型为自己自定义的MyPlay

package com.untitled;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;

import java.util.Map;

import javax.annotation.Nullable;

public class ReactVideo extends SimpleViewManager<MyPlay> {
    private static final int COMMAND_PAUSE_ID = 1;
    private static final String COMMAND_PAUSE_NAME = "pause";
    private static final int COMMAND_START_ID = 2;
    private static final String COMMAND_START_NAME = "start";

    @Override
    public String getName() {
        return "RV";
    }

    @Override
    protected MyPlay createViewInstance(ThemedReactContext reactContext) {
        MyPlay view = new MyPlay(reactContext);
        return view;
    }

    @Nullable
    @Override
    public Map<String, Integer> getCommandsMap() {
        return MapBuilder.of(
                COMMAND_PAUSE_NAME,COMMAND_PAUSE_ID,
                COMMAND_START_NAME,COMMAND_START_ID
        );
    }

    @Override
    public void receiveCommand(MyPlay root, int commandId, @Nullable ReadableArray args) {
        switch (commandId){
            case COMMAND_PAUSE_ID:
                root.vPause();
                break;
            case COMMAND_START_ID:
                root.vRestart();
                break;
            default:
                break;
        }
    }
}

3.在android/app/src/main/java/com/项目名/ 下新建一个package类,继承reactapplication,在其中实现createViewManagers方法,并将上一步的ReactVideo添加到集合中(注:0.47.0已经没有了createJSModules(),下面重写的方法如果没有返回值不要直接return null;会报错,用return Collections.emptyList();)

package com.untitled;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MyPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<Classextends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList(
                new ReactVideo()
        );
    }
}

4.在创建项目就有的android/app/src/main/java/com/项目名/mianapplication中的getpackages创建上步的package实例

package com.untitled;

import android.app.Application;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new MyPackage()//这里!!!
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
  }
}

5.在项目根目录下创建Vv.js

'use strict';
import React,{ Component,PropTypes }from 'react';
import {
    requireNativeComponent,
    View,
    UIManager,
    findNodeHandle,
}from 'react-native';

var RCT_VIDEO_REF = 'VideoView';
class VideoView extends Component {
    constructor(props) {
        super(props);
    }
    pause(){
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.refs[RCT_VIDEO_REF]),
            UIManager.RV.Commands.pause,
            null
        );
    }

    start(){
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.refs[RCT_VIDEO_REF]),
            UIManager.RV.Commands.start,
            null
        );
    }
    render(){
        return <RCTVideoView
            {...this.props}
            ref = {RCT_VIDEO_REF}
        />;
    };
}
VideoView.propTypes = {
    style: View.propTypes.style,
    ...View.propTypes,
};

var RCTVideoView = requireNativeComponent('RV',VideoView,{
    nativeOnly: {onChange: true}
});
module.exports = VideoView;

6.最后在js代码中调用就可以,在创建项目就有的项目根目录下android的js入口文件,index.android.js中添加

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  NativeModules,
    processColor,
    TouchableOpacity
} from 'react-native';
import VideoView from './Vv';

export default class untitled extends Component {
    onPressPause(){
        this.video.pause();
    }

    onPressStart(){
        this.video.start();
    }

    render() {
    return (
      
        450,width:580}}
            ref={(video)=>{this.video = video}}
           // seturl='http://192.168.1.110:8080/background.mp4'
        />
        50,flexDirection:'row',justifyContent:'flex-start'}}>
          10}} onPress={this.onPressPause.bind(this)}>
            暂停
          
          10}} onPress={this.onPressStart.bind(this)}>
            开始
          
        
      
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});
AppRegistry.registerComponent('untitled', () => untitled);

这样一个简单的播放器就完成了
本文参考:https://github.com/helengray/XiFan(稀饭的项目功能更加强大,不过用的是VideoView实现)

你可能感兴趣的:(react,native)