Android WebView Reproduzir HTML5 / h.264 / mp4 Vídeo, como chegar ao MediaPlayer

eu tenho umActivity que é umWebView. eu tenho umWebChromeClient dentro dele. Dentro disso, existem vários callbacks que devem retornarMediaPlayer manipulação dos bits de vídeo. Por exemplo:

@Override
public void onPrepared(MediaPlayer mp) {
    Log.i(TAG, " -------------> onPrepared");
}

Estes não conseguem disparar quando eu carrego um fluxo MP4 noWebView usando HTML<video> tags (via injeção).

Quando eufinish() a atividade, o logcat relata isso:

09-13 23:55:24.590: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:24.680: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:24.680: E/MediaPlayer(7949): mOnVideoSizeChangedListener is null. Failed to send MEDIA_SET_VIDEO_SIZE message.
09-13 23:55:25.675: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:26.735: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:27.755: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.
09-13 23:55:28.705: E/MediaPlayer(7949): mOnBufferingUpdateListener is null. Failed to send MEDIA_BUFFERING_UPDATE message.

Por mais que eu tente, não consigo parar, mesmo que oWebView é limpo e, em seguida, destruído. Ao carregar o vídeo usando<video> tags, eu não sei de qualquer maneira de forçar oWebChromeClient usar um determinadoMediaPlayer que eu criei para isso. Parece determinado usar algum oculto, que relata o acima. Existe uma maneira de localizar oMediaPlayer criado a partir de um<video> tag em umWebView?

--Atualizar

Aqui está o código para inicializar o WebView:

        mWebView = new WebView(mContext);

        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setPluginState(PluginState.OFF);
        mWebView.setVisibility(View.INVISIBLE);
        mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
        mWebView.getSettings().setBuiltInZoomControls(false);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.clearHistory();
        mWebView.clearFormData();
        mWebView.clearCache(true);
        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setUserAgentString("Android Mozilla/5.0 AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");

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

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

        mDomain = "http://foo.bar.com";
        mWebView.requestFocus(View.FOCUS_DOWN);

        String meat = genMainHTML(R.raw.frame);

        mWebView.loadDataWithBaseURL(mDomain, meat, "text/html", "utf-8", null);

O código "frame" é um iframe para lançar algum vídeo (o Vimeo e o YouTube parecem adotar essa abordagem, pelo menos). Eu tenho podado isso um pouco para evitar cruft:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
     <iframe src="-target.url.with.params-" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
     </iframe>
</div>
</body>
</html>

Dentro dessa classe WebView, existe essa classe:

private class MyWebViewClient extends WebViewClient {

    @Override
    public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            String injection = injectPageMonitor();
            if(injection != null && !injectionComplete) {
                // Log.i(TAG, " ---------------> Page Loaded . . .");
                view.loadUrl(injection);
                injectionComplete = true;
        }
    }

    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d(TAG, "*** Error ["+description+"] ["+failingUrl+"]");
        Toast.makeText(mContext, description, Toast.LENGTH_SHORT).show();
    }

}

E também esta classe:

    private class MyWebChromeClient extends WebChromeClient implements MediaPlayer.OnInfoListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnErrorListener, MediaPlayer.OnVideoSizeChangedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnBufferingUpdateListener {

       @Override
       public void onProgressChanged(WebView view, int progress) {
           //Log.e(TAG, " -------------> Progress Changed . . . . ["+progress+"] mWebView ["+mWebView+"] ["+view+"]");
           if(progress == 100) {
                               // Do something really interesting
           }  else  {
               updateBuffering(UPDATE_PERCENT_LAUNCH_EXTRACTOR + (progress / 2));
           }
       }

       @Override
       public boolean onConsoleMessage(ConsoleMessage cm) {
                       // Spit out lots of console messages here
           return(true);
       }
   }

E eu tenho todos os suspeitos do costume substituídos, apenas no caso de eu ter sorte e obter alguma resposta do MediaPlayer:

        @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        // Jump up and down because we got a mp!
                    // never happens, so no jumping
    }

Como uma nota lateral, eu explorei o reflexo e fiquei com o MediaPlayer dessa maneira, mas eu sempre me sinto um pouco obcecado depois de fazer esse tipo de coisa. E apesar de eu ter o objeto MediaPlayer, estou relutante em liberá-lo. Um pouco de estudo do código fonte do MP sugere que nada de ruim aconteceria, mas. . .

Isso não acontece em todos os dispositivos, eu notei. HTC parece se comportar melhor do que a Samsung, por exemplo ("mesmo" nível de OS / API - eu não sou realmente ambicioso o suficiente para comparar as duas árvores de origem).

O comportamento observado abaixo é chato, mas só para mim (que está assistindo a saída do logcat. Para o usuário ou aplicativo, parece não ter efeito. É que eu realmente não gosto da noção de que estou iniciando uma instância do MediaPlayer, definindo ele está ocupado, e depois (se / quando o usuário finaliza meu aplicativo) deixando o dingleberry por aí, eu tenho muito dinheiro preso em terapia neste momento, e isso não parece estar ajudando.

Desde já, obrigado.

questionAnswers(2)

yourAnswerToTheQuestion