WebView und HTML5 <Video>


122

Ich setze eine billige App zusammen, die unter anderem einige unserer Websites "umrahmt" ... Ziemlich einfach mit der WebViewClient. bis ich das Video getroffen habe.

Das Video wird als HTML5 Element erstellt, und diese funktionieren auf Chrome und iPhones einwandfrei, und jetzt, da wir die Codierungsprobleme behoben haben, funktioniert es Androidim nativen Browser hervorragend .

Jetzt die Reibung: WebViewmag es nicht. Überhaupt. Ich kann auf das Posterbild klicken und nichts passiert.

Beim Googeln habe ich festgestellt, dass dies nah ist, aber anscheinend auf einem 'Link' (wie in einem href ...) anstelle eines Videoelements basiert. (onDownloadListener wird anscheinend nicht für Videoelemente aufgerufen ...)

Ich sehe auch Verweise auf das Überschreiben von onShowCustomView, aber das scheint bei Videoelementen nicht aufgerufen zu werden ... und sollte auch nicht OverrideUrlLoading ..

Ich möchte lieber nicht auf "XML vom Server ziehen, in der App neu formatieren" eingehen. Indem ich das Story-Layout auf dem Server behalte, kann ich den Inhalt ein bisschen besser steuern, ohne die Leute zu zwingen, eine App weiter zu aktualisieren. Wenn ich WebView davon überzeugen kann, Tags wie den nativen Browser zu verarbeiten, ist dies am besten.

Mir fehlt eindeutig etwas Offensichtliches. Aber ich habe keine Ahnung, was.



In diesem Sinne suche ich einen HTML5-Player für meine Website. Was soll ich verwenden?
Wolfpack'08


1
Nichts hat funktioniert, also habe ich VideoEnabledWebViewhier nachgeschaut. Stackoverflow.com/questions/15768837/…
EpicPandaForce

Antworten:


92

Ich beantworte dieses Thema nur für den Fall, dass jemand es liest und sich für das Ergebnis interessiert. Es ist möglich, ein Videoelement (Video-HTML5-Tag) in einer WebView anzuzeigen, aber ich muss sagen, dass ich mich einige Tage damit befassen musste. Dies sind die Schritte, denen ich bisher folgen musste:

-Finden Sie ein richtig codiertes Video

- Wenn Sie WebView initialisieren, legen Sie das JavaScript fest, fügen Sie den WebViewClient und den WebChromeClient ein.

url = neuer 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);

- Behandeln Sie die onShowCustomView im WebChromeClient-Objekt.

@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();
        }
    }
}

- Behandeln Sie die Ereignisse onCompletion und onError für das Video, um zur Webansicht zurückzukehren.

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();
}

Aber jetzt sollte ich sagen, dass es noch ein wichtiges Thema gibt. Ich kann es nur einmal spielen. Wenn ich zum zweiten Mal auf den Video-Dispatcher klicke (entweder auf das Poster oder auf eine Wiedergabetaste), geschieht nichts.

Ich möchte auch, dass das Video im WebView-Frame abgespielt wird, anstatt das Media Player-Fenster zu öffnen, aber dies ist für mich ein sekundäres Problem.

Ich hoffe es hilft jemandem und ich würde mich auch für jeden Kommentar oder Vorschlag bedanken.

Saludos, Terrícolas.


Ich führe kein Ergebnis aus, mein Bildschirm ist schwarz. Ich möchte wissen, ob dies nötig ist. Mein Code ist zu lang, um hier zu posieren. Können Sie mir einen Kontakt geben oder ein anderes Thema öffnen?
Pengwang

Sind Sie ganz sicher, dass es sich nicht um ein Codierungsproblem handelt? Versuchen Sie es mit der URL, die ich gepostet habe. Offensichtlich muss es mit dem nativen Browser
funktionieren

46
Was ist "a"? wie diese Aktivität wäre das?
Collin Price

