WebView e HTML5 <video>

122

Estou montando um aplicativo barato que, entre outras coisas, "enquadra" alguns de nossos sites ... Bastante simples com o WebViewClient. até eu clicar no vídeo.

O vídeo é feito como HTML5 elementos, e eles funcionam bem no Chrome, nos iPhones e agora que corrigimos os problemas de codificação nos quais ele funciona muito bem no Androidnavegador nativo.

Agora o problema: WebViewnão gosta. Em absoluto. Posso clicar na imagem do pôster e nada acontece.

Pesquisando no Google, achei isso próximo, mas parece basear-se em um 'link' (como em um href ...) em vez de em um elemento de vídeo. (onDownloadListener não parece ser chamado nos elementos de vídeo ...)

Também vejo referências à substituição do onShowCustomView, mas isso parece não ser chamado nos elementos de vídeo ... nem shouldOverrideUrlLoading ..

Prefiro não entrar em "puxar xml do servidor, reformatá-lo no aplicativo". Mantendo o layout da história no servidor, posso controlar o conteúdo um pouco melhor sem forçar as pessoas a continuar atualizando um aplicativo. Portanto, se eu puder convencer o WebView a manipular tags como o navegador nativo, seria melhor.

Estou claramente perdendo algo óbvio ... mas não tenho idéia do que.

Brian Moore
fonte
Nessa mesma linha, estou procurando um player HTML5 para o meu site. O que devo usar?
precisa
1
A minha resposta aqui: stackoverflow.com/a/16179544/423171
cprcrack
1
Nada funcionou, então eu olhei para VideoEnabledWebViewaqui stackoverflow.com/questions/15768837/…
EpicPandaForce

Respostas:

92

Respondo a este tópico, caso alguém o leia e esteja interessado no resultado. É possível visualizar um elemento de vídeo (tag video html5) em um WebView, mas devo dizer que tive que lidar com ele por alguns dias. Estes são os passos que tive que seguir até agora:

-Encontre um vídeo codificado corretamente

-Quando inicializar o WebView, defina o JavaScript, Plug-ins, o WebViewClient e o WebChromeClient.

url = new String ("http://broken-links.com/tests/video/"); 
mWebView = (WebView) findViewById (R.id.webview);
mWebView.setWebChromeClient (chromeClient);
mWebView.setWebViewClient (wvClient);
mWebView.getSettings (). setJavaScriptEnabled (true);
mWebView.getSettings (). setPluginState (PluginState.ON);
mWebView.loadUrl (url);

-Manuseie o onShowCustomView no objeto WebChromeClient.

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    super.onShowCustomView(view, callback);
    if (view instanceof FrameLayout){
        FrameLayout frame = (FrameLayout) view;
        if (frame.getFocusedChild() instanceof VideoView){
            VideoView video = (VideoView) frame.getFocusedChild();
            frame.removeView(video);
            a.setContentView(video);
            video.setOnCompletionListener(this);
            video.setOnErrorListener(this);
            video.start();
        }
    }
}

-Manuseie os eventos onCompletion e onError do vídeo, para voltar à exibição na web.

public void onCompletion(MediaPlayer mp) {
    Log.d(TAG, "Video completo");
    a.setContentView(R.layout.main);
    WebView wb = (WebView) a.findViewById(R.id.webview);
    a.initWebView();
}

Mas agora devo dizer que ainda há uma questão importante. Eu posso tocar apenas uma vez. Na segunda vez que clico no distribuidor de vídeo (no pôster ou em algum botão de reprodução), ele não faz nada.

Também gostaria que o vídeo fosse reproduzido dentro do quadro do WebView, em vez de abrir a janela do Media Player, mas isso é para mim um problema secundário.

Espero que ajude alguém, e também gostaria de agradecer qualquer comentário ou sugestão.

Saludos, terrícolas.

