我正在使用React Native创建一个Android / iOS应用程序,并尝试在WebView组件中播放视频。视频在iOS上运行正常,但我无法在Android WebView中播放它。
我遇到过像这样的一些线程(在Android WebView中启用HTML5视频播放?)声称这是Android上相当常见的问题,可以通过导入WebChromeClient并在webview上设置该选项来解决:
mainWebView.setWebChromeClient(new WebChromeClient());
但几乎所有这些线程都严格关于构建原生Android应用程序而不使用React Native。
有谁知道如何在React Native中使用它?
我指的是 Yevgen Safronov撰写的文章
在其中,他写道
显然,应用程序中最具挑战性的部分是处理
直播视频流,因为它需要切换流的视频
基于可用互联网带宽的质量。但首先是事情
首先 - 我需要一个RN原生组件来显示任何视频流。那里
是RN的流行视频组件,但它仅支持iOS。一世
决定在Vitamio播放器周围编写自己的RN组件包装器。它
是众所周知的开源项目,我们支持RTMP协议
用于移动应用。
我以前没有写过本机RN组件的经验,所以我去了
直接向RN文档介绍如何创建一个。我指的是一个指南
被称为Native UI Components,与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();
}
...
}
代码看起来非常简单。除了传递参考
要激活到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 setter:
@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);
注册模块尽管没有按步骤提及
我们需要它的官方文档,因为它引用了root
活动:包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;
希望这是有帮助的,文章中给出了他自己的参考文献列表。