我有一个(客户)网站,使用js brightcove player来呈现html5视频。 (阅读:我无法编辑网站本身)
在移动Chrome中视频有效,一切都很好。但是在我的Android应用中,使用呈现完全相同页面的WebView无法播放视频。
我已阅读了许多类似的SO问题,并确保完成以下操作:
有些帖子建议手动调用视频的play()方法,这不是一个好主意,但是,无论如何都不可能,因为brightcove播放器的视频标签在iframe中并且没有通过javascript获取它的方法。
到目前为止,我的想法已经不多了,问题可能是什么或在哪里。任何建议都非常感谢。 LogCat中唯一相关的日志消息是:
10-25 14:01:01.503: D/VideoLayerManager(1307): Reinit GLResource for VideoLayer
我的WEBVIEW设置
课程内容可以从这里下载goo.gl/GVtgD0。
webView = (WebView)findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.setSoundEffectsEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("file:///emulated/0/GA_nHanceK12/temp/class1-sub1-top2/index.html"));
从我这里来的日志
07-16 14:44:11.787: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.787: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.787: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.797: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.797: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.797: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.807: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.807: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.817: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.817: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.817: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.817: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.827: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.827: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.837: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.837: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.837: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.847: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.847: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.847: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.857: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.857: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.857: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.857: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.857: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.867: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.867: D/MediaPlayer_Java(27539): [FXN.ASD] setDataSource :: uri = file:////storage/emulated/0/GA_nHanceK12/temp/class1-sub1-top2/_cp_n_m_
07-16 14:44:11.867: E/MediaPlayer-JNI(27539): [FXN][ASD]getVideoSurfaceTexture: null surface texture
07-16 14:44:11.867: E/MediaPlayer(27539): error (1, -2147483648)
07-16 14:44:11.917: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.917: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.917: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.917: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.927: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.927: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.927: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.927: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.927: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:11.937: E/MediaPlayer_Java(27539): Error (1,-2147483648)
07-16 14:44:12.488: D/VideoLayerManager(27539): Reinit GLResource for VideoLayer
答案 0 :(得分:2)
This answer可能会回答您的问题。
我尝试使用API 16(4.1 JB),但只有在全屏时才会播放此sample Brightcove video。
您可以在全屏模式下强制启动视频,并在用户要求或视频播放完毕时将其退出。
我认为这是由WebView类本身引起的,因为4.1 JellyBean是从Android浏览器到Google Chrome的过渡。虽然较新的4.1版本的默认浏览器变为Chrome,但WebView仍然使用旧引擎,因此无法正确呈现视频。
另一个解决方案是重定向用户并强迫他使用他的浏览器(如果你很幸运,那就是Chrome,视频将会显示)。
答案 1 :(得分:0)
这可能没有帮助,但您应该只为download the source for Firefox安卓,并将其捆绑到您的应用中,如果它让您的生活更轻松。我为一个需要websockets的项目做了这个,我们需要向后兼容。
答案 2 :(得分:0)
我曾在Android上使用html5视频播放,这对我有用:
我的活动
public class Test extends Activity {
HTML5WebView mWebView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView = new HTML5WebView(this);
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
mWebView.loadUrl("http://player.vimeo.com/video/27244727");
}
setContentView(mWebView.getLayout());
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mWebView.saveState(outState);
}
@Override
public void onStop() {
super.onStop();
mWebView.stopLoading();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mWebView.inCustomView()) {
mWebView.hideCustomView();
// mWebView.goBack();
//mWebView.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
我的自定义网页浏览
public class HTML5WebView extends WebView {
private Context mContext;
private MyWebChromeClient mWebChromeClient;
private View mCustomView;
private FrameLayout mCustomViewContainer;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private FrameLayout mContentView;
private FrameLayout mBrowserFrameLayout;
private FrameLayout mLayout;
static final String LOGTAG = "HTML5WebView";
private void init(Context context) {
mContext = context;
Activity a = (Activity) mContext;
mLayout = new FrameLayout(context);
mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);
mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
// Configure the webview
WebSettings s = getSettings();
s.setBuiltInZoomControls(true);
s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
s.setUseWideViewPort(true);
s.setLoadWithOverviewMode(true);
// s.setSavePassword(true);
s.setSaveFormData(true);
s.setJavaScriptEnabled(true);
mWebChromeClient = new MyWebChromeClient();
setWebChromeClient(mWebChromeClient);
setWebViewClient(new WebViewClient());
setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
// enable navigator.geolocation
// s.setGeolocationEnabled(true);
// s.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");
// enable Web Storage: localStorage, sessionStorage
s.setDomStorageEnabled(true);
mContentView.addView(this);
}
public HTML5WebView(Context context) {
super(context);
init(context);
}
public HTML5WebView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public FrameLayout getLayout() {
return mLayout;
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((mCustomView == null) && canGoBack()){
goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private class MyWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
{
//Log.i(LOGTAG, "here in on ShowCustomView");
HTML5WebView.this.setVisibility(View.GONE);
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomViewContainer.addView(view);
mCustomView = view;
mCustomViewCallback = callback;
mCustomViewContainer.setVisibility(View.VISIBLE);
}
@Override
public void onHideCustomView() {
System.out.println("customview hideeeeeeeeeeeeeeeeeeeeeeeeeee");
if (mCustomView == null)
return;
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
mCustomViewContainer.removeView(mCustomView);
mCustomView = null;
mCustomViewContainer.setVisibility(View.GONE);
mCustomViewCallback.onCustomViewHidden();
HTML5WebView.this.setVisibility(View.VISIBLE);
HTML5WebView.this.goBack();
//Log.i(LOGTAG, "set it to webVew");
}
@Override
public View getVideoLoadingProgressView() {
//Log.i(LOGTAG, "here in on getVideoLoadingPregressView");
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
}
return mVideoProgressView;
}
@Override
public void onReceivedTitle(WebView view, String title) {
((Activity) mContext).setTitle(title);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
((Activity) mContext).getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress*100);
}
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
}
static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
<强> custom_screen.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout android:id="@+id/fullscreen_custom_content"
android:visibility="gone"
android:background="@color/black"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="@+id/error_console"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<FrameLayout android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</FrameLayout>
<强> video_loading_progress.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progress_indicator"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar android:id="@android:id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView android:paddingTop="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="loading_video" android:textSize="14sp"
android:textColor="?android:attr/textColorPrimary" />
</LinearLayout>