#android #html #webview #uiwebview #html5-video
#Android #HTML #webview #uiwebview #html5-video
Вопрос:
Я запускаю приложение Android в webview уже год. Но есть некоторые клиенты, которые говорят, что видео html5 не воспроизводится в моем приложении несколько дней назад. У меня есть пять телефонов для тестирования, и со всеми моими телефонами все в порядке. Большинство клиентов используют приложение без каких-либо проблем.
Я изменил значение свойства предварительной загрузки с auto на meta, потому что я хочу, чтобы это было связано с нагрузкой на сеть.
Изображение ниже является скриншотом от клиента. Время 27: 10, и нет счетчика для загрузки. (Я думаю, что загрузка завершена) Однако пользователь не может нажать кнопку воспроизведения, и когда кнопка воспроизведения нажата, вокруг видеоэлемента появляется оранжевая линия.
На мобильном телефоне клиента установлены Galaxy note 8 и Galaxy J7, а версия Android — 8. Но в моем тестировании проблем не было. И есть пользователи Android 8, которые используют сервис без каких-либо проблем.
Как я могу это решить? Спасибо.
HTML
<video preload="meta" width="95%" autoplay="autoplay" controls="" playsinline="">
<source type="video/mp4" src="url.../file.mp4">
HTML5 is not supported.
</video>
android — MainActivity
public class MainActivity extends AppCompatActivity {
private WebView webView;
private BackPressCloseHandler backPressCloseHandler = new BackPressCloseHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
/* webView settings */
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.setWebChromeClient(new FullscreenableChromeClient(MainActivity.this));
webView.setWebViewClient(new WebViewClientClass());
webView.loadUrl("MY URL IS HERE");
} //onCreate
private class WebViewClientClass extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
пользовательский класс для включения полноэкранного режима видео
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;
public class FullscreenableChromeClient extends WebChromeClient {
private Activity mActivity = null;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private int mOriginalOrientation;
private FrameLayout mFullscreenContainer;
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
public FullscreenableChromeClient(Activity activity) {
this.mActivity = activity;
}
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mOriginalOrientation = mActivity.getRequestedOrientation();
FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
mFullscreenContainer = new FullscreenHolder(mActivity);
mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS);
decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
mCustomView = view;
setFullscreen(true);
mCustomViewCallback = callback;
// mActivity.setRequestedOrientation(requestedOrientation);
}
super.onShowCustomView(view, callback);
}
@SuppressWarnings("deprecation")
@Override
public void onShowCustomView(View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback) {
this.onShowCustomView(view, callback);
}
@Override
public void onHideCustomView() {
if (mCustomView == null) {
return;
}
setFullscreen(false);
FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
decor.removeView(mFullscreenContainer);
mFullscreenContainer = null;
mCustomView = null;
mCustomViewCallback.onCustomViewHidden();
mActivity.setRequestedOrientation(mOriginalOrientation);
}
private void setFullscreen(boolean enabled) {
Window win = mActivity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN;
if (enabled) {
winParams.flags |= bits;
} else {
winParams.flags amp;= ~bits;
if (mCustomView != null) {
mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
win.setAttributes(winParams);
}
private static class FullscreenHolder extends FrameLayout {
public FullscreenHolder(Context ctx) {
super(ctx);
setBackgroundColor(ContextCompat.getColor(ctx, android.R.color.black));
}
@Override
public boolean onTouchEvent(MotionEvent evt) {
return true;
}
}
}
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="...">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_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:theme="@style/AppTheme">
<activity android:name="....webview.MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
</activity>
<activity android:name="....webview.IntroActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Комментарии:
1. Здесь та же ситуация, за исключением того, что я могу воспроизвести на своем телефоне. Обновление для Android System WebView было обновлено 11 марта (не уверен, было ли тогда опубликовано обновление или именно тогда обновился мой телефон; просто отключаю «последнее обновление» в Google Play Store для Android System WebView), поэтому я предполагаю, что это сделало.
2. Я получил сообщения от пользователей Samsung 8 и Huawei P20 с той же проблемой
3. Мне удалось воспроизвести те же симптомы на моем тестовом мобильном телефоне. Я подождал почти пять минут, оранжевая линия исчезла, и я смог воспроизвести видео. Это проблема с сетью? Но мой сервер работал нормально, и на других тестовых телефонах, использующих тот же Wi-Fi, загрузка была мгновенно завершена. Благодаря советам людей, которые ответили, я собираюсь использовать JavaScript.
4. Это определенно ошибка в системном веб-просмотре Android. Я сталкиваюсь с этой проблемой на Galaxy S8 с Android Pie, используя Android WebView версии 73.0.3683.90. Я откатился до версии 71.0.3578.99, и эта проблема исчезла.
5. Раньше видео в WebView у меня работало, но больше не работает (после обновления Pie?) на моем S9 . На моем телефоне написано, что веб-просмотр системы Android отключен (версия 69) при включенном Chrome.
Ответ №1:
Приведенный ниже код работает нормально для меня, пожалуйста, проверьте один раз
добавьте эту строку в файл манифеста
<application android:hardwareAccelerated="true" ...>
MainActivity
public class MainActivity extends AppCompatActivity {
private WebView webview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webview = findViewById(R.id.webView);
webview.setWebViewClient(new MyBrowser());
webview.setWebChromeClient(new WebChromeClient());
webview.getSettings().setLoadsImagesAutomatically(true);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setAllowFileAccess(true);
webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setPluginState(WebSettings.PluginState.ON);
webview.getSettings().setMediaPlaybackRequiresUserGesture(false);
webview.loadUrl("https://www.w3schools.com/html/html5_video.asp");
}
private class MyBrowser extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView
android:id="@ id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
Комментарии:
1. Строка, которая исправила это для меня, — WebView.getSettings().setMediaPlaybackRequiresUserGesture(false); (API 17) Но я все еще не могу заставить полноэкранную кнопку больше работать!
2. @ErnieThomason У меня была такая же проблема, и setMediaPlaybackRequiresUserGesture (false) исправил ее!
Ответ №2:
У меня была такая же проблема с системой Android Webview 73 в моем видеоприложении. Похоже, что есть какая-то проблема со стилем видеопроигрывателя html5 по умолчанию. Я могу выполнить автоматическое воспроизведение или вызвать функцию play () в javascript.
Мое решение — использовать какой-нибудь другой видеоплеер на javascript. Я использовал VideoJS для замены интерфейса видеоплеера, и теперь он работает.
Ответ №3:
Поскольку javascript вызывает воспроизведение / приостановку работы видео, я исправил это в нашем приложении, включив div перед видео и изменив его размер в соответствии с кнопкой воспроизведения, которую Android размещает в центре видео. Вот фрагмент реакции:
const isAndroid = () => navigator.userAgent.indexOf('Android') >= 0;
let videoPlayer;
...
<div className="video-wrap">
<video
ref={node => videoPlayer = node}
controls
controlsList="nodownload"
crossOrigin="anonymous"
poster={episode.posterUrl}
>
<source src={episode.h264Url} type="video/mp4" />
{episode.webmUrl ? (
<source src={episode.webmUrl} type="video/webm" />
) : null}
{episode.vttUrl ? (
<track kind="captions" label="English" src={episode.vttUrl} srcLang="en" />
) : null}
</video>
{ isAndroid() ? (
<div
className="android-playback-fix"
onClick={e => {
e.preventDefault();
if (videoPlayer.paused) {
videoPlayer.play();
} else {
videoPlayer.pause();
}
}}
></div>
) : null}
</div>
Вот CSS:
.video-wrap {
position: relative;
}
.android-playback-fix {
border-radius: 100%;
height: 75px;
left: 50%;
position: absolute;
top: 45%;
transform: translate(-50%, -50%);
width: 75px;
}
Ответ №4:
У меня возникают те же проблемы.
Чтобы исправить это.
Поместите id
в свой HTML-тег video знак и вызовите его id
в своем Java-коде.
например
<video id = "video" preload="meta" width="95%" autoplay="autoplay" controls="" playsinline=""><source type="video/mp4" src="url.../file.mp4"></video>
На onPageFinished
— переопределение для WebViewClient
, поместите этот код
webView.loadUrl("javascript:(function() { document.getElementById('video').play(); })()");
webView.loadUrl("javascript:(function() { document.getElementById('video').pause(); })()");
Это введет функцию javascript, чтобы разрешить автоматическое воспроизведение видео