问题 React Native Android Webview Video


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

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

mainWebView.setWebChromeClient(new WebChromeClient());

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

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


7237
2018-06-15 05:44


起源

你试过这个插件吗? github.com/brentvatne/react-native-video - diedu
是的,这与我正在寻找的略有不同。我希望在webview中显示来自和在线视频播放器的嵌入链接,这样我就可以使用他们的网络播放器以及它们内置的所有功能(回滚30秒,全屏等)。 React-native-video只是一个允许您播放视频的组件,但需要我直接链接到源以及重新创建播放器的所有UI。如果我不能解决这个问题,我可能最终会这样做。谢谢! - AndrewTet
你有vsn .27吗?它支持android .. facebook.github.io/react-native - Rachel Gallen
是的,我正在使用.27。 webview本身运行正常。它只是试图在其中播放HTML5视频。 - AndrewTet
我有同样的问题,你有没有让这个工作? - Greg


答案:


我指的是 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;

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


9
2018-06-20 22:54