Question

Je suis en train de créer une application bon marché qui, entre autres, "encadre" certains de nos sites Web...Assez simple avec le WebViewClient.jusqu'à ce que je frappe la vidéo.

La vidéo est réalisée comme HTML5 éléments, et ceux-ci fonctionnent très bien sur Chrome, les iPhones, et maintenant que nous avons résolu les problèmes d'encodage, cela fonctionne très bien sur Android dans le navigateur natif.

Maintenant le hic : WebView n'aime pas ça.Du tout.Je peux cliquer sur l'image de l'affiche et rien ne se passe.

En cherchant sur Google, j'ai trouvé ce ce qui est proche, mais semble être basé sur un « lien » (comme dans un href...) au lieu d'un élément vidéo.(onDownloadListener ne semble pas être invoqué sur les éléments vidéo...)

Je vois également des références au remplacement de onShowCustomView, mais cela ne semble pas être appelé sur les éléments vidéo...ni ShouldOverrideUrlLoading..

Je préfère ne pas me lancer dans "extraire le XML du serveur, le reformater dans l'application".en conservant la mise en page de l'histoire sur le serveur, je peux mieux contrôler le contenu sans obliger les gens à continuer de mettre à jour une application.Donc, si je peux convaincre WebView de gérer les balises comme le navigateur natif, ce serait mieux.

Il me manque clairement quelque chose d'évident..mais je n'ai aucune idée de quoi.

Était-ce utile?

La solution

Je réponds à ce sujet juste au cas où quelqu'un a lu et est intéressé sur le résultat. Il est possible de voir un élément vidéo (tag vidéo html5) dans un WebView, mais je dois dire que je devais traiter pendant quelques jours. Ce sont les étapes que je devais suivre jusqu'à présent:

-Find correctement une vidéo encodée

-Lorsque l'initialisation du WebView, régler le JavaScript, les plug-ins le WebViewClient et le 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);

-Handle la onShowCustomView dans l'objet 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();
        }
    }
}

-Poignée la onCompletion et les événements onError pour la vidéo, afin de revenir à la vue 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();
}

Mais maintenant, je dois dire qu'il ya encore une question importante. Je peux jouer une seule fois. La deuxième fois que je clique sur le répartiteur vidéo (soit l'affiche ou un bouton de lecture), il ne fait rien.

Je voudrais aussi que la vidéo à jouer à l'intérieur du cadre de WebView, au lieu d'ouvrir la fenêtre Media Player, mais cela est pour moi une question secondaire.

J'espère que cela aide quelqu'un, et je remercie également tout commentaire ou suggestion.

Saludos, Terricolas.

Autres conseils

Après de longues recherches, je suis arrivé ce travail chose. Voir le code suivant:

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>

Expecting reste de choses que vous pouvez comprendre.

La réponse de mdelolmo était incroyablement utile, mais comme il a dit, la vidéo est lue une seule fois et vous ne pouvez pas l'ouvrir à nouveau.

je regardais dans ce un peu et voici ce que je trouve, dans le cas où tous les voyageurs fatigués WebView comme moi trébuchent sur ce poste à l'avenir.

Tout d'abord, je l'ai regardé VideoView et MediaPlayer de documentation et a obtenu une meilleure idée de la façon dont les travaux. Je recommande fortement ceux-ci.

Alors, je regardais le code source pour voir comment le navigateur Android fait. Faites une découverte de la page et allez voir comment ils gèrent onShowCustomView(). Ils gardent une référence au CustomViewCallbackand à la vue personnalisée.

Avec tout cela, et la réponse de mdelolmo à l'esprit, lorsque vous avez terminé avec la vidéo, tout ce que vous devez faire est de deux choses. Tout d'abord, sur le VideoView que vous avez enregistré une référence à, appel stopPlayback() qui libérera le MediaPlayer à utiliser plus tard ailleurs. Vous pouvez le voir dans la section code source de VideoView. En second lieu, sur la CustomViewCallback vous avez enregistré une référence à l'appel CustomViewCallback.onCustomViewHidden().

Après avoir fait ces deux choses, vous pouvez cliquer sur la même vidéo ou tout autre vidéo et ouvrira comme avant. Pas besoin de redémarrer l'ensemble WebView.

L'espoir qui aide.

En fait, il semble suffisant de fixer simplement un stock WebChromeClient à la vue du client, ala

mWebView.setWebChromeClient(new WebChromeClient());

et vous devez avoir l'accélération matérielle activée!

Au moins, si vous n'avez pas besoin de lire une vidéo en plein écran, il n'y a pas besoin de tirer le VideoView de la WebView et le pousser dans le point de vue de l'activité. Il jouera dans le rect alloué de l'élément vidéo.

