2012-01-27 83 views
5

我已經設法使用以下方式獲取vimeo視頻加載和播放。然而,如影片oembed doc所示,自動播放= 1在加載時不會自動播放。任何人發現了一種自動播放(還需要在視頻結束捕捉事件)在Android中自動播放vimeo視頻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

是上面的代碼是不是自動播放? – Venkat 2013-04-10 05:09:44

+0

是的,我還設置了一個顯示/隱藏進度條的WebViewClient,不確定設置自定義的WebViewClient會影響它嗎? – scottyab 2013-04-11 09:35:09

+0

但我嘗試了很多使用我們的代碼。但它不工作。所以我使用自定義的webview – Venkat 2013-04-22 07:17:24

回答

8

我們已經遇到了同樣的問題,似乎Android的WebView的(以及那些在iOS)不編程爲允許自動啓動視頻,因爲它可能會吃掉某些人的數據計劃。除非你想以谷歌的WebView爲起點並推出自己的產品,否則你必須實際使用它。這聽起來並不容易,我們試過了!

+0

這聽起來似乎是合理的,webviews沒有編程去做,你有沒有找到特定的代碼在Android webview類導致你的結論? – scottyab 2012-02-09 06:28:05

+0

這不是有代碼來阻止它,而是沒有代碼來實現它。 – CaseyB 2012-02-09 16:41:02

+0

@CaseyB這個答案是從2012年開始的,它還是正確的嗎? – khizar 2014-09-29 05:03:03

10

此答案只適用於Vimeo。經過大約十次失敗的嘗試後,這裏是我的工作。也許它會幫助別人。向其他SO答案的原作者致歉。我已經'借用了'下面的一些模式 - 只是認爲將所有這些放在一個地方很方便,並且不要爲我自己的代碼聲明它們。首先,我還沒有找到一種方法來嵌入Vimeo播放器(即無法直接訪問mp4流 - 至少不容易或不可靠 - 我敢肯定這是故意的)。其次,Vimeo提供了一個JavaScript庫來測試他們的播放器,並且使用它是相當不可避免的。請注意,它需要消息傳遞,這是一個較新的瀏覽器功能。這是記錄在他們的API頁面上。第三,正如其他地方所記載的那樣,你需要非常小心地等待堆疊的部分準備就緒,並且不要跳槍。第四,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視頻支持)。

再次,這裏的參考是我使用的。

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準備就緒後,html和js進入,包括帶有Vimeo播放器的iframe。當文件被加載時,我們等待玩家準備就緒。當玩家準備好後,我們添加一些聽衆。 3秒鐘後,我們開始使用api'play'方法。

觀衆中的那些蘋果打火機可能會想知道,爲了完整起見,如何停止視頻?兩位。首先,當它結束時,我通過觀看控制檯輸出來顯示一條消息來停止它。因此:

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

可以插入像這樣:

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

第二位是視頻完成其一點自我。因此,在上述vimeo_frame.html,只是「玩」回調後,我把:

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

而在活動中,我說得有點看這個 - 見上面的onConsoleMessage覆蓋。

然而,截至撰寫本文時,我還沒有對一個嘮叨的問題進行排序。在WebView及其後代消失之後,MediaPlayer繼續存在。我確信這會產生一些問題,但我還沒有確定它們。

+1

我注意到,準備好也不會被解僱。它被破壞或者它只是Android的WEBVIEW UUUUUUHHHHHGGGGHHHH。 – 2013-10-08 18:02:52

+0

我很確定它已經壞掉 - 儘管WebView肯定有它的挑戰。 Vimeo只是悄悄地重做了他們的球員(也許四周前現在呢?)。我們花了一些時間去適應它,但上述解決方案仍然有效。 – 2013-10-09 11:10:10

+0

我得到了Vimeo的工作(接受外部播放/暫停/尋求命令)比這個少得多的代碼,我會在我清理了一下代碼後發佈另一個答案。 – 2013-10-09 16:01:49

0

我有同樣的問題,我認爲你可以用這個來做到這一點:

公共抽象無效setMediaPlaybackRequiresUserGesture(布爾 要求)

在API級別17設置是否WebView要求用戶手勢 播放媒體。默認值是true。

參數要求的WebView是否需要用戶手勢玩 媒體

希望能幫助你至少有一點!