YouTube 视频在 WebView Android 中仅在屏幕旋转时播放音频

Posted

技术标签:

【中文标题】YouTube 视频在 WebView Android 中仅在屏幕旋转时播放音频【英文标题】:YouTube video plays only audio on screen rotate in WebView Android 【发布时间】:2020-11-21 02:48:30 【问题描述】:

我正在尝试在 android 上的 WebView 中实现 YouTube。播放视频并旋转屏幕时,视频会显示回放缩略图,并且仅播放音频。我已经包含了

在我的清单中。

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>



android:hardwareAccelerated="true" 

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 

Activity 仅包含高度和宽度设置为 match_parent 的 WebView。

重现问题:

    播放视频。 切换到全屏。 旋转屏幕出现问题,只播放音频,视频显示缩略图。

Java 代码:


import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity 

    WebView mWebView;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWebView = (WebView) findViewById(R.id.webView);

        mWebView.setWebViewClient(new Browser_home());
        mWebView.setWebChromeClient(new MyChrome());
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setjavascriptEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setAppCacheEnabled(true);


        if(savedInstanceState==null)
            mWebView.post(new Runnable() 
                @Override
                public void run() 
                    loadWebsite();
                
            );
        

    


    @Override
    public void onConfigurationChanged(Configuration newConfig) 
        super.onConfigurationChanged(newConfig);
    

    @Override
    protected void onSaveInstanceState(Bundle outState )
    
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    
        super.onRestoreInstanceState(savedInstanceState);
        mWebView.restoreState(savedInstanceState);
    

    private void loadWebsite() 
        ConnectivityManager cm = (ConnectivityManager) getApplication().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) 
            mWebView.loadUrl("https://www.youtube.com/");
         else 
            mWebView.setVisibility(View.GONE);
        
    

    class Browser_home extends WebViewClient 

        Browser_home() 
        

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) 
            super.onPageStarted(view, url, favicon);

        

        @Override
        public void onPageFinished(WebView view, String url) 
            setTitle(view.getTitle());
            super.onPageFinished(view, url);

        
    

    private class MyChrome extends WebChromeClient 

        private View mCustomView;
        private WebChromeClient.CustomViewCallback mCustomViewCallback;
        protected FrameLayout mFullscreenContainer;
        private int mOriginalOrientation;
        private int mOriginalSystemUiVisibility;

        MyChrome() 

        public Bitmap getDefaultVideoPoster()
        
            if (mCustomView == null) 
                return null;
            
            return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
        

        public void onHideCustomView()
        
            ((FrameLayout)getWindow().getDecorView()).removeView(this.mCustomView);
            this.mCustomView = null;
            getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
            setRequestedOrientation(this.mOriginalOrientation);
            this.mCustomViewCallback.onCustomViewHidden();
            this.mCustomViewCallback = null;
        

        public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
        
            if (this.mCustomView != null)
            
                onHideCustomView();
                return;
            
            this.mCustomView = paramView;
            this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
            this.mOriginalOrientation = getRequestedOrientation();
            this.mCustomViewCallback = paramCustomViewCallback;
            ((FrameLayout)getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
            getWindow().getDecorView().setSystemUiVisibility(3846);
        
    

【问题讨论】:

【参考方案1】:

我根据您的代码从头开始创建了一个应用程序,因此可以旋转屏幕,但是我不知道您的 Manifest、布局和 gradle 实际是什么样的,但这是我为您构建的完整应用程序:

FullscreenActivity.java

package com.harold.paulino.youtubeplayer;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;

public class FullscreenActivity extends AppCompatActivity 

    WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fullscreen);


        mWebView = (WebView) findViewById(R.id.webView);


        mWebView.setWebViewClient(new Browser_home());
        mWebView.setWebChromeClient(new MyChrome());
        mWebView.setWebChromeClient(new WebChromeClient());
        mWebView.setWebViewClient(new WebViewClient());
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setAppCacheEnabled(true);


        if(savedInstanceState==null)
            mWebView.post(new Runnable() 
                @Override
                public void run() 
                    loadWebsite();
                
            );
        
    


    @Override
    public void onBackPressed() 

        if(mWebView.canGoBack())
            mWebView.goBack();
        else
            super.onBackPressed();
    

    @Override
    public void onConfigurationChanged(Configuration newConfig) 
        super.onConfigurationChanged(newConfig);
    

    @Override
    protected void onSaveInstanceState(Bundle outState )
    
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    
        super.onRestoreInstanceState(savedInstanceState);
        mWebView.restoreState(savedInstanceState);
    

    private void loadWebsite() 
        ConnectivityManager cm = (ConnectivityManager) getApplication().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) 
            mWebView.loadUrl("https://www.youtube.com/");
         else 
            mWebView.setVisibility(View.VISIBLE);
        
    

    class Browser_home extends WebViewClient 

        Browser_home() 
        

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) 
            super.onPageStarted(view, url, favicon);

        

        @Override
        public void onPageFinished(WebView view, String url) 
            setTitle(view.getTitle());
            super.onPageFinished(view, url);

        
    

    private class MyChrome extends WebChromeClient 

        private View mCustomView;
        private WebChromeClient.CustomViewCallback mCustomViewCallback;
        protected FrameLayout mFullscreenContainer;
        private int mOriginalOrientation;
        private int mOriginalSystemUiVisibility;

        MyChrome() 

        public Bitmap getDefaultVideoPoster()
        
            if (mCustomView == null) 
                return null;
            
            return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
        

        public void onHideCustomView()
        
            ((FrameLayout)getWindow().getDecorView()).removeView(this.mCustomView);
            this.mCustomView = null;
            getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
            setRequestedOrientation(this.mOriginalOrientation);
            this.mCustomViewCallback.onCustomViewHidden();
            this.mCustomViewCallback = null;
        

        public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
        
            if (this.mCustomView != null)
            
                onHideCustomView();
                return;
            
            this.mCustomView = paramView;
            this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
            this.mOriginalOrientation = getRequestedOrientation();
            this.mCustomViewCallback = paramCustomViewCallback;
            ((FrameLayout)getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
            getWindow().getDecorView().setSystemUiVisibility(3846);
        
    

activity_fullscreen.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:background="#0099cc"
    tools:context=".FullscreenActivity">

    <WebView
        android:id="@+id/webView"
        android:layout_
        android:layout_
        android:gravity="center"
        android:keepScreenOn="true" />

</FrameLayout>

styles.xml

    <resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>

    <style name="FullscreenTheme" parent="AppTheme">
        <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@null</item>
        <item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
        <item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
    </style>

    <style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
        <item name="android:background">@color/black_overlay</item>
    </style>

</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.harold.paulino.youtubeplayer">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:hardwareAccelerated="true"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
        android:theme="@style/AppTheme">
        <activity
            android:name=".FullscreenActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/title_activity_fullscreen"
            android:theme="@style/FullscreenTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

build.gradle

apply plugin: 'com.android.application'

android 
    compileSdkVersion 29

    defaultConfig 
        applicationId "com.harold.paulino.youtubeplayer"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
    

    buildTypes 
        release 
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        
    


dependencies 
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'


strings.xml

<resources>
    <string name="app_name">MyYoutube</string>
    <string name="title_activity_fullscreen">MyYoutube</string>
</resources>

【讨论】:

完美运行。谢谢☺【参考方案2】:

只需通过覆盖onRotate() 方法将其设置为在屏幕旋转时自动调整,如下所示:

@Override
void onRotate()

    mWebView.autoAdjust(true);

这将在屏幕旋转时自动调整您的 WebView。

【讨论】:

以上是关于YouTube 视频在 WebView Android 中仅在屏幕旋转时播放音频的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 上的 webView 中显示 YouTube 视频

为啥 Youtube 视频没有在 webview android 中播放

Android:在 Webview 上播放 youtube 视频

如何在android webview中获取完成youtube视频的事件

在 WebView 中加载 YouTube 视频时,全屏选项不可用

Android webView 播放 YouTube 视频