2012-01-27 16 views
5

He logrado obtener un video vimeo para cargar y reproducir, utilizando lo siguiente. Sin embargo, la reproducción automática = 1 como se indica en el vimeo oembed doc s no se reproduce automáticamente en la carga. Cualquier persona encontró una forma de reproducción automática (también tienen que ponerse al evento cuando el vídeo termina)Reproducción automática de videos vimeo en Android webview

mWebView.getSettings().setJavaScriptEnabled(true); 
mWebView.getSettings().setAppCacheEnabled(true); 
mWebView.getSettings().setDomStorageEnabled(true); 

// how plugin is enabled change in API 8 
if (Build.VERSION.SDK_INT < 8) { 
    mWebView.getSettings().setPluginsEnabled(true); 
} else { 
    mWebView.getSettings().setPluginState(PluginState.ON); 
} 
mWebView.loadUrl("http://player.vimeo.com/video/24577973?player_id=player&autoplay=1&title=0&byline=0&portrait=0&api=1&maxheight=480&maxwidth=800"); 
+0

¿El código anterior funciona sin reproducción automática? – Venkat

+0

Sí, también configuré un WebViewClient que muestra/oculta una barra de progreso, ¿no está seguro de si configurar un WebViewClient personalizado lo afecta? – scottyab

+0

pero probé mucho usando tu código. Pero no funciona. entonces uso webview personalizado – Venkat

Respuesta

8

que hemos encontrado el mismo problema y parece que Android WebView 's (así como aquellos en IOS) no son programado para permitir el inicio automático de videos, ya que es posible que se coman en el plan de datos de alguien. Tienes que tocar en realidad a menos que quieras tomar el WebView de Google como punto de partida y hacer tu propio. ¡No es tan fácil como suena, lo intentamos!

+0

Parece plausible que las vistas web no estén programadas para hacerlo, ¿encontró un código específico en la clase de vista web de Android que lo llevó a esta conclusión? – scottyab

+0

No hay código para detenerlo, es que no hay código para hacerlo. – CaseyB

+0

@CaseyB esta respuesta es de 2012, ¿sigue siendo correcta? – khizar

10

Esta respuesta es específica solo de Vimeo. Después de una docena de intentos fallidos, esto es lo que tengo trabajando. Quizás ayudará a alguien más. Mil disculpas a los autores originales de otras respuestas SO. He 'prestado' una serie de patrones a continuación, solo pensé que sería útil tener todo esto en un solo lugar, y no reclamarlos para mi propio código.

En primer lugar, no he encontrado una manera de incrustar el reproductor Vimeo (es decir, no se puede acceder directamente a la transmisión de mp4, al menos no de manera fácil o confiable) estoy bastante seguro de que es deliberado). En segundo lugar, Vimeo ofrece una biblioteca de JavaScript para instrumentar a su reproductor, y su uso es bastante inevitable. Tenga cuidado, requiere el envío de mensajes, que es una función de navegador más nueva. Esto está documentado en su página API. En tercer lugar, como se documenta en otra parte de SO, debe tener mucho cuidado de esperar para que las partes de la pila estén listas y no disparar. En cuarto lugar, el reproductor Vimeo incluye una imagen de fondo particularmente inútil que pretende transmitir que el complemento falta o está roto (un pequeño marco de película, icono común para esto). Lo que realmente significa es que su javascript ha sido bombardeado en algún lugar, y nada en absoluto se está ejecutando. Si ve un poco de película en una pantalla en blanco, verifique su javascript.

Paso 1. Configure un WebView. Tienes esto correcto arriba. Como referencia, aquí está lo que utilicé.

mWebView = new WebView((Context) this); 
mWebView.setLayoutParams(new LayoutParams(windowWidth, windowHeight)); 

mWebView.getSettings().setJavaScriptEnabled(true); 
// Watch the sdk level here, < 12 requires 'false 
// Wanted to force HTML5/264/mp4, you may want flash 
// where still available 
mWebView.getSettings().setPluginState(PluginState.OFF); 
mWebView.getSettings().setLoadWithOverviewMode(true); 
mWebView.getSettings().setUseWideViewPort(true); 
mWebView.getSettings().setUserAgentString("Android Mozilla/5.0 AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"); 

wcc = new MyWebChromeClient(); 
mWebView.setWebChromeClient(wcc); 

wvc = new MyWebViewClient(); 
mWebView.setWebViewClient(wvc); 

Paso 2. Usted necesita el WebChromeClient si desea que el vídeo para trabajar en la vista Web. Eso está documentado aquí: http://developer.android.com/reference/android/webkit/WebView.html (Ver Soporte de video HTML).

Nuevamente, para referencia aquí es lo que he usado.

private class MyWebChromeClient extends WebChromeClient { 
    @Override 
    public void onProgressChanged(WebView view, int progress) { 
     if(progress == 100) { 
      // Your page is loaded, but not visible, 
      // add whatever navigation elements you plan to use here. 
      // N.B. these are JAVA, not JS nav elements 
     } 
    } 

