React-native UI Component,从任务/菜单按钮

时间:2017-04-09 10:06:12

标签: android react-native

我想创建android组件,在这个组件中我有视频播放器,使用MediaPlayer和SurfaceTexture。当我在示例应用程序中尝试compoent时,它工作正常。但是,当我试图按下主页按钮(Android设备中的圆形按钮),然后从历史记录关闭运行应用程序再次打开应用程序(按下按钮任务/菜单,然后单击应用程序),媒体播放器未正常调用。但如果我再次单击应用程序图标,则媒体播放器正常工有谁知道会发生什么?

我尝试记录,当我从后台应用程序恢复它时,它说

04-09 17:42:13.160 330-22013/? E/MediaPlayerService: setVideoSurfaceTexture failed: -19
04-09 17:44:49.944 453-453/com.videofiltertest E/MediaPlayer: pause called in state 0
04-09 17:44:49.945 453-453/com.videofiltertest E/MediaPlayer: error (-38, 0)

感谢。

这是我的原生组件代码。

public class VideoPlayer extends TextureView implements TextureView.SurfaceTextureListener, LifecycleEventListener, MediaPlayer.OnPreparedListener{

private static final String TAG = VideoThumbnail.class.getSimpleName();
public MediaPlayer mMediaPlayer;
public VideoTextureRenderer mRenderer;
private int surfaceWidth;
private int surfaceHeight;
private ThemedReactContext mContext;
private String videoPath;
private String fragmentShaderCode = null;

private boolean isCrop = false;
private boolean isAutoPlay = false;
private boolean isLooping = false;
private boolean mediaPlayerReady = false;
private boolean isTextureAvailable = false;

private SurfaceTexture surfaceTexture;
private SurfaceTexture surface = null;
private int xpos;

private int seekto = 0;

private boolean isPaused = false;
private boolean isCreated = false;
private boolean mediaPlayerPrepared = false;


public VideoPlayer(ThemedReactContext context) {
    super(context);
    mContext = context;
    mContext.addLifecycleEventListener(this);
    this.setSurfaceTextureListener(this);
}

public VideoPlayer(ThemedReactContext context, AttributeSet attrs) {
    super(context, attrs);
    mContext = context;
    mContext.addLifecycleEventListener(this);
    this.setSurfaceTextureListener(this);
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    surfaceHeight = View.MeasureSpec.getSize(heightMeasureSpec);
    surfaceWidth = View.MeasureSpec.getSize(widthMeasureSpec);
    this.setMeasuredDimension(surfaceWidth, surfaceWidth);
}

private void getSurface(){
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (surface != null) {
                try {
                    mMediaPlayer.setDataSource(videoPath);
                    mMediaPlayer.prepare();
                    isCreated = true;
                } catch (IOException e) {
                    Log.e("DEBUG", e.toString());
                    throw new RuntimeException("Could not open input video!");
                }
            } else {
                surface =  mRenderer.getVideoTexture();
                getSurface();
            }
        }
    }, 1000);
}

private void setup(){

    if(mMediaPlayer == null){
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(this);
    }
    if(mRenderer == null){
        mRenderer = new VideoTextureRenderer(mContext, surfaceTexture, surfaceWidth, surfaceWidth );
    }

    getSurface();
}

public void setSource(String src){
    videoPath = src;
}

public void setFilter(int filterCode){
    switch (filterCode){
        ...
    }

    if(mediaPlayerReady){
        mMediaPlayer.start();
        mRenderer.setShader(fragmentShaderCode);
    }
}

public void setCrop(boolean isCrop){
    this.isCrop = isCrop;
    if(mediaPlayerReady){
        if(!mMediaPlayer.isPlaying()){
            mMediaPlayer.start();
        }
        mRenderer.setCrop(this.isCrop);
    }
}

public void togglePlayPause(){
    if(mediaPlayerReady){
        if(!mMediaPlayer.isPlaying()){
            mMediaPlayer.start();
        }else{
            mMediaPlayer.pause();
        }
    }
}

public boolean isPlaying(){
    if(mediaPlayerReady){
        return mMediaPlayer.isPlaying();
    }
    return false;
}

public void setPaused(){
    if(mediaPlayerReady){
        if(mMediaPlayer.isPlaying()){
            mMediaPlayer.pause();
        }
    }
}

public void setStop(){
    if(mediaPlayerReady){
        mMediaPlayer.stop();
    }
}

public void setStart(){
    if(mediaPlayerReady){
        if(!mMediaPlayer.isPlaying()){
            mMediaPlayer.start();
        }
    }
}

public void seekTo(int time){
    if(mediaPlayerReady){
        mMediaPlayer.seekTo(time);
    }else{
        seekto = time;
    }
}

public boolean isPlayerReady(){
    return mediaPlayerReady;
}

public int getCurrentPos(){
    if(mediaPlayerReady){
        return mMediaPlayer.getCurrentPosition();
    }
    return 0;
}

public int getDuration(){
    return mMediaPlayer.getDuration();
}

public void setAutoPlay(boolean isAutoPlay){
    this.isAutoPlay = isAutoPlay;
}

public void setLooping(boolean isLooping){
    this.isLooping = isLooping;
}

@Override
public void onHostResume() {
    if(isPaused){
        resume();
        isPaused = false;
    }
}

@Override
public void onHostPause() {
    pause();
}

@Override
public void onHostDestroy() {
    cleanup();
}

public void resume(){
    Log.e("DEBUG","IN RESUME");
}

