Проблема с загрузкой FLV видео в WebView - PullRequest
12 голосов
/ 06 июля 2011

Я хочу загрузить .flv видео в веб-просмотре.

Я получил помощь от по этой ссылке , но проблема в том, что я не могу просматривать видео в эмуляторе.

Это мой код:

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&video=@VIDEO@' " +
        "  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("@VIDEO@",  "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: /2861923/kak-priostanovit-flash-kontent-v-android-webview-kogda-moya-aktivnost-ne-vidna 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);
        }
    }
  }

}

Я получил эту ошибку в журнале 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

Ответы [ 4 ]

11 голосов
/ 28 июля 2011

Вы не ясно указываете, какая у вас версия Android, однако я могу подтвердить, что флэш-плагин загружается, а проигрыватель фильмов интилируется с графикой в ​​форме кружка. Я могу включить его в полноэкранный режим. Я также могу воспроизводить онлайн-видео, но не из папки ресурсов приложения, однако у меня есть обходной путь.

В вашем файле manifest.xml требуются следующие разрешения:

<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 Tab под управлением Froyo (2.2)

UPDATE

Я включаю полное задание, которое было проверено и работает. Это предполагает, что копия Flash player, 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: /2861923/kak-priostanovit-flash-kontent-v-android-webview-kogda-moya-aktivnost-ne-vidna 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, поэтому не подходит в качестве общего решения.

1 голос
/ 19 февраля 2014

Это работает для меня для локальных файлов 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
    }
}

    }
0 голосов
/ 01 августа 2011

Я сталкивался с этой проблемой раньше. Проблема заключается в кодировке URL в load (). Вы должны закодировать? и = к URL в кодированном эквиваленте% 3F и% 3D соответственно.

0 голосов
/ 26 июля 2011

Вот краткий совет для вас.Я знаю, что эмуляторы не поддерживают флэш, многие бюджетные телефоны Android также не поддерживают флэш.Поэтому, когда вы проводите тестирование, убедитесь, что вы делаете это в телефоне, который поддерживает вспышку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...