反应原生的Android Webvideo

我正在使用React Native创build一个Android / iOS应用程序,并尝试让video在WebView组件中播放。 video在iOS上播放很好,但我无法在Android WebView中播放。

我遇到过这样的几个线程( 在Android WebView中启用HTML5video播放? ),声称这是一个相当普遍的问题在Android上,可以通过导入WebChromeClient并在webview上设置该选项来解决,如下所示:

mainWebView.setWebChromeClient(new WebChromeClient()); 

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

有谁知道如何让这个工作在React Native?

我提到叶夫根·萨夫罗诺夫(Yevgen Safronov)的一篇文章

他写道

显然,应用程序中最具挑战性的部分是处理实况videostream,因为它要求根据可用的互联网带宽切换videostream的质量。 但首先,我需要一个RN本地组件来显示任何videostream。 有一个stream行的RNvideo组件,但它只支持iOS。 我决定在Vitamio玩家身边编写我自己的RN组件包装。 这是众所周知的开源项目,并支持我们用于移动应用程序的RTMP协议。

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

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

实现自定义ViewManager参考为Vitamio声明VideoView的例子,这是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的videostream和实例的path。

 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模块为了在JavaScript中公开自定义UI组件,有必要调用特殊的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 eg 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; 

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