public void pause(){
    Log.e("DEBUG","IN PAUSE ");
    if (mMediaPlayer != null){
        Log.e("DEBUG","!NULL MPLAYER");
        mMediaPlayer.pause();
        mMediaPlayer.setDisplay(null);
        mMediaPlayer.reset();
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
    if (mRenderer != null){
        Log.e("DEBUG","!NULL MRENDER");
        mRenderer.onPause();
        mRenderer = null;
    }

    surfaceTexture = null;
    mediaPlayerReady = false;
    isPaused = true;
}

public void cleanup() {
    Log.e("DEBUG", "CLEAN ");
    if(mMediaPlayer != null){
        mMediaPlayer.pause();
        mMediaPlayer.release();
    }
    if(mRenderer != null){
        mRenderer.onPause();
    }
}


@Override
public void onSurfaceTextureAvailable(final SurfaceTexture surface, int width, int height) {
    Log.e("DEBUG", "surface avalilable");
    isTextureAvailable = true;
    surfaceTexture = surface;
    surfaceWidth = width;
    surfaceHeight = height;
    setup();
}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    return false;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    Log.e("DEBUG", "MASUK ONPREPARED");

    final Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            mRenderer.setMediaPlayer(mMediaPlayer);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.setSurface(new Surface(surface));
            mRenderer.setDimension(mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight());
            mRenderer.setShader(fragmentShaderCode);
            mRenderer.setCrop(isCrop);

            if(!mMediaPlayer.isLooping()){
                mMediaPlayer.setLooping(isLooping);
            }

            if(isAutoPlay){
                mMediaPlayer.start();
            }else{
                mMediaPlayer.seekTo(seekto);
            }

            mediaPlayerReady = true;
        }
    });
    thread.run();        
}
}

这是UI管理器代码

public class RNVideoPlayerManager extends SimpleViewManager<VideoPlayer>{
private static final String REACT_CLASS = "RNVideoEditPlayer";

private static final String PROPS_SRC = "src";
private static final String PROPS_CROP = "isCrop";
private static final String PROPS_SEEK = "seekTo";
private static final String PROPS_AUTOPLAY = "isAutoPlay";
private static final String PROPS_LOOPING = "isLoop";
private static final String PROPS_FILTER = "filter";

@Override
public String getName(){
    return REACT_CLASS;
}

@Override
public VideoPlayer createViewInstance(ThemedReactContext themedReactContext){
    return new VideoPlayer(themedReactContext);
}

@Override
public void onDropViewInstance(VideoPlayer videoPlayer) {
    super.onDropViewInstance(videoPlayer);
    videoPlayer.cleanup();
}

@ReactProp(name = PROPS_SRC)
public void setSource(final VideoPlayer videoPlayer, final String src){
    videoPlayer.setSource(src);
}

@ReactProp(name = PROPS_CROP, defaultBoolean = false)
public void setCrop(final VideoPlayer videoPlayer, final boolean isCrop){
    videoPlayer.setCrop(isCrop);
}

@ReactProp(name = PROPS_SEEK, defaultInt = -1)
public void seekTo(final VideoPlayer videoPlayer, final int seekTime){
    if(seekTime > 0){
        videoPlayer.seekTo(seekTime);
    }else{
        return;
    }
}

@ReactProp(name = PROPS_AUTOPLAY, defaultBoolean = false)
public void setAutoPlay(final VideoPlayer videoPlayer, final boolean isAutoPlay){
    videoPlayer.setAutoPlay(isAutoPlay);
}

@ReactProp(name = PROPS_LOOPING, defaultBoolean = false)
public void setLoop(final VideoPlayer videoPlayer, final boolean isLoop){
    videoPlayer.setLooping(isLoop);
}

@ReactProp(name = PROPS_FILTER, defaultInt = 0)
public void setFilter(final VideoPlayer videoPlayer, final int filterId){
    videoPlayer.setFilter(filterId);
}
}

这是我的javascript组件代码

import React, { Component, PropTypes } from 'react'
import {
AppRegistry,
requireNativeComponent,
View
} from 'react-native'
var iface = {
name: 'VideoPlayer',
propTypes: {
    src : PropTypes.string,
    isCrop : PropTypes.bool,
    seekTo : PropTypes.number,
    isAutoPlay : PropTypes.bool,
    isLoop : PropTypes.bool,
    filter : PropTypes.number,
    ...View.propTypes,
}
}
const VideoPlayer = requireNativeComponent('RNVideoEditPlayer', iface)
export class VideoEditPlayer extends Component{
static propTypes = {
    src: PropTypes.string.isRequired,
    isCrop : PropTypes.bool,
    seekTo : PropTypes.number,
    isAutoPlay : PropTypes.bool,
    isLoop : PropTypes.bool,
    filter : PropTypes.number,
    style : PropTypes.object,
    ...View.propTypes, 
}
static defaultProps = {
    filter : 0,
    isCrop : false,
    isLoop : false,
    isAutoPlay : false,
}

constructor(props){
    super(props)
}

render(){
    const{
        src,
        isCrop,
        isLoop,
        isAutoPlay,
        seekTo,
        filter,
        style,
        ...props
    } = this.props
    return(
        <VideoPlayer
            style={style}
            src={src}
            isCrop={isCrop}
            isAutoPlay={isAutoPlay}
            isLoop={isLoop}
            filter={filter}
            seekTo={seekTo}
            {...props}
        />
    );
}
}

0 个答案:

没有答案