    @Override 
    public boolean onConsoleMessage(ConsoleMessage cm) { 

    // I like to watch in the console. And, since it was 
    // a very convenient way to monitor the javascript, I 
    // use it for that too. Purists will object, no doubt 

     if(cm.message().equalsIgnoreCase("EVENT -- Finish")) { 
      Log.i(TAG, "---> Finishing . . ."); 
      // Depart the activity 
      finish(); 
     } else { 
      Log.d(TAG, " **Console ["+cm.sourceId()+"] ("+cm.lineNumber()+") ["+cm.message()+"]"); 
     } 
     return(true); 
    } 

     @Override 
     public View getVideoLoadingProgressView() { 
         // Something entertaining while the bytes arrive 
      Log.i(TAG, " -------------> Loading Progress . . . "); 
      LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      return(inflater.inflate(R.layout.loading_video, null)); 
     } 

     @Override 
     public void onShowCustomView(View v, WebChromeClient.CustomViewCallback callback) { 
         // With great sadness, I report that this never fires. 
         // Neither does the 'hide'. 
     } 

     @Override 
     public void onHideCustomView() { 
     } 

} 

El WebViewClient se parece a esto:

private class MyWebViewClient extends WebViewClient { 

    @Override 
    public void onPageFinished(WebView view, String url) { 
      super.onPageFinished(view, url); 
      String injection = injectPageMonitor(); 
      if(injection != null) { 
      Log.d(TAG, " ---------------> Page Loaded . . ."); 
       Log.d(TAG, " Injecting . . . ["+injection+"]"); 
       view.loadUrl(injection); 
      } 
    } 

} 

Paso 3. Es necesario construir un poco de Javascript para disparar el jugador. Utilicé esto:

public String injectPageMonitor() { 
    return("javascript:" + 
       "jQuery(document).ready(function() { " + 
       "console.log(' === Page Ready ===> Setting up');" + 
       "console.log(' ==== Sending PLAY Command ===');" + 
       "var froogaloop = $f('froog');" + 
       "setTimeout(function() { froogaloop.api('play'); }, 3000);" + 
    "});"); 
} 

Explicación rápida. . . Uso jQuery en mi JS, eso viene a continuación. Eso es solo por conveniencia, puedes hacer JS directamente si quieres aligerar la carga. Tenga en cuenta que una vez que todo lo demás está listo, la secuencia de comandos espera otros 3 segundos para disparar en realidad. En mis momentos más débiles, me imagino que la gente amable de Vimeo tiene una devolución de llamada "lista" rota. 3 Segundos parece hacerlo.

Paso 4. Necesita un poco de HTML y JavaScript en la página. Lo puse en un archivo de texto dentro de los recursos (raw/vimeo_frame.html).El archivo tiene el siguiente aspecto:

<!DOCTYPE html> 
<html> 
<head> 

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> 
<script type="text/javascript">jQuery.noConflict();</script> 
<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script> 

<script type="text/javascript"> 

    jQuery(document).ready(function() { 
     var showing_player = false; 
     var froogaloop = $f('froog'); 

      console.log(' === Page Ready ===> Setting up'); 
     jQuery('.froog_container_class').hide(); 
     jQuery('.console').css('height', '100%'); 

     froogaloop.addEvent('ready', function() { 

      console.log('==== PLAYER READY ====> Setting Play Callback'); 
       froogaloop.addEvent('play', function(data) { 
       console.log('EVENT -- Play'); 
       /* No idea why, but if the player isn't displayed, it goes 
        straight to 'pause'. Probably a feature. So I give it 4x4px 
        to do it's thing during setup */ 
       jQuery('.froog_container_class').show(); 
       jQuery('.froog_container_class').css('height', '4px'); 
       jQuery('.froog_container_class').css('width', '4px'); 
       jQuery('.froog_container_class').css('overflow', 'hidden'); 
      }); 

      /* I don't want to reveal the video until it is actually 
       playing. So I do that here */ 
      var showingPlayer = false; 
      froogaloop.addEvent('playProgress', function(data) { 
       if(!showingPlayer && data.percent > 0) { 
        showingPlayer = true; 
        jQuery('.froog_container_class').show(); 
        jQuery('.froog_container_class').css('height', '_windowHeight'); 
        jQuery('.froog_container_class').css('width', '_windowWidth'); 
        /* Most tablets I tested aren't quick enough to make this work 
        but one can still hope */ 
        jQuery('#loading').fadeOut('slow'); 
       } 
      }); 

     }); 
}); 
</script> 
</head> 
<body> 
<style> 
    body { 
    background-image: url('http://<SomethingEntertainingToWatch>.png'); 
    background-size: contain; 
    } 
    .mask { 
    float: left; 
    height: _windowHeight; 
    width: _windowWidth; 
    z-index: 100; 
    background: transparent; 
    display: inline; 
    position: absolute; 
    top: 0; 
    left: 0; 
    } 
    .froog_container_class { 
     position: absolute; 
     height: _windowHeight; 
     width: _windowWidth; 
     left: 0; 
     top: 0; 
     display: inline; 
     z-index: 1; 
    } 
    #froog { 
     display: inline; 
     height: _windowHeight; 
     width: _windowWidth; 
     postion: absolute; 
     top: 0; 
     left: 0; 
    } 