1
@Collin Price a ist eine Instanz der Aktivität, die die Webansicht hostet. @desgraci, ich kann es zur Verfügung stellen, aber es gibt nicht viel darüber hinaus. Lassen Sie eine Klasse WebChromeClientdie entsprechenden Methoden erweitern und überschreiben, die Sie benötigen. Wenn Sie darauf bestehen, kann ich den Rest der Klasse später hochladen, wenn ich nach Hause komme.
Mdelolmo

6
Funktioniert nicht mit ICS, da getFocusedChild () keine VideoView ist, sondern eine HTML5VFullScreen $ SurfaceVideoView. Irgendeine Idee, wie man es mit ICS macht? (siehe stackoverflow.com/questions/13540654/…
Pascal

61

Nach langer Recherche habe ich dieses Ding zum Laufen gebracht. Siehe folgenden Code:

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>

Farben.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>

Erwarten Sie den Rest der Dinge, die Sie verstehen können.


7
Dies sollte die akzeptierte Antwort sein. Surendra und Malenkiy, ihr beide habt meine geistige Gesundheit gerettet. Hat super für mich funktioniert.
George Baker

Ich stimme George zu. Genau so funktioniert der native Android-Browser mit VideoView. Dies scheint der gleiche Code wie hier zu sein . Code.google.com/p/html5webview . Es funktioniert hervorragend für alle Android-Versionen (ich habe auf Android 2.2 und höher getestet). Nur eine Sache, die ich bemerken wollte, sollten Sie bedenken, dass, wenn Sie das Ziel-SDK auf etwas über 13 ändern, Ihre Aktivität bei Änderung der Ausrichtung neu erstellt wird. Um dies zu vermeiden, hängen Sie entweder screenSize an android: configChanges an (in diesem Fall müssen Sie jedoch min sdk <13 verwenden) oder verwenden Sie das alte Ziel-SDK (dann können Sie android: configChanges behalten)
Yuriy Ashaev

2
Dies gibt mir einen weißen leeren Bildschirm auf Nexus 7 (Android 4.1). Irgendeine Idee, wie man das behebt?
Sahil

Der Backbutton stoppt das Video nicht und das Audio ist immer noch hörbar. Haben Sie eine Idee, wie Sie das beheben können?
CONvid19

Dies ist, was ich genau nach dem nativen Browser-Flow gesucht habe. Vielen Dank an Ton Surendra und Malenkiy.
Abhilash

33

mdelolmos antwort war unglaublich hilfreich, aber wie er sagte, das video wird nur einmal abgespielt und dann kann man es nicht wieder öffnen.

Ich habe mich ein wenig damit befasst und hier ist, was ich gefunden habe, falls müde WebView-Reisende wie ich in Zukunft über diesen Beitrag stolpern sollten.

Zunächst einmal, schaute ich auf der Videoview und Mediaplayer ‚s Dokumentation und bekam ein besseres Gefühl für , wie diese Arbeit. Ich kann diese nur empfehlen.

Dann habe ich mir den Quellcode angesehen, um zu sehen, wie der Android-Browser das macht. Machen Sie eine Seite suchen und schauen Sie sich an, wie sie damit umgehen onShowCustomView(). Sie behalten einen Verweis auf die CustomViewCallbackund auf die benutzerdefinierte Ansicht.

In Anbetracht dessen und unter Berücksichtigung der Antwort von mdelolmo müssen Sie nach Abschluss des Videos nur zwei Dinge tun. VideoViewRufen Sie zunächst auf dem, auf den Sie einen Verweis gespeichert haben, stopPlayback()den MediaPlayerauf, der später für eine andere Verwendung freigegeben wird. Sie können es im VideoView- Quellcode sehen. Zweitens haben Sie auf der CustomViewCallbackReferenz einen Anruf gespeichert CustomViewCallback.onCustomViewHidden().

Nachdem Sie diese beiden Dinge getan haben, können Sie auf dasselbe Video oder ein anderes Video klicken und es wird wie zuvor geöffnet. Sie müssen nicht das gesamte WebView neu starten.

Hoffentlich hilft das.


Eigentlich habe ich es auch irgendwie gelöst, ich habe mich nur nicht daran erinnert, die Lösung zu posten (Schande über mich). Genau wie Sie musste ich mir den Code des Android-Browsers ansehen, und nun, nicht viel hinzuzufügen, habe ich stattdessen den onCompletion-Listener verwendet, um den Player zu stoppen, und musste einige Male die Sichtbarkeit einstellen, aber ich würde Ihre Lösung kaufen. Grüße!
Mdelolmo

1
Die Google Code Search wurde eingestellt. Ich denke, diese Version von BrowserActivity.java (von Froyo) entspricht in etwa der hier beschriebenen: github.com/android/platform_packages_apps_browser/blob/…
michiakig

Der verknüpfte Code von @ spacemanki enthält keine Erwähnungen von VideoView im gesamten Repo. Ich denke, BrowserActivity macht es jetzt anders. Ich bin sogar zur Eclair-Veröffentlichung zurückgekehrt. Kann keine Verwendung finden.
mxcl

Das Problem, das ich mit all dem habe, ist das, was ich von frame.getFocusedChild () zurück bekomme; ist eine HTml5VideoView anstelle einer ViewView und daher funktioniert nichts davon für mich und kann nicht zum Vollbildmodus wechseln :( Ich bin auf Android 4.1.2.
Gonan

1
Was es schließlich für mich getan hat, war hinzuzufügen: @Override public void onStop () {super.onStop (); mWebView.destroy (); } für die Aktivität ... die webview.destroy () war entscheidend
MacD

8

Tatsächlich scheint es ausreichend zu sein, lediglich einen Standard-WebChromeClient an die Client-Ansicht anzuhängen, ala

mWebView.setWebChromeClient(new WebChromeClient());

und Sie müssen die Hardwarebeschleunigung aktiviert haben!

Wenn Sie kein Vollbildvideo abspielen müssen, müssen Sie die Videoansicht nicht aus der Webansicht ziehen und in die Ansicht der Aktivität verschieben. Es wird im zugewiesenen Rechteck des Videoelements abgespielt.

Irgendwelche Ideen, wie man die Schaltfläche zum Erweitern des Videos abfängt?


Sie können es mit WebChromeClient abfangen und onShowCustomView
Frank

Bitte geben Sie an, welche Version von Android. Dies funktioniert für verschiedene Versionen unterschiedlich.
Ethan_AI

7

Ich weiß, dass dieser Thread mehrere Monate alt ist, aber ich habe eine Lösung gefunden, um das Video in WebView abzuspielen, ohne es im Vollbildmodus auszuführen (aber immer noch im Media Player ...). Bisher habe ich im Internet keinen Hinweis darauf gefunden, daher ist dies möglicherweise auch für andere interessant. Ich habe immer noch Probleme mit einigen Problemen (z. B. Platzieren des Media Players im rechten Bereich des Bildschirms. Ich weiß nicht, warum ich es falsch mache, aber es ist ein relativ kleines Problem, denke ich ...).

Geben Sie im benutzerdefinierten ChromeClient LayoutParams an:

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

Meine onShowCustomView-Methode sieht folgendermaßen aus:

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();
         }
     }
 }