mdelolmo
fonte
Eu não corro nenhum resultado, minha tela é preta. Eu quero saber se isso precisa. meu código é muito longo para aparecer aqui. você pode me dar uma forma de contato ou abrir outro tópico.
8102 pengwang
Tem certeza de que não é um problema de codificação? Tente com o URL que eu postei. Obviamente, ele tem que trabalhar com o navegador nativo
mdelolmo
46
o que é uma"? como essa atividade seria?
Collin Price
1
@Collin Price a é uma instância da Atividade que hospeda a visualização na web. @ desgraci, posso fornecer, mas não há muito além disso. Faça uma classe estender WebChromeCliente substituir os métodos correspondentes necessários. Se você insistir, posso enviar o restante da aula mais tarde quando chegar em casa.
Mdelolmo 11/07/2012
6
Não está funcionando no ICS, pois getFocusedChild () não é um VideoView, mas um HTML5VFullScreen $ SurfaceVideoView. Alguma idéia de como fazer no ICS? (consulte stackoverflow.com/questions/13540654/…
Pascal,
61

Após uma longa pesquisa, consegui fazer isso funcionar. Veja o seguinte código:

Test.java

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Test extends Activity {

    HTML5WebView mWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new HTML5WebView(this);

        if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
        } else {    
            mWebView.loadUrl("http://192.168.1.18/xxxxxxxxxxxxxxxx/");
        }

        setContentView(mWebView.getLayout());
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    }

    @Override
    public void onStop() {
        super.onStop();
        mWebView.stopLoading();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView.inCustomView()) {
                mWebView.hideCustomView();
            //  mWebView.goBack();
                //mWebView.goBack();
                return true;
            }

        }
        return super.onKeyDown(keyCode, event);
    }
}

HTML% VIDEO.java

package com.ivz.idemandtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

public class HTML5WebView extends WebView {

    private Context                             mContext;
    private MyWebChromeClient                   mWebChromeClient;
    private View                                mCustomView;
    private FrameLayout                         mCustomViewContainer;
    private WebChromeClient.CustomViewCallback  mCustomViewCallback;

    private FrameLayout                         mContentView;
    private FrameLayout                         mBrowserFrameLayout;
    private FrameLayout                         mLayout;

    static final String LOGTAG = "HTML5WebView";

    private void init(Context context) {
        mContext = context;     
        Activity a = (Activity) mContext;

        mLayout = new FrameLayout(context);

        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);

        mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);

        // Configure the webview
        WebSettings s = getSettings();
        s.setBuiltInZoomControls(true);
        s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        s.setUseWideViewPort(true);
        s.setLoadWithOverviewMode(true);
      //  s.setSavePassword(true);
        s.setSaveFormData(true);
        s.setJavaScriptEnabled(true);
        mWebChromeClient = new MyWebChromeClient();
        setWebChromeClient(mWebChromeClient);

        setWebViewClient(new WebViewClient());

setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

        // enable navigator.geolocation 
       // s.setGeolocationEnabled(true);
       // s.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");

        // enable Web Storage: localStorage, sessionStorage
        s.setDomStorageEnabled(true);

        mContentView.addView(this);
    }

    public HTML5WebView(Context context) {
        super(context);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public FrameLayout getLayout() {
        return mLayout;
    }

    public boolean inCustomView() {
        return (mCustomView != null);
    }

    public void hideCustomView() {
        mWebChromeClient.onHideCustomView();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((mCustomView == null) && canGoBack()){
                goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private class MyWebChromeClient extends WebChromeClient {
        private Bitmap      mDefaultVideoPoster;
        private View        mVideoProgressView;

        @Override
        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
        {
            //Log.i(LOGTAG, "here in on ShowCustomView");
            HTML5WebView.this.setVisibility(View.GONE);

            // if a view already exists then immediately terminate the new one
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomViewContainer.addView(view);
            mCustomView = view;
            mCustomViewCallback = callback;
            mCustomViewContainer.setVisibility(View.VISIBLE);
        }

        @Override
        public void onHideCustomView() {
            System.out.println("customview hideeeeeeeeeeeeeeeeeeeeeeeeeee");
            if (mCustomView == null)
                return;        

            // Hide the custom view.
            mCustomView.setVisibility(View.GONE);

            // Remove the custom view from its container.
            mCustomViewContainer.removeView(mCustomView);
            mCustomView = null;
            mCustomViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();

            HTML5WebView.this.setVisibility(View.VISIBLE);
            HTML5WebView.this.goBack();
            //Log.i(LOGTAG, "set it to webVew");
        }


        @Override
        public View getVideoLoadingProgressView() {
            //Log.i(LOGTAG, "here in on getVideoLoadingPregressView");

            if (mVideoProgressView == null) {
                LayoutInflater inflater = LayoutInflater.from(mContext);
                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
            }
            return mVideoProgressView; 
        }

         @Override
         public void onReceivedTitle(WebView view, String title) {
            ((Activity) mContext).setTitle(title);
         }

         @Override
         public void onProgressChanged(WebView view, int newProgress) {
             ((Activity) mContext).getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress*100);
         }

         @Override
         public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
             callback.invoke(origin, true, false);
         }
    }


    static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
        new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

custom_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@+id/fullscreen_custom_content"
        android:visibility="gone"
        android:background="@color/black"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:id="@+id/error_console"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
        />

        <FrameLayout android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
    </LinearLayout>
</FrameLayout>

video_loading_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/progress_indicator"
         android:orientation="vertical"
         android:layout_centerInParent="true"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">

       <ProgressBar android:id="@android:id/progress"
           style="?android:attr/progressBarStyleLarge"
           android:layout_gravity="center"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" />

       <TextView android:paddingTop="5dip"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center"
           android:text="@string/loading_video" android:textSize="14sp"
           android:textColor="?android:attr/textColorPrimary" />
 </LinearLayout>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/http_authentication_colors.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->
<!-- FIXME: Change the name of this file!  It is now being used generically
    for the browser -->
<resources>
    <color name="username_text">#ffffffff</color>
    <color name="username_edit">#ff000000</color>

    <color name="password_text">#ffffffff</color>
    <color name="password_edit">#ff000000</color>

    <color name="ssl_text_label">#ffffffff</color>
    <color name="ssl_text_value">#ffffffff</color>

    <color name="white">#ffffffff</color>
    <color name="black">#ff000000</color>



    <color name="geolocation_permissions_prompt_background">#ffdddddd</color>
</resources>

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Test"
                  android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:configChanges="orientation|keyboardHidden|keyboard">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>  
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
</manifest>

Esperando o resto das coisas que você pode entender.

surendra
fonte
7
Essa deve ser a resposta aceita. Surendra e Malenkiy, vocês dois salvaram minha sanidade. Funcionou muito bem para mim.
George Baker
Eu concordo com o George. É exatamente assim que o navegador nativo do Android funciona com o VideoView. Parece que este é o mesmo código que aqui code.google.com/p/html5webview . Funciona muito bem para todas as versões do Android (eu testei no Android 2.2 e superior). Gostaria de observar apenas uma coisa: lembre-se de que, se você alterar o SDK de destino para algo acima de 13, a atividade de sua será recriada com a alteração da orientação. Para evitar isso, quer anexar screensize para android: configChanges (mas neste caso, você precisará usar min SDK <13) ou usar velho SDK alvo (então você pode manter android: configChanges)
Yuriy Ashaev
2
Isso está me dando uma tela branca em branco no nexus 7 (android 4.1). Alguma idéia de como consertar isso?
Sahil
O botão traseiro não para o vídeo e o áudio ainda é audível, alguma idéia de como consertar isso?
perfil completo de CONVID19
Era isso que eu estava procurando exatamente como o fluxo do navegador nativo. Obrigado a Ton Surendra e Malenkiy.
Abhilash
33

A resposta de mdelolmo foi incrivelmente útil, mas, como ele disse, o vídeo é reproduzido apenas uma vez e você não pode abri-lo novamente.

Analisei um pouco isso e eis o que encontrei, caso algum viajante cansado do WebView como eu tropeçar neste post no futuro.

Primeiro, examinei a documentação do VideoView e do MediaPlayer e tive uma melhor noção de como elas funcionam. Eu recomendo fortemente aqueles.

Então, olhei o código-fonte para ver como o Navegador Android faz isso. Faça uma página encontrar e vá ver como eles lidam onShowCustomView(). Eles mantêm uma referência à CustomViewCallbackexibição personalizada e.

Com tudo isso, e com a resposta de mdelolmo em mente, quando você terminar o vídeo, tudo o que você precisa fazer é duas coisas. Primeiro, na VideoViewqual você salvou uma referência, a chamada stopPlayback()que liberará a MediaPlayerserá usada posteriormente em outro lugar. Você pode vê-lo no código fonte do VideoView . Segundo, CustomViewCallbackvocê salvou uma referência para ligar CustomViewCallback.onCustomViewHidden().

Depois de fazer essas duas coisas, você pode clicar no mesmo vídeo ou em qualquer outro vídeo e ele abrirá como antes. Não há necessidade de reiniciar todo o WebView.

Espero que ajude.

cottonBallPaws
fonte
Na verdade, eu meio que resolvi isso também, só não me lembro de postar a solução (que vergonha). Assim como você, eu tive que dar uma olhada no código do navegador Android e, bem, não há muito a acrescentar, usei o ouvinte onCompletion para parar o Player e tive que definir a visibilidade algumas vezes, mas eu compraria sua solução. Saudações!
Mdelolmo
1
O Google Code Search foi retirado, acho que esta versão do BrowserActivity.java (da Froyo) corresponde aproximadamente à descrita aqui: github.com/android/platform_packages_apps_browser/blob/…
michiakig
O código vinculado do @ spacemanki não contém nenhuma menção ao VideoView em todo o repositório. Eu acho que BrowserActivity faz diferente agora. Até voltei ao lançamento do Eclair. Não foi possível encontrar nenhum uso.
Mxcl 22/03/12
O problema que tenho com tudo isso é que estou voltando do frame.getFocusedChild (); é um HTml5VideoView em vez de um ViewView e, portanto, nenhum dos isso funciona para mim e não pode mudar para fullscreen :( Eu estou no Android 4.1.2.
Gonan
1
O que finalmente fez por mim foi adicionar: @Override public void onStop () {super.onStop (); mWebView.destroy (); } para a atividade ... o webview.destroy () foi crucial
MacD 04/04
8

Na verdade, parece suficiente apenas anexar um WebChromeClient de ações à visão do cliente, ala

mWebView.setWebChromeClient(new WebChromeClient());

e você precisa ter a aceleração de hardware ativada!

Pelo menos, se você não precisar reproduzir um vídeo em tela cheia, não será necessário puxar o VideoView para fora da WebView e empurrá-lo para a visualização da Atividade. Ele será reproduzido no retângulo alocado do elemento de vídeo.

Alguma idéia de como interceptar o botão de expansão de vídeo?

Russ Schnapp
fonte
você pode interceptá-lo usando o WebChromeClient e substituindo onShowCustomView
Frank
Especifique qual versão do Android. Isso funciona de maneira diferente para versões diferentes.
18714 Ethan_AI
7

Sei que este tópico tem vários meses, mas encontrei uma solução para reproduzir o vídeo dentro do WebView sem fazê-lo em tela cheia (mas ainda no media player ...). Até agora, não encontrei nenhuma dica sobre isso na internet, então talvez isso também seja interessante para outros. Ainda estou lutando com alguns problemas (ou seja, colocando o media player na seção correta da tela, não sei por que estou fazendo errado, mas acho que é um problema relativamente pequeno ...).

No ChromeClient personalizado, especifique LayoutParams:

// 768x512 is the size of my video
FrameLayout.LayoutParams LayoutParameters = 
                                     new FrameLayout.LayoutParams (768, 512); 

Meu método onShowCustomView é assim:

public void onShowCustomView(final View view, final CustomViewCallback callback) {
     // super.onShowCustomView(view, callback);
     if (view instanceof FrameLayout) {
         this.mCustomViewContainer = (FrameLayout) view;
         this.mCustomViewCallback = callback;
         this.mContentView = (WebView) this.kameha.findViewById(R.id.webview);
         if (this.mCustomViewContainer.getFocusedChild() instanceof VideoView) {
             this.mCustomVideoView = (VideoView) 
                                     this.mCustomViewContainer.getFocusedChild();
             this.mCustomViewContainer.setVisibility(View.VISIBLE);
             final int viewWidth = this.mContentView.getWidth();
             final int viewLeft = (viewWidth - 1024) / 2;
             // get the x-position for the video (I'm porting an iPad-Webapp to Xoom, 
             // so I can use those numbers... you have to find your own of course...
             this.LayoutParameters.leftMargin = viewLeft + 256; 
             this.LayoutParameters.topMargin = 128;
             // just add this view so the webview underneath will still be visible, 
             // but apply the LayoutParameters specified above
             this.kameha.addContentView(this.mCustomViewContainer, 
                                             this.LayoutParameters); 
             this.mCustomVideoView.setOnCompletionListener(this);
             this.mCustomVideoView.setOnErrorListener(this);
             // handle clicks on the screen (turning off the video) so you can still
             // navigate in your WebView without having the video lying over it
             this.mCustomVideoView.setOnFocusChangeListener(this); 
             this.mCustomVideoView.start();
         }
     }
 }

Então, espero poder ajudar ... Eu também tive que brincar com a codificação de vídeo e vi diferentes tipos de uso do WebView com vídeo html5 - no final, meu código de trabalho era uma mistura selvagem de diferentes partes de código encontradas em a internet e algumas coisas que eu tive que descobrir sozinha. Realmente foi uma dor no a *.

SOU
fonte
No ICS, getFocusedChild () não retorna um VideoView. Alguma idéia de como fazer isso funcionar no ICS?
187 Pascal
4

Essa abordagem funciona muito bem até 2.3. E, adicionando hardwareaccelerated = true, funciona até 3.0 para o ICS. Um problema que estou enfrentando atualmente é o segundo lançamento do aplicativo media player que está sendo travado porque eu não parei a reprodução e liberei o Media player. Como o objeto VideoSurfaceView, que obtemos na função onShowCustomView do SO 3.0, é específico para o navegador e não um objeto VideoView como no, até o SO 2.3 Como posso acessá-lo e interromper a reprodução e liberar recursos?

Nova
fonte
3

As AMs são semelhantes às do BrowerActivity . para FrameLayout.LayoutParams LayoutParameters = novo FrameLayout.LayoutParams (768, 512);

Acho que podemos usar

FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
            FrameLayout.LayoutParams.FILL_PARENT) 

em vez de.

Outro problema que encontrei é se o vídeo está sendo reproduzido e o usuário clica no botão Voltar. Na próxima vez, você acessará esta atividade (primeira opção única) e não poderá reproduzir o vídeo. para consertar isso, chamei o

try { 
    mCustomVideoView.stopPlayback();  
    mCustomViewCallback.onCustomViewHidden();
} catch(Throwable e) { //ignore }

no método onBackPressed da atividade.

yincan
fonte
2

Sei que essa é uma pergunta muito antiga, mas você já tentou o hardwareAccelerated="true"sinalizador de manifesto para seu aplicativo ou atividade?

Com esse conjunto, ele parece funcionar sem nenhuma modificação do WebChromeClient (o que eu esperaria de um elemento DOM).

Fralda
fonte
2
hardwareAcceleratedinicia a partir do Android 3.0
vbence
2

Eu usei o html5webview para resolver esse problema. Faça o download e coloque-o no seu projeto para poder codificar da seguinte maneira.

private HTML5WebView mWebView;
String url = "SOMEURL";
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mWebView = new HTML5WebView(this);
    if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
    } else {
            mWebView.loadUrl(url);
    }
    setContentView(mWebView.getLayout());
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mWebView.saveState(outState);
}

