本文在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<Class extends 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实现)