Intereting Posts
Экстремальное отставание камеры на Nexus 4 Как настроить выборщик в тексте внутри него Android: Как установить содержимое Редактировать текст с помощью кнопки? Альтернатива FusedLocationProviderApi Как узнать, был ли выбран элемент spinner в android? Как создать хэш-код Facebook? Android: как я могу проверить, поддерживает ли устройство мультитач? Как изменить цвет текста ActionBar в Android 5.0 Lollipop? Идентификатор ресурса не найден для атрибута fontFamily в пакете android В EditText всплывающее диалоговое окно при нажатии на определенное подмножество текста Есть ли способ написать единичный тест для целевого API Android Studio enum left right bug? Как отключить предупреждения RTL для всего проекта? SVG-преобразование – эффективный способ хранения объектов Path, Paint и Matrix? Изменение размера предварительного просмотра камеры Молчаливое автоматическое удаленное обновление приложений для Android?

Воспроизведение видео в формате HTML5 на полноэкранном режиме в веб-обозревателе Android

Ну, я уже несколько дней искал, как отображать видео в формате HTML5 в полноэкранном режиме на веб-обозревателе Android.

Мне удалось воспроизвести видео в формате HTML5 на моем веб-просмотре. Проблемы возникают при отображении видео в полноэкранном режиме.

Как я понял, андроид имеет два способа обработки тега <video>:

  1. В версиях Android версии <= 2.3.3 запускается метод onShowCustomView, и у меня может быть экземпляр VideoView и установка слушателей при завершении видео, установка контроллеров и т. Д. До сих пор это было так хорошо.

  2. В ICS (и, возможно, 3.0 и выше) , похоже, что <video> обрабатывается по-разному. Когда воспроизводится видео HTML5, onShowCustomView не вызывается в обычном режиме – похоже, что внутри WebView, который воспроизводит видео, есть внутренний бизнес, и отображаются все элементы управления, определенные в теге <video> – I Не может получить к нему доступа никоим образом. Собственно, если видео воспроизводится в нормальном режиме, это нормально, потому что элементы управления работают и работают.

Это привело меня к большой проблеме: при отображении видео в полноэкранном режиме вызывается onShowCustomView, но в ICS параметр «view» не является экземпляром VideoView.

Мне удалось выяснить, что экземпляр принадлежит VideoSurfaceView, частному внутреннему классу класса HTML5VideoFullScreen. Единственный способ получить доступ к этому внутреннему классу – это отражение.

Изучив GrepCode для этого класса, я узнал, что в отличие от VideoView, HTML5VideoFullScreen $ VideoSurfaceView не содержит экземпляр MediaPlayer, который я могу прослушивать его события или получать доступ к его элементам управления. Единственное, что я могу сделать, это взять этот VideoSurfaceView так, как он есть, и поместить его в полноэкранный макет, не контролируя его.

Нижняя строка. Когда вы показываете видео в полноэкранном режиме, я не знаю, когда заканчивается видео, его элементы управления не отображаются – это довольно грустно. Я не могу получить триггер для закрытия полноэкранного режима.

Я пробовал несколько неудачных обходных решений:

  1. Отражение: я попытался добраться до экземпляра HTML5VideoFullScreen, который содержит элемент MediaPlayer, из внутреннего класса VideoSurfaceView. Мне не удалось это получить, я не уверен, что это возможно (ViewSurfaceView не поддерживает экземпляр своего владельца).

  2. Зарегистрируйтесь для видео-событий через Javascript (например, например) и обработайте то, что мне нужно, в JAVA через JavascriptInterface: я нашел, что это решение не является надежным, потому что при этом я столкнулся с другой проблемой: тег <video> может быть вложен В. Источник iframe не принадлежит мне, и я не могу получить его содержимое (getElementById или getElementsByTagName [i] являются нулями), что означает, что я не могу достичь элемента <video> внутри iframe.

Я все еще ищу решение, очень мало написано об этой проблеме. Кто-нибудь сумел это решить? Помощь будет очень признательна!

Класс VideoView : Здесь (есть MediaPlayer)

Класс HTML5VideoFullScreen $ VideoSurfaceView : здесь (нет MediaPlayer)

Edit 2014/10: по популярному запросу я поддерживаю и переношу это в GitHub. Пожалуйста, проверьте cprcrack / VideoEnabledWebView для последней версии. Будет держать этот ответ только для справки.

