2016-06-15 164 views
9

我正在使用React Native创建Android/iOS应用程序,并试图让视频在WebView组件中播放。该视频在iOS上播放良好,但我无法在Android WebView中播放。React Native Android Webview视频

我遇到几个线程一样,声称这是Android上的一个相当普遍的问题,可以通过导入WebChromeClient并设置该选项上的WebView像这样来解决这一个(Enabling HTML5 video playback in android WebView?):

mainWebView.setWebChromeClient(new WebChromeClient()); 

但几乎所有这些线程都严格构建原生Android应用程序,而不是使用React Native。

有谁知道如何让它在React Native中工作?

+0

你有没有试过这个插件https://github.com/brentvatne/react-native-video – diedu

+0

是的,这与我所寻找的略有不同。我正在寻找在webview中显示来自于在线视频播放器的嵌入式链接,以便我可以使用他们的网络播放器及其内置的所有功能(回退30秒,全屏等)。 React-native-video只是一个允许您播放视频的组件,但需要我直接链接到源代码以及重新创建播放器的所有UI。如果我不能解决这个问题,我可能会这样做。虽然谢谢! – AndrewTet

+0

你有vsn .27吗?它支持android .. http://facebook.github.io/react-native/ –

回答

8

我指的是article by Yevgen Safronov

在书中,他写道

显然,应用程序的最具挑战的部分是处理 实时视频流,因为它需要根据现有的切换流的视频 质量互联网带宽。但首先 首先 - 我需要一个RN本地组件显示任何视频流。有 是一款流行的RN视频组件,但它仅支持iOS。我 决定写我自己的围绕维塔米奥球员的RN组件包装。它是 是众所周知的开源项目,并支持RTMP协议我们 用于移动应用程序。

我以前没有编写本地RN组件的经验,所以我直接去 到RN文档,了解如何创建一个。我参考 的指南称为本地用户界面组件,对于iOS也有类似的指导。有 的声明几个基本部分组成:

实现自定义ViewManager(Android部分)
注册ViewManager(Android部分)
实现JavaScript的模块
注册模块(Android部分)

实现自定义ViewManager参考声明 VideoView for Vitamio的示例,这是VideoView声明 的本质如何:

public class VideoViewDemo extends Activity { 
@Override public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    if (!LibsChecker.checkVitamioLibs(this)) 
    return; 
    setContentView(R.layout.videoview); 
    mEditText = (EditText) findViewById(R.id.url); 
    mVideoView = (VideoView) findViewById(R.id.surface_view); 
    if (path == "") { return; } 
    mVideoView.setVideoPath(path); 
    mVideoView.setMediaController(new MediaController(this)); 
    mVideoView.requestFocus(); 
} 
... 
} 

该代码看起来很简单。除了将参考 传递给Activity到LibsChecker之外,VideoView还需要一个指向视频 流和MediaController实例的路径。

public class VitamioViewManager extends SimpleViewManager<VideoView>{ 
public static final String REACT_CLASS = “RCTVitamioView”; 
@Override 
public String getName() { 
    return REACT_CLASS; 
} 

使用ReactProp暴露setStreamUrl二传手:

@ReactProp(name = "streamUrl") 
public void setStreamUrl(VideoView view, @Nullable String streamUrl) { 
    if (!LibsChecker.checkVitamioLibs(mActivity)) 
     return; 

    view.setVideoPath(streamUrl);  
    view.setMediaController(new MediaController(mContext)); 
    view.requestFocus();  
} 

添加createViewInstance实现:

private ThemedReactContext mContext = null; 
private Activity mActivity = null; 
@Override 
public VideoView createViewInstance(ThemedReactContext context){ 
    mContext = context; 
    return new VideoView(context); 
} 
One note about the code. Because LibsChecker requires an instance of Activity we will receive it via constructor, it will reference root activity used for RN application; 
public VitamioViewManager(Activity activity) { 
    mActivity = activity; 
} 

注册ViewManager 最后Java的一步是将ViewManager注册申请,这通过应用程序包成员函数createViewManagers发生: ...

public class VitamioViewPackage implements ReactPackage { 

    private Activity mActivity = null; 

    public VitamioViewPackage(Activity activity) { 
     mActivity = activity; 
    } 


    @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 VitamioViewManager(mActivity) 
    );  
    } 
} 

实现JavaScript的模块为了揭露自定义UI组件 在JavaScript中,需要调用特殊requireNativeComponent 功能:

var { requireNativeComponent, PropTypes } = require('react-native'); 

var iface = { 
    name: 'VideoView', 
    propTypes: { 
    streamUrl: PropTypes.string 
    } 
}; 

module.exports = requireNativeComponent('RCTVitamioView', iface); 

注册模块虽然没有提及 官方文档中需要的步骤,但我们需要它,因为参考到根 活动:package com.vitamio_demo;用法 的

import com.facebook.react.ReactActivity; 
import com.facebook.react.ReactPackage; 
import com.facebook.react.shell.MainReactPackage; 

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

import com.sejoker.VitamView.VitamioViewPackage; // <--- import 

public class MainActivity extends ReactActivity { 

    /** 
    * Returns the name of the main component registered from JavaScript. 
    * This is used to schedule rendering of the component. 
    */ 
    @Override 
    protected String getMainComponentName() { 
     return "vitamio_demo"; 
    } 

    /** 
    * Returns whether dev mode should be enabled. 
    * This enables e.g. the dev menu. 
    */ 
    @Override 
    protected boolean getUseDeveloperSupport() { 
     return BuildConfig.DEBUG; 
    } 

    /** 
    * A list of packages used by the app. If the app uses additional views 
    * or modules besides the default ones, add more packages here. 
    */ 
    @Override 
    protected List<ReactPackage> getPackages() { 
     return Arrays.<ReactPackage>asList(
     new MainReactPackage(), 
     new VitamioViewPackage(this)   // <------ add here 
    ); 
    } 
} 

实施例中的一个项目安装软件包:

npm i react-native-android-vitamio --save 

DeclareVideoView:

var VitamioView = require('react-native-android-vitamio'); 

class VideoScreen extends React.Component { 
    render() { 
    return (
     <View> 
     <VitamioView style={styles.video} streamUrl="rtmp://fms.12E5.edgecastcdn.net/0012E5/mp4:videos/8Juv1MVa-485.mp4"/> 
     </View> 
    ); 
    } 
} 


var styles = StyleSheet.create({ 
    video: { 
     flex: 1, 
     flexDirection: 'row', 
     height: 400, 
    } 
}) 

module.exports = VideoScreen; 

希望这有帮助,他自己的参考文献列表在文章中给出。