</style> 
<div id="loading" class="loading"><h1>Loading</h1><img class="loading_anim" src="http://foo.bar.com/assets/global/loading.gif"/> 
</div> 
<!-- Completely optional, I put a div in front of the player to block controls --> 
<div id="mask" class="mask"> 
</div> 
<div id="froog_container" class="froog_container_class"> 
    <iframe id="froog" src="_targetUrl?api=1&title=0&byline=0&portrait=0&player_id=froog" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen> 
    </iframe> 
</div> 
</body> 
</html> 

Y me carga el archivo HTML de este modo:

public String genMainHTML() { 
    String code = null; 
    try { 
     Resources res = getResources(); 
     InputStream in_s = res.openRawResource(R.raw.vimeo_frame); 

     byte[] b = new byte[in_s.available()]; 
     in_s.read(b); 
     code = new String(b); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    if(code != null) { 
      code = code.replaceAll("_windowHeight", "" + windowHeight + "px"); 
      code = code.replaceAll("_windowWidth", "" + windowWidth + "px"); 
      code = code.replaceAll("_targetUrl", targetUrl); 
      return(code); 
    } else { 
      return(null); 
    } 
} 

e inyectarlo así:

mDomain = "http://player.vimeo.com"; 
mWebView.requestFocus(View.FOCUS_DOWN); 
targetUrl = extras.getString("URL"); 
String meat = genMainHTML(); 
mWebView.loadDataWithBaseURL(mDomain, meat, "text/html", "utf-8", null); 

setContentView(mWebView); 

Uf! Cuando WebView está listo, entran el html y el js, incluido el iframe con el reproductor Vimeo. Cuando el documento está cargado, esperamos que el reproductor esté listo. Cuando el jugador está listo, agregamos algunos oyentes. Y 3 segundos después, disparamos el método api 'play'.

Esos pulidores de manzanas en la audiencia pueden estar preguntándose, para ser completos, ¿cómo se detiene el video? Dos bits Primero, cuando termina, lo detengo viendo la salida de la consola para un mensaje que visualizo. Por lo tanto:

public String injectPageFinisher() { 
    return("javascript:" + 
      "jQuery(document).ready(function() { " + 
       "console.log(' === Page Ready ===> Tearing down');" + 
       "console.log(' ==== Sending PAUSE Command ===');" + 
       "var froogaloop = $f('froog');" + 
      "froogaloop.api('pause');" + 
       "jQuery('#froog_container').html('');" + 
      "});"); 
    } 

que puede ser insertado de este modo:

@Override 
public void onPause() { 
    super.onPause(); 
    if(isFinishing()){ 
     // Unload the page 
     if(mWebView != null) { 
      Log.i(TAG, " ------> Destroying WebView"); 
      mWebView.destroy(); 
     } 
    } 
    finish(); 
} 

El segundo bit es donde el video completa su pequeño yo. Así, en el vimeo_frame.html anteriormente, justo después de la devolución de llamada 'juego', puse:

froogaloop.addEvent('finish', function(data) { 
    console.log('EVENT -- Finish'); 
}); 

Y en la actividad, puse un poco de ver para esto - véase más arriba en la anulación onConsoleMessage.

SIN EMBARGO, al momento de escribir esto, todavía no he resuelto un problema persistente. El MediaPlayer permanece activo después de que WebView y toda su progenie desaparezcan. Estoy seguro de que esto crea algunos problemas, pero aún no los he identificado.

+1

Me di cuenta de que ready no se dispara también. ¿ESTÁ ROTO O ES SOLO LA PÁGINA WEB DE ANDROID UUUUUUHHHHHGGGGHHHH? –

+0

Estoy bastante seguro de que está roto, aunque WebView ciertamente tiene sus desafíos. Vimeo simplemente volvió a trabajar en silencio a su jugador (¿tal vez hace cuatro semanas?).Nos llevó un poco adaptarnos a él, pero la solución anterior aún funciona. –

+0

Tengo Vimeo para trabajar (y acepto comandos externos de reproducción/pausa/búsqueda) con mucho menos código que este, y publicaré otra respuesta aquí después de limpiar un poco el código. –

0

que tenían el mismo problema, creo que se puede utilizar éste para que esto ocurra:

pública abstract void setMediaPlaybackRequiresUserGesture (booleano requieren)

Agregado en el nivel de la API 17 establece si el WebView requiere un gesto de usuario para reproducir medios. El defecto es cierto.

parámetros requieren si la vista Web requiere un gesto de usuario para jugar medios

esperanza para ayudarle a al menos un poco!

Cuestiones relacionadas