Ta odpowiedź jest specyficzna tylko dla Vimeo. Po kilkunastu nieudanych próbach, oto co pracuję. Być może pomoże to komuś innemu. Tysiące przeprosin dla autorów innych odpowiedzi na SO. "Pożyczyłem" kilka wzorów poniżej - tylko pomyślałem, że przydałoby się to wszystko w jednym miejscu i nie roszczę sobie ich za mój własny kod.
Po pierwsze, nie znalazłem sposobu na osadzenie odtwarzacza Vimeo (tzn. Nie można uzyskać bezpośrednio strumienia MP4 - przynajmniej nie łatwo lub niezawodnie - jestem prawie pewien, że jest to celowe). Po drugie, Vimeo oferuje bibliotekę javascript na instrumentowanie swojego odtwarzacza, a korzystanie z niej jest dość nieuniknione. Uwaga, wymaga przesłania wiadomości, co jest nowszą funkcją przeglądarki. Jest to udokumentowane na ich stronie API. Po trzecie, jak to jest udokumentowane w innym miejscu SO, musisz być bardzo ostrożny, aby poczekać, aż części stosu staną się gotowe, a nie do skoku pistoletowego. Po czwarte, odtwarzacz Vimeo zawiera szczególnie niepomocny obraz tła, który ma przekazać, że wtyczka jest brakująca lub zepsuta (mała klatka filmu, wspólna ikona dla tego). Oznacza to, że twój javascript został zbombardowany gdzieś i nic nie działa. Jeśli zobaczysz odrobinę filmu na pustym ekranie, sprawdź swój javascript.
Krok 1. Skonfiguruj WebView. Masz to poprawnie powyżej. Dla odniesienia, tutaj jest to, czego użyłem.
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);
Krok 2. Potrzebujesz WebChromeClient, jeśli chcesz, aby wideo działało na WebView. To jest udokumentowane tutaj: http://developer.android.com/reference/android/webkit/WebView.html (Patrz Obsługa HTML Video).
Ponownie, dla odniesienia tutaj jest to, czego użyłem.
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 wygląda następująco:
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);
}
}
}
Krok 3. Trzeba budować odrobinę JavaScript, żeby odpalić odtwarzacz. Użyłem tego:
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);" +
"});");
}
Szybkie wyjaśnienie. . . Używam jQuery w moim JS, który jest poniżej. To tylko dla wygody, możesz zrobić proste JS, jeśli chcesz zmniejszyć obciążenie. Zauważ, że gdy wszystko inne jest już gotowe, skrypt czeka kolejne 3 sekundy na odpalenie. W moich słabszych chwilach wyobrażam sobie, że ludzie z Vimeo mają zepsute "gotowe" oddzwanianie. Wydaje się, że robi to 3 sekundy.
Krok 4. Potrzebujesz strony HTML i JavaScript. Umieściłem go w pliku tekstowym wewnątrz zasobów (raw/vimeo_frame.html).Plik wygląda następująco:
<!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>
I załadować ten plik HTML tak:
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);
}
}
i wstrzyknąć go tak:
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);
Uff! Kiedy WebView jest gotowy, wtedy html i js wchodzą, w tym iframe z odtwarzaczem Vimeo. Po załadowaniu dokumentu czekamy, aż odtwarzacz stanie się gotowy. Kiedy odtwarzacz jest gotowy, dodajemy niektórych słuchaczy. A 3 sekundy później uruchamiamy metodę api "play".
Te polerki jabłkowe na widowni mogą się zastanawiać, dla kompletności, jak zatrzymać wideo? Dwa bity. Po pierwsze, zatrzymam go, obserwując wyjście konsoli dla wyświetlanego komunikatu. Zatem:
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('');" +
"});");
}
który może być wstawiony tak:
@Override
public void onPause() {
super.onPause();
if(isFinishing()){
// Unload the page
if(mWebView != null) {
Log.i(TAG, " ------> Destroying WebView");
mWebView.destroy();
}
}
finish();
}
Drugi kawałek jest, gdy film kończy trochę siebie. Tak więc, w vimeo_frame.html powyżej, zaraz po „Play” zwrotnego, kładę:
froogaloop.addEvent('finish', function(data) {
console.log('EVENT -- Finish');
});
oraz w działalności, kładę trochę uważać na to - patrz wyżej w ręcznym onConsoleMessage.
JEDNAK - od tego pisania wciąż nie rozwiązałem jednego dokuczliwego problemu. MediaPlayer żyje po tym, jak WebView zniknął z jego potomstwa. Jestem pewien, że stwarza to pewne problemy, ale jeszcze ich nie zidentyfikowałem.
czy powyższy kod działa bez autoodtwarzania ?? – Venkat
Tak, ustawiłem również WebViewClient, który pokazuje/ukrywa pasek postępu, nie wiem, czy ustawienie niestandardowego WebViewClient wpływa na to? – scottyab
ale próbowałem dużo za pomocą ur code.but it isnot pracy. więc używam niestandardowej przeglądarki internetowej – Venkat