2012-01-27 49 views
5

次のようにして、読み込んで再生するためのvimeo動画を取得できました。しかし、vimeo oembed docに示されているautoplay = 1は、ロード時に自動再生されません。誰もが私たちは、同じ問題に遭遇してきたし、Android WebView年代(だけでなく、iOSの上のもの)がないことを思わ自動再生への道(もビデオが終了したときにイベントをキャッチする必要があります)Android webviewでvimeoの動画を自動再生する

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

は、上記のコードは自動再生なしで動作していますか? – Venkat

+0

はい、カスタムWebViewClientを設定しても効果がないかどうかはわかりませんが、進捗バーを表示/非表示するWebViewClientも設定していますか? – scottyab

+0

しかし、私はur code.butを使ってたくさん試しました。私はカスタムwebviewを使用する – Venkat

答えて

8

を見つけましたそれは誰かのデータプランを食べる可能性があるので、ビデオの自動開始を許可するようにプログラムされています。 GoogleのWebViewを出発点にして自分でロールしたいのでなければ、実際にそれをタップする必要があります。それは聞こえるほど簡単ではありません、私たちは試しました!

+0

これは、webviewsはそれを行うようにプログラムされていない可能性があると思う、あなたはこの結論に導いたAndroid webviewクラス内の特定のコードを見つけましたか? – scottyab

+0

それを止めるコードはありません。それを実現させるコードはありません。 – CaseyB

+0

@CaseyBこの回答は2012年ですが、それはまだ正しいですか? – khizar

10

この回答はVimeoにのみ適用されます。約12回失敗した試行の後、ここで私が働いているものがあります。多分それは誰かを助けるでしょう。他のSO答えの原作者に何千もの謝罪。私は以下のパターンをいくつも借りてきました。ただ一つの場所にすべてを持っていると便利だと思っていて、自分のコードを要求していません。

最初に、私はVimeoプレーヤーを埋め込む方法を見つけられませんでした(つまり、mp4ストリームには直接アクセスできません - 少なくとも簡単で信頼性の高い方法ではありません - 私はかなり熟考しています)。第二に、Vimeoはプレーヤーを装備するためのjavascriptライブラリを提供しており、それを使用することはかなり避けられません。気をつけて、それは新しいブラウザ機能であるメッセージパッシングを必要とします。これはAPIページに記載されています。第3に、SOの他の場所に記載されているように、スタックの一部が準備完了になるのを待って、ガンジャンプしないように注意する必要があります。第4に、Vimeoプレーヤーには、プラグインが紛失または破損していることを伝えることを目的とした、特に役に立たない背景画像が含まれています(これは映画の小さな枠組みです)。本当に意味するのは、あなたのJavaScriptがどこかで爆破され、何も実行されていないということです。あなたが空白の画面に少しのフィルムを見たら、あなたのJavaScriptをチェックしてください。

ステップ1. WebViewを設定します。あなたはこれを上記のとおりにしています。参考までに、ここで私が使ったことがあります。

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

ステップ2.ビデオをWebViewで使用するには、WebChromeClientが必要です。それはここに書かれています:http://developer.android.com/reference/android/webkit/WebView.html(HTML Video Supportを参照)。

ここでも参考にしています。

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

} 

WebViewClientは次のようになります。

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

} 

ステップ3.あなたがプレーヤーを発射するのJavascriptのほんの少しを構築する必要があります。私はこれを使用しました:

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

簡単な説明。 。 。私はJSでjQueryを使用していますが、これは以下のとおりです。利便性のためだけですが、ロードを軽くしたい場合は、ストレートJSを行うことができます。他のすべての準備ができたら、スクリプトは実際に起動するまでさらに3秒待つことに注意してください。私の弱い瞬間には、Vimeoの親切な人たちが壊れた "準備完了"コールバックを持っていると思います。 3秒はそれをするようです。

ステップ4.ページにHTMLとJavaScriptが必要です。私はリソース(raw/vimeo_frame.html)の中のテキストファイルに入れます。ファイルには、次のようになります。

<!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> 

そして、私はそうのように、このHTMLファイルをロード:

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

をそしてそうのようにそれを注入:

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

やれやれ! WebViewが準備完了すると、Vimeoプレーヤーのiframeを含むhtmlとjsが入ります。ドキュメントがロードされると、プレーヤーは準備が整うのを待ちます。プレーヤーが準備ができたら、いくつかのリスナーを追加します。そして3秒後、私たちはapi 'play'メソッドを起動します。

観客の中のリンゴポリッシャーは、完全性のためにビデオをどのように停止するのだろうかと疑問に思うかもしれません。 2ビット。まず、終了時に、表示されたメッセージのコンソール出力を見て停止します。したがって:

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

ビデオはその少し自己を完了したところ、第2のビットは次のとおりですので、同じように挿入することができ

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

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

を、活動に、私はこれを監視するビットを置く - onConsoleMessageオーバーライドで上記参照:したがって、上記vimeo_frame.htmlでは、単に「遊び」コールバックした後、私は置きます。

この記事の執筆時点では、まだまだ問題は1つもありません。 MediaPlayerは、WebViewとその子孫がすべて消えた後も存続します。私はこれがいくつかの問題を引き起こすと確信していますが、私はそれらをまだ特定していません。

+1

私は準備ができても解雇されないことに気づいた。それは壊れているのか、それとも単にアンドロイドのWEBVIEW UUUUUHHHHHHHGGGGHHHHです。 –

+0

私はそれが壊れていることは間違いないと確信していますが、WebViewには確かに課題があります。 Vimeoはちょうど静かにプレイヤーを修正しました(おそらく4週間前ですか?)。調整するのに少し時間がかかりましたが、上記の解決策はまだ機能します。 –

+0

私はVimeoをこれよりもはるかに少ないコードで動作させる(外部再生/一時停止/シークコマンドを受け入れる)ようにしました。コードを少しきれいにした後、別の答えを投稿します。 –

0

私は私はあなたがそれを実現するために、このいずれかを使用することができると考えて、同じ問題を持っていた:APIレベルで

パブリック抽象ボイドsetMediaPlaybackRequiresUserGesture(ブール が必要です)

を追加しました17かどうかを設定しますWebViewでメディアを再生するには、ユーザーの身振り が必要です。デフォルトはtrueです。

パラメータは、WebViewのは、あなたが、少なくとも少し手助けする メディア

希望を再生するには、ユーザーのジェスチャーを必要とするかどうかが必要です!

関連する問題