Edit 2014/01: улучшено использование примера для включения представлений nonVideoLayout, videoLayout и videoLoading для тех пользователей, которые запрашивают больше кода примера для лучшего понимания.

Edit 2013/12: некоторые исправления ошибок, связанные с совместимостью устройств Sony Xperia, но которые фактически затрагивают все устройства.

Редактировать 2013/11: после выхода Android 4.4 KitKat (API уровня 19) с новым веб-обзором Chromium мне пришлось снова много работать. Было сделано несколько улучшений. Вы должны обновить эту новую версию. Я выпускаю этот источник под WTFPL . Пожертвования принимаются (найдите ссылку «Пожертвовать» внизу).

Редактировать 2013/04: после 1 недели напряженной работы я, наконец, достиг всего, что мне нужно. Я думаю, что эти два генерических класса, которые я создал, могут решить все ваши проблемы.

VideoEnabledWebChromeClient может использоваться отдельно, если вы не требуете функциональности, VideoEnabledWebView добавляет VideoEnabledWebView . Но VideoEnabledWebView всегда должен полагаться на VideoEnabledWebChromeClient . Пожалуйста, внимательно прочитайте все комментарии обоих классов.

Класс VideoEnabledWebChromeClient

 import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnPreparedListener; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.webkit.WebChromeClient; import android.widget.FrameLayout; /** * This class serves as a WebChromeClient to be set to a WebView, allowing it to play video. * Video will play differently depending on target API level (in-line, fullscreen, or both). * * It has been tested with the following video classes: * - android.widget.VideoView (typically API level <11) * - android.webkit.HTML5VideoFullScreen$VideoSurfaceView/VideoTextureView (typically API level 11-18) * - com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView (typically API level 19+) * * Important notes: * - For API level 11+, android:hardwareAccelerated="true" must be set in the application manifest. * - The invoking activity must call VideoEnabledWebChromeClient's onBackPressed() inside of its own onBackPressed(). * - Tested in Android API levels 8-19. Only tested on http://m.youtube.com. * * @author Cristian Perez (http://cpr.name) * */ public class VideoEnabledWebChromeClient extends WebChromeClient implements OnPreparedListener, OnCompletionListener, OnErrorListener { public interface ToggledFullscreenCallback { public 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; /** * 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 */ @SuppressWarnings("unused") 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. */ @SuppressWarnings("unused") public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView) { 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. */ @SuppressWarnings("unused") public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView) { 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(View activityNonVideoView, ViewGroup activityVideoView, View loadingView, VideoEnabledWebView webView) { 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.INVISIBLE); activityVideoView.addView(videoViewContainer, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); activityVideoView.setVisibility(View.VISIBLE); if (focusedChild instanceof android.widget.VideoView) { // android.widget.VideoView (typically API level <11) android.widget.VideoView videoView = (android.widget.VideoView) focusedChild; // Handle all the required events videoView.setOnPreparedListener(this); videoView.setOnCompletionListener(this); videoView.setOnErrorListener(this); } else { // Other classes, including: // - android.webkit.HTML5VideoFullScreen$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 11-18) // - android.webkit.HTML5VideoFullScreen$VideoTextureView, which inherits from android.view.TextureView (typically API level 11-18) // - com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 19+) // Handle HTML5 video ended event only if the class is a SurfaceView // Test case: TextureView of Sony Xperia T API level 16 doesn't work fullscreen when loading the javascript below if (webView != null && webView.getSettings().getJavaScriptEnabled() && focusedChild instanceof SurfaceView) { // Run javascript code that detects the video end and notifies the Javascript interface String js = "javascript:"; js += "var _ytrp_html5_video_last;"; js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];"; js += "if (_ytrp_html5_video != undefined && _ytrp_html5_video != _ytrp_html5_video_last) {"; { js += "_ytrp_html5_video_last = _ytrp_html5_video;"; js += "function _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); } } } @Override @SuppressWarnings("deprecation") public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) // Available in API level 14+, deprecated in API level 18+ { onShowCustomView(view, callback); } @Override public void onHideCustomView() { // This method should be manually called on video end in all cases because it's not always called automatically. // This method must be manually 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.INVISIBLE); activityVideoView.removeView(videoViewContainer); activityNonVideoView.setVisibility(View.VISIBLE); // Call back (only in API level <19, because in API level 19+ with chromium webview it crashes) if (videoViewCallback != null && !videoViewCallback.getClass().getName().contains(".chromium.")) { videoViewCallback.onCustomViewHidden(); } // Reset video related variables isVideoFullscreen = false; videoViewContainer = null; videoViewCallback = null; // Notify full-screen change if (toggledFullscreenCallback != null) { toggledFullscreenCallback.toggledFullscreen(false); } } } @Override public View getVideoLoadingProgressView() // Video will start loading { 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 android.widget.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 android.widget.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 android.widget.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 was not (video view is not visible) */ public boolean onBackPressed() { if (isVideoFullscreen) { onHideCustomView(); return true; } else { return false; } } } 

Класс VideoEnabledWebView

 import android.annotation.SuppressLint; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; import android.webkit.WebChromeClient; import android.webkit.WebView; import java.util.Map; /** * This class serves as a WebView to be used in conjunction with a VideoEnabledWebChromeClient. * It makes possible: * - To detect the HTML5 video ended event so that the VideoEnabledWebChromeClient can exit full-screen. * * Important notes: * - Javascript is enabled by default and must not be disabled with getSettings().setJavaScriptEnabled(false). * - setWebChromeClient() must be called before any loadData(), loadDataWithBaseURL() or loadUrl() method. * * @author Cristian Perez (http://cpr.name) * */ public class VideoEnabledWebView extends WebView { public class JavascriptInterface { @android.webkit.JavascriptInterface public void notifyVideoEnd() // Must match Javascript interface method of VideoEnabledWebChromeClient { // This code is not executed in the UI thread, so we must force that to happen new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { if (videoEnabledWebChromeClient != null) { videoEnabledWebChromeClient.onHideCustomView(); } } }); } } private VideoEnabledWebChromeClient videoEnabledWebChromeClient; private boolean addedJavascriptInterface; public VideoEnabledWebView(Context context) { super(context); addedJavascriptInterface = false; } @SuppressWarnings("unused") public VideoEnabledWebView(Context context, AttributeSet attrs) { super(context, attrs); addedJavascriptInterface = false; } @SuppressWarnings("unused") public VideoEnabledWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); addedJavascriptInterface = 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 videoEnabledWebChromeClient != null && videoEnabledWebChromeClient.isVideoFullscreen(); } /** * 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 JavascriptInterface(), "_VideoEnabledWebView"); // Must match Javascript interface name of VideoEnabledWebChromeClient addedJavascriptInterface = true; } } } 

Пример использования:

Основной макет activity_main.xml, в который мы помещаем VideoEnabledWebView и другие используемые виды:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <!-- View that will be hidden when video goes fullscreen --> <RelativeLayout android:id="@+id/nonVideoLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <your.package.VideoEnabledWebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> <!-- View where the video will be shown when video goes fullscreen --> <RelativeLayout android:id="@+id/videoLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- View that will be shown while the fullscreen video loads (maybe include a spinner and a "Loading..." message) --> <View android:id="@+id/videoLoading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="invisible" /> </RelativeLayout> </RelativeLayout> 

Activity onCreate () , в котором мы инициализируем его:

 private VideoEnabledWebView webView; private VideoEnabledWebChromeClient webChromeClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set layout setContentView(R.layout.activity_main); // Save the web view webView = (VideoEnabledWebView) findViewById(R.id.webView); // Initialize the VideoEnabledWebChromeClient and set event handlers View nonVideoLayout = findViewById(R.id.nonVideoLayout); // Your own view, read class comments ViewGroup videoLayout = (ViewGroup) findViewById(R.id.videoLayout); // Your own view, read class comments View loadingView = getLayoutInflater().inflate(R.layout.view_loading_video, null); // Your own view, read class comments webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout, loadingView, webView) // See all available constructors... { // Subscribe to standard events, such as onProgressChanged()... @Override public void onProgressChanged(WebView view, int progress) { // Your code... } }; webChromeClient.setOnToggledFullscreen(new VideoEnabledWebChromeClient.ToggledFullscreenCallback() { @Override public void toggledFullscreen(boolean fullscreen) { // Your code to handle the full-screen change, for example showing and hiding the title bar. Example: if (fullscreen) { WindowManager.LayoutParams attrs = getWindow().getAttributes(); attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; getWindow().setAttributes(attrs); if (android.os.Build.VERSION.SDK_INT >= 14) { getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); } } else { WindowManager.LayoutParams attrs = getWindow().getAttributes(); attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; getWindow().setAttributes(attrs); if (android.os.Build.VERSION.SDK_INT >= 14) { getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } } } }); webView.setWebChromeClient(webChromeClient); // Navigate everywhere you want, this classes have only been tested on YouTube's mobile site webView.loadUrl("http://m.youtube.com"); } 

И не забудьте вызвать onBackPressed () :

 @Override public void onBackPressed() { // Notify the VideoEnabledWebChromeClient, and handle it ourselves if it doesn't handle it if (!webChromeClient.onBackPressed()) { if (webView.canGoBack()) { webView.goBack(); } else { // Close app (presumably) super.onBackPressed(); } } } 

Изменить: см. Мой другой ответ , так как вам, вероятно, сейчас это не нужно.

Как вы сказали, в уровнях API 11+ передается HTML5VideoFullScreen $ VideoSurfaceView. Но я не думаю, что вы правы, когда говорите, что «у него нет MediaPlayer».

Это способ получить экземпляр MediaPlayer из экземпляра HTML5VideoFullScreen $ VideoSurfaceView, используя отражение :

 @SuppressWarnings("rawtypes") Class c1 = Class.forName("android.webkit.HTML5VideoFullScreen$VideoSurfaceView"); Field f1 = c1.getDeclaredField("this$0"); f1.setAccessible(true); @SuppressWarnings("rawtypes") Class c2 = f1.getType().getSuperclass(); Field f2 = c2.getDeclaredField("mPlayer"); f2.setAccessible(true); Object ___html5VideoViewInstance = f1.get(focusedChild); // Look at the code in my other answer to this same question to see whats focusedChild Object ___mpInstance = f2.get(___html5VideoViewInstance); // This is the MediaPlayer instance. 

Итак, теперь вы можете установить прослушиватель onCompletion экземпляра MediaPlayer следующим образом:

 OnCompletionListener ocl = new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // Do stuff } }; Method m1 = f2.getType().getMethod("setOnCompletionListener", new Class[] { Class.forName("android.media.MediaPlayer$OnCompletionListener") }); m1.invoke(___mpInstance, ocl); 

Код не подводит, но я не совсем уверен, действительно ли этот прослушиватель onCompletion будет действительно вызван или может быть полезен для вашей ситуации. Но на всякий случай кто-то хотел бы попробовать.

Большое вам спасибо за этот класс, Кристиан.

Я сделал небольшую настройку, чтобы пользовательский режим загрузки был необязательным, например:

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

Я также добавил новый конструктор, который просто принимает два параметра. Во всяком случае, просто небольшое упрощение, если вам не нужно загрузочное представление. Еще раз спасибо за предоставление этого.

Просто установите
mWebView.setWebChromeClient(new WebChromeClient());

И воспроизведение видео, как обычно, не требует какого-либо пользовательского представления.

Отлично. Но если вы хотите, чтобы ваши ссылки на сайты открывались в самом приложении, добавьте этот код в свой пример ExampleActivity.java:

 webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (Uri.parse(url).getHost().endsWith("yourwebsite.com")) { return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); view.getContext().startActivity(intent); return true; } }); 

Ответ Cprcrack очень хорошо работает для уровней API 19 и ниже. Просто небольшое дополнение к onShowCustomView onShowCustomView позволит ему работать с API уровня 21+

 if (Build.VERSION.SDK_INT >= 21) { videoViewContainer.setBackgroundColor(Color.BLACK); ((ViewGroup) webView.getParent()).addView(videoViewContainer); webView.scrollTo(0,0); // centers full screen view } else { activityNonVideoView.setVisibility(View.INVISIBLE); ViewGroup.LayoutParams vg = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); activityVideoView.addView(videoViewContainer,vg); activityVideoView.setVisibility(View.VISIBLE); } 

Вам также необходимо будет отразить изменения в onHideCustomView

Кажется, что в lollipop и up (или, возможно, просто другой версии WebView), что вызов cprcrack's onHideCustomView() не работает. Он работает, если он вызывается из полноэкранной кнопки выхода, но когда вы специально вызываете метод, он выйдет только из полноэкранного webView но webView останется пустым. Кстати, это просто добавить эти строки кода в onHideCustomView() :

 String js = "javascript:"; js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];"; js += "_ytrp_html5_video.webkitExitFullscreen();"; webView.loadUrl(js); 

Это уведомит веб-экран, что полноэкранный режим вышел.