Also, ich hoffe ich könnte helfen ... Auch ich musste mit Video-Encoding herumspielen und sah verschiedene Arten der Verwendung von WebView mit HTML5-Video - am Ende war mein Arbeitscode eine wilde Mischung aus verschiedenen Code-Teilen, in denen ich gefunden habe das Internet und einige Dinge, die ich selbst herausfinden musste. Es war wirklich ein Schmerz im a *.


Auf ICS gibt getFocusedChild () keine VideoView zurück. Haben Sie eine Idee, wie dies auf ICS funktioniert?
Pascal

4

Dieser Ansatz funktioniert sehr gut bis 2.3. Und durch Hinzufügen von hardwareaccelerated = true funktioniert er sogar von 3.0 zu ICS. Ein Problem, mit dem ich derzeit konfrontiert bin, ist, dass beim zweiten Start der Media Player-Anwendung ein Absturz auftritt, da ich die Wiedergabe nicht gestoppt und den Media Player freigegeben habe. Da das VideoSurfaceView-Objekt, das wir in der onShowCustomView-Funktion ab dem Betriebssystem 3.0 erhalten, spezifisch für den Browser und nicht für ein VideoView-Objekt wie in 2.3 ist, wie kann ich darauf zugreifen und die Wiedergabe stoppen und Ressourcen freigeben?


