2012-01-27 122 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是否需要用户手势玩 媒体

希望能帮助你至少有一点!