Toutes les idées comment intercepter le bouton vidéo? élargissons

Je sais que ce fil est plusieurs mois, mais j'ai trouvé une solution pour lire la vidéo dans la WebView sans le faire en plein écran (mais toujours dans le lecteur multimédia ...). Jusqu'à présent, je ne trouve aucune allusion à ce sujet dans Internet alors peut-être c'est aussi intéressant pour les autres. Je me bats toujours sur certaines questions (à savoir placer le lecteur multimédia dans la partie droite de l'écran, ne sais pas pourquoi je le fais mal, mais il est une question relativement faible, je pense ...).

Dans la mesure ChromeClient spécifier LayoutParams:

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

Mon méthode onShowCustomView ressemble à ceci:

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

Alors, j'espère que je pourrais aider ... Moi aussi, je devais jouer avec la vidéo-Encoding et a vu différents types d'utilisation de la WebView avec html5 vidéo - à la fin de mon code de travail était un mélange sauvage de différentes parties de code J'ai trouvé dans Internet et certaines choses que je devais comprendre par moi-même. Il était vraiment une douleur dans le plan a *.

Cette approche fonctionne bien jusqu'à très 2.3 Et en ajoutant hardwareaccelerated = true, il fonctionne même de 3,0 à ICS Un problème que je suis confronté est actuellement à la deuxième lancement de l'application de lecteur multimédia se est écrasé parce que je ne l'ai pas arrêté la lecture et publié Media Player. Comme objet VideoSurfaceView, que nous obtenons en fonction onShowCustomView de 3.0 OS, sont spécifiques au navigateur et non un objet VideoView comme, jusqu'à 2.3 OS Comment puis-je accéder et stopPlayback et des ressources libération?

AM est similaire à ce que la BrowerActivity fait. pour       FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams (768, 512);

Je pense que nous pouvons utiliser

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

au lieu.

Une autre question que j'ai rencontré est si la lecture de la vidéo, et l'utilisateur clique sur le bouton de retour, la prochaine fois, vous allez à cette activité (singleTop un) et ne peut pas lire la vidéo. pour résoudre ce problème, j'ai appelé le

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

dans la méthode onBackPressed de l'activité.

Je sais que c'est une question très ancienne, mais avez-vous essayé le drapeau manifeste hardwareAccelerated="true" pour votre application ou activité?

Avec cet ensemble, il semble fonctionner sans aucune modification de WebChromeClient (que j'attendre d'un DOM-élément.)

html5webview pour résoudre ce problem.Download et le mettre dans votre projet, vous peut coder comme ça.

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

Pour la vidéo rotative, mettre android: configChanges = code "d'orientation" dans votre activité par exemple (AndroidManifest.xml)

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

et remplacer la méthode onConfigurationChanged.

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

Cette question est ans, mais peut-être ma réponse aider les gens comme moi qui ont à supporter ancienne version Android. J'ai essayé beaucoup de différentes approches qui ont travaillé sur certaines versions Android, mais pas sur tous. La meilleure solution que je trouve est d'utiliser le Crosswalk Webview qui est optimisé pour le support de HTML5 fonctionnalité et fonctionne sur Android 4.1 et plus haute. Il est aussi simple à utiliser par défaut Android WebView. Il suffit d'inclure la bibliothèque. Ici vous pouvez trouver un tutoriel simple sur la façon de l'utiliser: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/

Eh bien, apparemment, ce n'est tout simplement pas possible sans utiliser un JNI pour enregistrer un plugin afin d'obtenir l'événement vidéo.(Personnellement, j'évite les JNI car je ne veux vraiment pas avoir affaire à un gâchis lorsque des tablettes Android basées sur Atom sortiront dans les prochains mois, perdant ainsi la portabilité de Java.)

La seule véritable alternative semble être de créer une nouvelle page Web uniquement pour WebView et de réaliser des vidéos à l'ancienne avec un lien A HREF comme cité dans l'URL Codelark ci-dessus.

Icky.

Lors de l'utilisation en nid d'abeille hardwareaccelerated=true et pluginstate.on_demand semble fonctionner

J'ai eu un problème similaire. J'ai eu des fichiers HTML et des vidéos dans le dossier actifs de mon application.

Par conséquent, les vidéos ont été situé à l'intérieur de l'APK. Parce que l'APK est vraiment un fichier ZIP, le WebView n'a pas été en mesure de lire les fichiers vidéo.

Copie tous HTML- et des fichiers vidéo sur la carte SD a fonctionné pour moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top