您的位置:首页 > 移动开发

安卓WebView中全屏播放网页视频

2016-12-28 11:30 381 查看
Android中WebView是支持播放网页视频的,需打开WebView的脚本支持:

activity_web_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<cn.cwkj.vediodemo.VideoEnabledWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>

<FrameLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:visibility="gone" />

</LinearLayout>


WebViewActivity

package cn.cwkj.vediodemo;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

public class WebViewActivity extends Activity {
private VideoEnabledWebView webView;
private LinearLayout parent;
private FrameLayout videoLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);

webView = (VideoEnabledWebView) findViewById(R.id.webView);
parent = (LinearLayout) findViewById(R.id.parent);
videoLayout = (FrameLayout) findViewById(R.id.videoLayout);

webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}

public void onPageStarted(WebView view, String url, Bitmap favicon) {
}

@Override
public void onPageFinished(WebView view, String url) {
}
});
webView.setWebChromeClient(new VideoEnabledWebChromeClient(this, parent, videoLayout));
//load url
webView.loadUrl("http://vedio.html");
}
}

package cn.cwkj.vediodemo;

import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;
import android.widget.VideoView;

public class VideoEnabledWebChromeClient extends WebChromeClient implements OnPreparedListener, OnCompletionListener, OnErrorListener {
public interface ToggledFullscreenCallback {
void toggledFullscreen(boolean fullscreen);
}

private View activityNonVideoView;
private ViewGroup activityVideoView;
private View loadingView;
private VideoEnabledWebView webView;
private boolean isVideoFullscreen; // Indicates if the video is being displayed using a custom view (typically full-screen)
private FrameLayout videoViewContainer;
private CustomViewCallback videoViewCallback;
private ToggledFullscreenCallback toggledFullscreenCallback;
private Activity mContext;

/**
* Never use this constructor alone.
* This constructor allows this class to be defined as an inline inner class in which the user can override methods
*/
public VideoEnabledWebChromeClient() {
}

/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
* @param activityVideoView     A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
*/
public VideoEnabledWebChromeClient(Activity activity, View activityNonVideoView, ViewGroup activityVideoView) {
this.mContext = activity;
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = null;
this.webView = null;
this.isVideoFullscreen = false;
}

/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
* @param activityVideoView    A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
* @param loadingView          A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and without a parent view.
*/
public VideoEnabledWebChromeClient(Activity activity,View activityNonVideoView, ViewGroup activityVideoView, View loadingView) {
this.mContext = activity;
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = loadingView;
this.webView = null;
this.isVideoFullscreen = false;
}

/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
* @param activityVideoView    A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
* @param loadingView          A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and without a parent view.
* @param webView              The owner VideoEnabledWebView. Passing it will enable the VideoEnabledWebChromeClient to detect the HTML5 video ended event and exit full-screen.
*                             Note: The web page must only contain one video tag in order for the HTML5 video ended event to work. This could be improved if needed (see Javascript code).
*/
public VideoEnabledWebChromeClient(Activity activity,View activityNonVideoView, ViewGroup activityVideoView, View loadingView, VideoEnabledWebView webView) {
this.mContext = activity;
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = loadingView;
this.webView = webView;
this.isVideoFullscreen = false;
}

/**
* Indicates if the video is being displayed using a custom view (typically full-screen)
*
* @return true it the video is being displayed using a custom view (typically full-screen)
*/
public boolean isVideoFullscreen() {
return isVideoFullscreen;
}

/**
* Set a callback that will be fired when the video starts or finishes displaying using a custom view (typically full-screen)
*
* @param callback A VideoEnabledWebChromeClient.ToggledFullscreenCallback callback
*/
public void setOnToggledFullscreen(ToggledFullscreenCallback callback) {
this.toggledFullscreenCallback = callback;
}

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (view instanceof FrameLayout) {
// A video wants to be shown
FrameLayout frameLayout = (FrameLayout) view;
View focusedChild = frameLayout.getFocusedChild();
// Save video related variables
this.isVideoFullscreen = true;
this.videoViewContainer = frameLayout;
this.videoViewCallback = callback;
// Hide the non-video view, add the video view, and show it
activityNonVideoView.setVisibility(View.GONE);
activityVideoView.addView(videoViewContainer, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
activityVideoView.setVisibility(View.VISIBLE);
if (focusedChild instanceof VideoView) {
// VideoView (typically API level <11)
VideoView videoView = (VideoView) focusedChild;
// Handle all the required events
videoView.setOnPreparedListener(this);
videoView.setOnCompletionListener(this);
videoView.setOnErrorListener(this);
} else // Usually android.webkit.HTML5VideoFullScreen$VideoSurfaceView, sometimes android.webkit.HTML5VideoFullScreen$VideoTextureView
{
// HTML5VideoFullScreen (typically API level 11+)
// Handle HTML5 video ended event
if (webView != null && webView.getSettings().getJavaScriptEnabled()) {
// Run javascript code that detects the video end and notifies the interface
String js = "javascript:";
js += "_ytrp_html5_video = document.getElementsByTagName('video')[0];";
js += "if (_ytrp_html5_video !== undefined) {";
{
js += "function _ytrp_html5_video_ended() {";
{
js += "_ytrp_html5_video.removeEventListener('ended', _ytrp_html5_video_ended);";
js += "_VideoEnabledWebView.notifyVideoEnd();"; // Must match Javascript interface name and method of VideoEnableWebView
}
js += "}";
js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";
}
js += "}";
webView.loadUrl(js);
}
}

// Notify full-screen change
if (toggledFullscreenCallback != null) {
toggledFullscreenCallback.toggledFullscreen(true);
}

setFullscreen(true);
}
}

@Override
public void onShowCustomView(View view, int requestedOrientat
c3bc
ion, CustomViewCallback callback) // Only available in API level 14+
{
onShowCustomView(view, callback);
}

@Override
public void onHideCustomView() {
// This method must be manually (internally) called on video end in the case of VideoView (typically API level <11)
// This method must be manually (internally) called on video end in the case of HTML5VideoFullScreen (typically API level 11+) because it's not always called automatically
// This method must be manually (internally) called on back key press (from this class' onBackPressed() method)
if (isVideoFullscreen) {
// Hide the video view, remove it, and show the non-video view
activityVideoView.setVisibility(View.GONE);//播放视频的
activityVideoView.removeView(videoViewContainer);
activityNonVideoView.setVisibility(View.VISIBLE);

// Call back
if (videoViewCallback != null) videoViewCallback.onCustomViewHidden();

// Reset video related variables
isVideoFullscreen = false;
videoViewContainer = null;
videoViewCallback = null;

// Notify full-screen change
if (toggledFullscreenCallback != null) {
toggledFullscreenCallback.toggledFullscreen(false);
}
setFullscreen(false);
}
}

@Override
public View getVideoLoadingProgressView() // Video will start loading, only called in the case of VideoView (typically API level <11)
{
if (loadingView != null) {
loadingView.setVisibility(View.VISIBLE);
return loadingView;
} else {
return super.getVideoLoadingProgressView();
}
}

@Override
public void onPrepared(MediaPlayer mp) // Video will start playing, only called in the case of VideoView (typically API level <11)
{
if (loadingView != null) {
loadingView.setVisibility(View.GONE);
}
}

@Override
public void onCompletion(MediaPlayer mp) // Video finished playing, only called in the case of VideoView (typically API level <11)
{
onHideCustomView();
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) // Error while playing video, only called in the case of VideoView (typically API level <11)
{
return false; // By returning false, onCompletion() will be called
}

/**
* Notifies the class that the back key has been pressed by the user.
* This must be called from the Activity's onBackPressed(), and if it returns false, the activity itself should handle it. Otherwise don't do anything.
*
* @return Returns true if the event was handled, and false if it is not (video view is not visible)
*/
public boolean onBackPressed() {
if (isVideoFullscreen) {
onHideCustomView();
return true;
} else {
return false;
}
}

private void setFullscreen(boolean enable) {
if (enable) { //show status bar
WindowManager.LayoutParams lp = mContext.getWindow().getAttributes();
lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
mContext.getWindow().setAttributes(lp);
mContext.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else { //hide status bar
WindowManager.LayoutParams lp = mContext.getWindow().getAttributes();
lp.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
mContext.getWindow().setAttributes(lp);
mContext.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
}

package cn.cwkj.vediodemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

import java.util.Map;

/**
* Created by zengd on 2016/8/19 0019.
*/
public class VideoEnabledWebView extends WebView {

private VideoEnabledWebChromeClient videoEnabledWebChromeClient;
private boolean addedJavascriptInterface;

public VideoEnabledWebView(Context context) {
this(context, null);
}

public VideoEnabledWebView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public VideoEnabledWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addedJavascriptInterface = false;
}

/**
* Pass only a VideoEnabledWebChromeClient instance.
*/
@Override
@SuppressLint("SetJavaScriptEnabled")
public void setWebChromeClient(WebChromeClient client) {
getSettings().setJavaScriptEnabled(true);

if (client instanceof VideoEnabledWebChromeClient) {
this.videoEnabledWebChromeClient = (VideoEnabledWebChromeClient) client;
}

super.setWebChromeClient(client);
}

@Override
public void loadData(String data, String mimeType, String encoding) {
addJavascriptInterface();
super.loadData(data, mimeType, encoding);
}

@Override
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding,
String historyUrl) {
addJavascriptInterface();
super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}

@Override
public void loadUrl(String url) {
addJavascriptInterface();
super.loadUrl(url);
}

@Override
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
addJavascriptInterface();
super.loadUrl(url, additionalHttpHeaders);
}

private void addJavascriptInterface() {
if (!addedJavascriptInterface) {
// Add javascript interface to be called when the video ends (must be done before page load)
addJavascriptInterface(new Object() {
}, "_VideoEnabledWebView"); // Must match Javascript interface name of VideoEnabledWebChromeClient
addedJavascriptInterface = true;
}
}
}


最后,不要忘记添加权限

<uses-permission android:name="android.permission.INTERNET" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android