19

私は を持ってActivityWebViewます。中にWebChromeClient入っています。MediaPlayerその中には、ビデオ ビットの処理を返すためのコールバックがいくつかあります。例えば:

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

MP4 ストリームWebViewを HTML<video>タグを使用して (インジェクション経由で) ロードすると、これらは起動しません。

アクティビティをfinish()実行すると、logcat は次のように報告します。

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.

WebViewなんとかして、クリアしてから破壊しても止められません。タグを使用してビデオをロードする場合、作成した特定のタグを強制的に使用する<video>方法がわかりません。上記を報告する隠されたものを使用することが決定されているようです。のタグを介して作成されたを見つける方法はありますか?WebChromeClientMediaPlayerMediaPlayer<video>WebView

- アップデート

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

「フレーム」コードは、ビデオを起動するための iframe です (少なくとも、Vimeo と YouTube の両方がこのアプローチを採用しているようです)。クラフトを避けるために、これを少し剪定しました。

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

その WebView クラス内には、次のクラスが存在します。

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

}

また、このクラス:

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

そして、運が良ければ、MediaPlayer から何らかの応答が得られる場合に備えて、通常の容疑者をすべて上書きしています。

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

補足として、私はリフレクションを使って掘り下げ、その方法で MediaPlayer を手に入れましたが、そのようなことをした後はいつも少し気が狂っています。MediaPlayer オブジェクトを持っていても、それを解放するのは気が進まないのです。MP のソース コードを少し調べてみると、悪いことは何も起こらないことがわかりますが、. . .

これはすべてのデバイスで発生するわけではありません。たとえば、HTC は Samsung よりも動作が優れているようです (「同じ」OS/API レベル - 私は 2 つのソース ツリーを比較するほど野心的ではありません)。

以下に示す動作は迷惑ですが、私 (logcat の出力を見ている人) にとってのみです。ユーザーまたはアプリケーションにとっては効果がないようです。MediaPlayer インスタンスを開始し、それは忙しいキャッシュアウェイ、そして(ユーザーが私のアプリを終了した場合)そこにそのディングルベリーをぶら下げたままにします. 私はこの時点で治療に多額のお金を縛っていますが、それは役に立っていないようです.

前もって感謝します。

4

2 に答える 2

5

リフレクションなしで MediaPlayer にアクセスする方法はありません。WebViewClient と WebChromeClient は意図的にそれを公開しません。また、リフレクションを使用するとアプリや WebView が壊れる可能性があると言って間違いありません。これは、Android のバージョンや OEM によってコードが異なる可能性があるためです。

これを行うには、ビデオ要素に対応する HTML5VideoView のインスタンスを見つける必要があります。このオブジェクトは、MediaPlayer のインスタンスを「mPlayer」として作成および維持します。https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/core/java/android/webkit/HTML5VideoView.javaをご覧ください。

于 2012-12-04T23:01:14.323 に答える
4

in your class

private class MyWebChromeClient extends WebChromeClient 
                                implements ..... MediaPlayer.onCompletion {
}

adding

@Override
public void onCompletion(MediaPlayer mp) {
    // TODO Auto-generated method stub
    mp.release();           
}

gets rid of the error messages for me after the webview closes.

Now if only I could get the webview to play/stream vimeo videos :(

于 2013-04-04T07:53:09.670 に答える