Android WebView 视频播放解决

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1805812268/article/details/51364999

最近项目中遇到WebView 播放视频需求(H5 video 标签),那么问题来了视频无法全屏播放等。

对于这种视频播放问题有多种方案可以解决,例如:

1.实现一个网络视频播放器来播放网络视频(这个方案如果不利用开源的框架,实现起来费时费力)

2.自定义WebView实现利用H5的Video标签来播放视频(可以解决基本的视频播放需求,但是可能很多效果难以实现,比如手势控制等)

下面介绍第二种解决方案:

需要我们自定义WebView 来实现。

分步指南

  1. 新建一个Activity 来播放视频( PlayVideoWebViewActivity) 
    这个activity的布局非常简单,就是一个简单的 WebView,布局文件如下:
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/container"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical">
    
     <FrameLayout
     android:id="@+id/video_view"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:visibility="gone">
    
     </FrameLayout>
    
     <WebView
     android:id="@+id/video_webview"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"/>
    
     <ImageView
     android:id="@+id/goback"
     android:layout_width="45dp"
     android:layout_height="45dp" />
    </FrameLayout>
    
    可以看到布局文件中除了一个WebView 还有一个 FrameLayout  id/video_view,这个FrameLayout 其实就是我们用来解决全屏播放的。

  2. 初始化View
    private void initwidget() {
    // TODO Auto-generated method stub
     videoview = (FrameLayout) findViewById(R.id.video_view);
     videowebview = (WebView) findViewById(R.id.video_webview);
     back = (ImageView) findViewById(R.id.goback) ;
     back.setOnClickListener(new Listener());
     WebSettings ws = videowebview.getSettings();
     /**
     *
     * setAllowFileAccess 启用或禁止WebView访问文件数据 setBlockNetworkImage 是否显示网络图像
     * setBuiltInZoomControls 设置是否支持缩放 setCacheMode 设置缓冲的模式
     * setDefaultFontSize 设置默认的字体大小 setDefaultTextEncodingName 设置在解码时使用的默认编码
     * setFixedFontFamily 设置固定使用的字体 setJavaSciptEnabled 设置是否支持Javascript
     * setLayoutAlgorithm 设置布局方式 setLightTouchEnabled 设置用鼠标激活被选项
     * setSupportZoom 设置是否支持变焦
     * */
     ws.setBuiltInZoomControls(true);// 隐藏缩放按钮
     ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);// 排版适应屏幕
     ws.setUseWideViewPort(true);// 可任意比例缩放
     ws.setLoadWithOverviewMode(true);// setUseWideViewPort方法设置webview推荐使用的窗口。setLoadWithOverviewMode方法是设置webview加载的页面的模式。
     ws.setSavePassword(true);
     ws.setSaveFormData(true);// 保存表单数据
     ws.setJavaScriptEnabled(true);
     ws.setGeolocationEnabled(true);// 启用地理定位
     ws.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");// 设置定位的数据库路径
     ws.setDomStorageEnabled(true);
     mWebchromeclient = new mWebChromeClient();
     videowebview.setWebChromeClient(mWebchromeclient);
     videowebview.setWebViewClient(new xWebViewClientent());
    
    }
  3. 下面重点来了
    自定义 mWebChromeClient 继承 WebChromeClient。实现对全屏操作的处理,及默认播放图标,Html 页面标题等。
    /**
     * 处理Javascript的对话框、网站图标、网站标题以及网页加载进度等
     *
     * @author
     **/
     public class mWebChromeClient extends WebChromeClient {
    private Bitmap xdefaltvideo;
     private View xprogressvideo;
    
     @Override
     //播放网络视频时全屏会被调用的方法
     public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
     videowebview.setVisibility(View.GONE);
     //如果一个视图已经存在,那么立刻终止并新建一个
     if (xCustomView != null) {
                    callback.onCustomViewHidden();
     return;
     }
    videoview.addView(view);
     xCustomView = view;
     xCustomViewCallback = callback;
     videoview.setVisibility(View.VISIBLE);
     }
    
    @Override
     //视频播放退出全屏会被调用的
     public void onHideCustomView() {
    if (xCustomView == null)//不是全屏播放状态
     return;
     // Hide the custom view.
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
     xCustomView.setVisibility(View.GONE);
     // Remove the custom view from its container.
     videoview.removeView(xCustomView);
     xCustomView = null;
     videoview.setVisibility(View.GONE);
     xCustomViewCallback.onCustomViewHidden();
     videowebview.setVisibility(View.VISIBLE);
     }
    
    // //视频加载添加默认图标
    // @Override
    // public Bitmap getDefaultVideoPoster() {
    // //Log.i(LOGTAG, "here in on getDefaultVideoPoster");
    // if (xdefaltvideo == null) {
    // xdefaltvideo = BitmapFactory.decodeResource(getResources(), R.drawable.seach_icon);
    // }
    // return xdefaltvideo;
    // }
    
     //视频加载时进程loading
    // @Override
    // public View getVideoLoadingProgressView() {
    // //Log.i(LOGTAG, "here in on getVideoLoadingPregressView");
    // if (xprogressvideo == null) {
    // LayoutInflater inflater = LayoutInflater.from(PlayVideoWebViewActivity.this);
    // xprogressvideo = inflater.inflate(R.layout.video_loading_progress, null);
    // }
    // return xprogressvideo;
    // }
    
     //网页标题
     @Override
     public void onReceivedTitle(WebView view, String title) {
                (PlayVideoWebViewActivity.this).setTitle(title);
     }
    
        }

     

  4. 实现横竖屏切换
    /**
     * * 当横竖屏切换时会调用该方法
     * * @author
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Log.i("testwebview", "=====<<< onConfigurationChanged >>>=====");
     super.onConfigurationChanged(newConfig);
     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            Log.i("webview", " 现在是横屏1");
     islandport = false;
     } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            Log.i("webview", " 现在是竖屏1");
     islandport = true;
     }
    }


  5. 添加按键监听,实现音量+/-,实现全屏模式下返回退出全屏,实现退出播放操作等。
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
     int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    
     if (keyCode == KeyEvent.KEYCODE_BACK) {
    if (inCustomView()) {
                hideCustomView();
     return true;
     } else {
    videowebview.loadUrl("about:blank");
     videowebview = null;
     this.finish();
     }
        }
    
    if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){//音量+
     mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume+1, 1);
     }
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){//音量-
     mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume-1, 1);
     }
    return true;
    }
    /**
     * 判断是否是全屏
     *
     * @return
     */
    public boolean inCustomView() {
        return (xCustomView != null);
    }
    
    /**
     * 全屏时按返加键执行退出全屏方法
     */
    public void hideCustomView() {
        mWebchromeclient.onHideCustomView();
    }
    上面可以看到返回退出播放时webview加载了一个空白页面,这样做的目的是如果不加载空白页面,会出现界面退出了但是声音还存在,也就没有回收资源。

  6. 实现全屏,去掉应用标题及手机状态栏
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉应用标题
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
     setContentView(R.layout.activity_play_video_web_view);
     //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
     initwidget();
     url = getIntent().getStringExtra("url");
     videowebview.loadUrl(url);
    }
  7. 完整类文件http://download.csdn.net/detail/qq1805812268/9515793
  8. 号外:
    1.该Activity要允许横屏
    
    <activity
        android:name=".guide.activity.PlayVideoWebViewActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        >
    2.硬件加速
    android:hardwareAccelerated="true"
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页