React Native Android Webview Video

And*_*Tet 11 javascript video android webview react-native

我正在使用React Native创建一个Android/iOS应用程序,并尝试在WebView组件中播放视频.视频在iOS上运行正常,但我无法在Android WebView中播放它.

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

mainWebView.setWebChromeClient(new WebChromeClient());
Run Code Online (Sandbox Code Playgroud)

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

有谁知道如何在React Native中使用它?

Rac*_*len 9

我指的是Yevgen Safronov一篇文章

他写道,在里面

显然,该应用程序中最具挑战性的部分是处理实时视频流,因为它需要根据可用的Internet带宽切换流的视频质量.但首先要做的是 - 我需要一个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();
 }
...
}
Run Code Online (Sandbox Code Playgroud)

代码看起来非常简单.除了将对Activity的引用传递给LibsChecker之外,VideoView还需要一条路径来访问视频流和MediaController的实例.

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

使用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();       
}
Run Code Online (Sandbox Code Playgroud)

添加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;
}
Run Code Online (Sandbox Code Playgroud)

注册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)
    );    
  }
}
Run Code Online (Sandbox Code Playgroud)

实现JavaScript模块为了在JavaScript中公开自定义UI组件,有必要调用特殊的requireNativeComponent函数:

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

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

module.exports = requireNativeComponent('RCTVitamioView', iface);
Run Code Online (Sandbox Code Playgroud)

注册模块虽然在官方文档中没有提到它作为必需步骤,但我们需要它,因为参考了根活动: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
      );
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例在项目中安装包:

npm i react-native-android-vitamio --save
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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