3

AMs ähneln denen der BrowerActivity . für FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams (768, 512);

Ich denke wir können verwenden

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

stattdessen.

Ein weiteres Problem, auf das ich gestoßen bin, ist, wenn das Video abgespielt wird und der Benutzer beim nächsten Mal auf die Schaltfläche "Zurück" klickt. Sie gehen zu dieser Aktivität (singleTop one) und können das Video nicht abspielen. Um dies zu beheben, rief ich die

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

in der onBackPressed-Methode der Aktivität.


2

Ich weiß, dass dies eine sehr alte Frage ist, aber haben Sie das hardwareAccelerated="true"Manifest-Flag für Ihre Anwendung oder Aktivität ausprobiert ?

Mit diesem Set scheint es ohne WebChromeClient-Modifikation zu funktionieren (was ich von einem DOM-Element erwarten würde).


2
hardwareAcceleratedstartet von Android 3.0
vbence

2

Ich habe html5webview verwendet , um dieses Problem zu lösen. Laden Sie es herunter und fügen Sie es in Ihr Projekt ein. Dann können Sie einfach so codieren.

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);
}

Um das Video drehbar zu machen, fügen Sie beispielsweise den Code android: configChanges = "Orientierung" in Ihre Aktivität ein (Androidmanifest.xml).

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

und überschreiben Sie die onConfigurationChanged-Methode.

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

2

Diese Frage ist Jahre alt, aber vielleicht hilft meine Antwort Leuten wie mir, die die alte Android-Version unterstützen müssen. Ich habe viele verschiedene Ansätze ausprobiert, die bei einigen Android-Versionen funktionierten, jedoch nicht bei allen. Die beste Lösung, die ich gefunden habe, ist die Verwendung von Crosswalk Webview, das für die Unterstützung von HTML5-Funktionen optimiert ist und unter Android 4.1 und höher funktioniert. Es ist so einfach zu bedienen wie das Standard-Android-WebView. Sie müssen nur die Bibliothek einschließen. Hier finden Sie ein einfaches Tutorial zur Verwendung: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/


Hinweis: Der Zebrastreifen wird nicht mehr gewartet .
Slhck

1

Nun, anscheinend ist dies einfach nicht möglich, ohne ein JNI zu verwenden, um ein Plugin zu registrieren, um das Videoereignis zu erhalten. (Ich persönlich vermeide JNIs, da ich mich wirklich nicht mit einem Durcheinander befassen möchte, wenn Atom-basierte Android-Tablets in den nächsten Monaten herauskommen und die Portabilität von Java verlieren.)

Die einzige wirkliche Alternative scheint darin zu bestehen, eine neue Webseite nur für WebView zu erstellen und Videos auf die alte Art und Weise mit einem A HREF-Link zu erstellen, wie in der obigen Codelark-URL angegeben.

Eklig.


1

Auf Wabengebrauch hardwareaccelerated=trueund pluginstate.on_demandscheint zu funktionieren


1

Ich hatte ein ähnliches Problem. Ich hatte HTML-Dateien und Videos im Assets-Ordner meiner App.

Daher befanden sich die Videos innerhalb der APK. Da es sich bei der APK tatsächlich um eine ZIP-Datei handelt, konnte WebView die Videodateien nicht lesen.

Das Kopieren aller HTML- und Videodateien auf die SD-Karte hat bei mir funktioniert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.