2016-06-15 78 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; 

希望這有幫助,他自己的參考文獻列表在文章中給出。