Para tornar o vídeo rotativo, coloque o código android: configChanges = "guidance" em sua Atividade, por exemplo (Androidmanifest.xml)

<activity android:name=".ui.HTML5Activity" android:configChanges="orientation"/>

e substitua o método onConfigurationChanged.

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
}
Methuz Kaewsai-kao
fonte
2

Esta pergunta tem anos, mas talvez minha resposta ajude pessoas como eu que precisam oferecer suporte à versão antiga do Android. Eu tentei várias abordagens diferentes que funcionavam em algumas versões do Android, mas não em todas. A melhor solução que encontrei é usar o Crosswalk Webview, que é otimizado para suporte a recursos HTML5 e funciona no Android 4.1 e superior. É tão simples de usar quanto o Android WebView padrão. Você apenas precisa incluir a biblioteca. Aqui você encontra um tutorial simples de como usá-lo: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/

Apfelsaft
fonte
Nota: A faixa de pedestres não é mais mantida .
slhck 6/02/19
1

Bem, aparentemente isso não é possível sem o uso de um JNI para registrar um plug-in para obter o evento de vídeo. (Pessoalmente, estou evitando JNIs, já que realmente não quero lidar com uma bagunça quando os tablets Android baseados em Atom forem lançados nos próximos meses, perdendo a portabilidade do Java.)

A única alternativa real parece ser criar uma nova página da Web apenas para o WebView e gravar vídeos da maneira antiga com um link A HREF, conforme mencionado no URL do Codelark acima.

Icky.

Brian Moore
fonte
1

No uso do favo de mel hardwareaccelerated=truee pluginstate.on_demandparece funcionar

user953501
fonte
1

Eu tive um problema parecido. Eu tinha arquivos e vídeos HTML na pasta de ativos do meu aplicativo.

Portanto, os vídeos foram localizados dentro do APK. Como o APK é realmente um arquivo ZIP, o WebView não conseguiu ler os arquivos de vídeo.

Copiar todos os arquivos HTML e de vídeo para o cartão SD funcionou para mim.

RhodanV5500
fonte