Проблема с загрузкой FLV-видео в webview
Я хочу загрузить.flv видео в webview.
Я получил помощь эту ссылку, но проблема в том, что я не могу просматривать видео в эмуляторе.
Это мой код:
package com.FlvTester;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class FlvTester extends Activity {
WebView webView;
String htmlPre = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"></head><body style='margin:0; pading:0; background-color: black;'>";
String htmlCode =
" <embed style='width:100%; height:100%' src='http://www.platipus.nl/flvplayer/download/1.0/FLVPlayer.swf?fullscreen=true&[email protected]@' " +
" autoplay='true' " +
" quality='high' bgcolor='#000000' " +
" name='VideoPlayer' align='middle'" + // width='640' height='480'
" allowScriptAccess='*' allowFullScreen='true'" +
" type='application/x-shockwave-flash' " +
" pluginspage='http://www.macromedia.com/go/getflashplayer' />" +
"";
String htmlPost = "</body></html>";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginsEnabled(true);
htmlCode = htmlCode.replaceAll("@[email protected]", "file:///android_asset/expression_sad.flv");
webView.loadDataWithBaseURL("file:///android_asset/expression_sad.flv", htmlPre+htmlCode+htmlPost, "text/html", "UTF-8", null);
}
@Override
protected void onPause(){
super.onPause();
callHiddenWebViewMethod("onPause");
webView.pauseTimers();
if(isFinishing()){
webView.loadUrl("about:blank");
setContentView(new FrameLayout(this));
}
}
@Override
protected void onResume(){
super.onResume();
callHiddenWebViewMethod("onResume");
webView.resumeTimers();
}
private void callHiddenWebViewMethod(String name){
// credits: http://stackoverflow.com/info/3431351/how-do-i-pause-flash- content-in-an-android-webview-when-my-activity-isnt-visible
if( webView != null ){
try {
Method method = WebView.class.getMethod(name);
method.invoke(webView);
} catch (NoSuchMethodException e) {
//Lo.g("No such method: " + name + e);
} catch (IllegalAccessException e) {
//Lo.g("Illegal Access: " + name + e);
} catch (InvocationTargetException e) {
//Lo.g("Invocation Target Exception: " + name + e);
}
}
}
}
Я получил эту ошибку в log cat
07-06 12:00:48.567: WARN/dalvikvm(381): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): FATAL EXCEPTION: main
07-06 12:00:48.597: ERROR/AndroidRuntime(381): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.FlvTester/com.FlvTester.FlvTester}: java.lang.ClassCastException: android.widget.VideoView
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.os.Handler.dispatchMessage(Handler.java:99)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.os.Looper.loop(Looper.java:123)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at java.lang.reflect.Method.invokeNative(Native Method)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at java.lang.reflect.Method.invoke(Method.java:521)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at dalvik.system.NativeStart.main(Native Method)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): Caused by: java.lang.ClassCastException: android.widget.VideoView
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.FlvTester.FlvTester.onCreate(FlvTester.java:31)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): ... 11 more
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<WebView android:layout_width="match_parent" android:id="@+id/webview" android:layout_height="match_parent"></WebView>
</LinearLayout>
Обновление
![this is new image]()
Ответы
Ответ 1
Вы четко не указываете, какую версию для Android, но я могу подтвердить, что флеш-плагин действительно загружается, а проигрыватель видеороликов делает интилизацию с графикой swirly shape. Я могу включить его в полноэкранный режим. Я также могу играть в онлайн-видео, но не из папки ресурсов приложения, однако у меня есть обходной путь.
В вашем файле manifest.xml требуются следующие permissinos:
<uses-permission android:name="android.permission.INTERNET"></uses-permission> <!-- where required -->
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
Интересно, что я обнаружил, что смог запустить SWF-плеер из папки с ресурсами, когда html был статически загружен, когда я создал html файл и загрузился непосредственно из папки с ресурсами, используя loadUrl(). Кажется, что что-то блокирует доступ к каталогу приложения при загрузке html-данных с использованием метода loadDataBaseUrl.
Чтобы успешно воспроизводить видео с локального устройства, статический html файл и видео должно быть размещено на SD-карте. Мой единственный вывод заключается в том, что папка с ресурсами отключена встроенным плагином по соображениям безопасности.
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {
webView.loadUrl("file://"+Environment.getExternalStorageDirectory()+"/FLVplayer/index.html");
}
И вот html файл
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body style="margin:0; pading:0; background-color: black;">
<embed
style="width:100%; height:100%"
src="./FLVPlayer.swf?fullscreen=true&video=./expression_sad.flv"
autoplay="true"
quality="high"
bgcolor="#000000"
name="VideoPlayer"
align="middle"
allowScriptAccess="*"
allowFullScreen="true"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</body>
</html>
Это 100% -ное рабочее решение, но вам нужно будет написать html файл на SD-карту перед вызовом loadUrl для динамической замены имени видеофайла. Кроме того, вы должны скопировать видео из вашей папки с данными в тот же путь на SD-карте (как вы можете видеть из моего примера, я создал папку с именем FLVplayer.
Тест, выполненный на вкладке Samsung Galaxy, в которой запущен Froyo (2.2)
UPDATE
Я включаю в себя полную активность, которая была протестирована и работает. Это ожидает, что копия Flash-плеера, FLV файла и файла index.html будет помещена в папку с именем "FLVplayer" в корне вашей SD-карты, которую вы можете скопировать с помощью проводника файлов. Вы можете отредактировать различные функции утилиты, чтобы изменить поведение, чтобы скопировать файлы из папки ваших ресурсов.
package com.FLVplayer;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class FLVplayerActivity extends Activity {
private static final String TAG="FLVplayer";
private static WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webview);
//WebView webview = new WebView(this);
//setContentView(webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginsEnabled(true);
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {
//prepare the directory
File flvDirectory = new File(Environment.getExternalStorageDirectory(),"FLVplayer");
if(!flvDirectory.exists())
try {
flvDirectory.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//specify the html file name to use
File flvHtml = new File(flvDirectory,"index.html");
//copy what you need
copySwfAsset(flvDirectory, "FLVPlayer.swf");
copyFlvAsset(flvDirectory, "20051210-w50s.flv");
//render the html
createVideoHtml(flvHtml, "20051210-w50s.flv");
//load the content into the webview
webView.loadUrl(Uri.fromFile(flvHtml).toString());
//sit back, watch FLV and eat popcorn
}
}
private void createVideoHtml(File htmlFile, String htmlFileName)
{
//TODO render your own html file to sdcard
}
private void copySwfAsset(File flvDirectory, String flashFileName)
{
//TODO copy your own SWF video player file from assets
}
private void copyFlvAsset(File flvDirectory, String videoFileName)
{
//TODO copy your oown FLV file from asset folder
}
@Override
protected void onPause(){
super.onPause();
callHiddenWebViewMethod("onPause");
webView.pauseTimers();
if(isFinishing()){
webView.loadUrl("about:blank");
setContentView(new FrameLayout(this));
}
}
@Override
protected void onResume(){
super.onResume();
callHiddenWebViewMethod("onResume");
webView.resumeTimers();
}
private void callHiddenWebViewMethod(String name){
// credits: http://stackoverflow.com/questions/3431351/how-do-i-pause-flash- content-in-an-android-webview-when-my-activity-isnt-visible
if( webView != null ){
try {
Method method = WebView.class.getMethod(name);
method.invoke(webView);
} catch (NoSuchMethodException e) {
//Lo.g("No such method: " + name + e);
} catch (IllegalAccessException e) {
//Lo.g("Illegal Access: " + name + e);
} catch (InvocationTargetException e) {
//Lo.g("Invocation Target Exception: " + name + e);
}
}
}
}
ADENDUM
Я считаю, что может быть способ обойти проблемы безопасности, перехватив URL-адрес различных файлов и возвращая данные непосредственно из папки с ресурсами, используя WebViewClient. shouldInterceptRequest(), но для этого требуется API 11, поэтому он не подходит в качестве общего решения.
Ответ 2
Я столкнулся с этим вопросом раньше. Проблема заключается в кодировке URL в load(). Вы должны закодировать? и = к URL закодированному эквиваленту% 3F и% 3D соответственно.
Ответ 3
Это работает для меня для локальных файлов sdcard
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class MainActivity extends Activity {
private static final String TAG = "FLVplayer";
private static WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String file = "/sdcard/FLVplayer/20051210-w50s.flv";
String htmlPre = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"></head><body style='margin:0; pading:0; background-color: black;'>";
String htmlCode = " <embed style='width:100%; height:100%' src='/sdcard/FLVplayer/FLVPlayer.swf?fullscreen=true&video="
+ file
+ "&autoplay=true' "
+ " autoplay='true' "
+ " quality='high' bgcolor='#000000' "
+ " name='VideoPlayer' align='middle'"
+ // width='640' height='480'
" allowScriptAccess='*' allowFullScreen='true'"
+ " type='application/x-shockwave-flash' "
+ " pluginspage='http://www.macromedia.com/go/getflashplayer' />"
+ "";
String htmlPost = "</body></html>";
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
// WebView webview = new WebView(this);
// setContentView(webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
Log.d(TAG, "No SDCARD");
} else {
// load the content into the webview
// webView.loadUrl(htmlPre+htmlCode+htmlPost);
webView.loadDataWithBaseURL("file:///android_asset/FLVPlayer.swf",
htmlPre + htmlCode + htmlPost, "text/html", "UTF-8", null);
// sit back, watch FLV and eat popcorn
}
}
}
Ответ 4
Вот вам быстрый совет.
Я знаю, что эмуляторы не поддерживают флеш-память, многие из бюджетных телефонов Android не поддерживают флеш-память. Поэтому, когда вы проводите тестирование, убедитесь, что вы делаете это в телефоне, поддерживающем флэш-память.