【问题标题】:Problem to load flv video in webview在 webview 中加载 flv 视频的问题
【发布时间】:2011-09-29 14:07:27
【问题描述】:

我想在 webview 中加载 .flv 视频。

我得到了this link 的帮助,但问题是我无法在模拟器中观看视频。

这是我的代码:

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: 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);
        }
    }
  }

}

我在 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>

更新

【问题讨论】:

  • 好吧,不要试图在模拟器上玩flv或flash。他们永远无法播放这些格式。如果您有支持闪存的设备,请在上面尝试您的示例。它应该可以工作。
  • 能否请您发布您的 main.xml 文件。
  • 我的 main.xml 更新了,请注意
  • 这很奇怪。 XML 指定了一个 WebView,您转换为一个 WebView,系统抱怨,因为它声称该视图是一个 VideoView。您绝对确定这是正在加载的main.xml 布局文件吗?也许你有一个 layout-portrait 或类似的资源文件夹和不同的 main.xml
  • @Ted Hopp 好的,现在我需要做什么

标签: android flash


【解决方案1】:

这对我来说适用于本地 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
    }
}

    }

【讨论】:

    【解决方案2】:

    我之前遇到过这个问题。问题是 load() 中的 URL 编码。您必须对 ?和 = 分别对应 URL 编码的等效 %3F 和 %3D。

    【讨论】:

      【解决方案3】:

      您没有明确说明您的 Android 版本是什么,但我可以确认 Flash 插件确实加载了,并且电影播放器​​确实使用了漩涡状图形。我可以让它进入全屏模式。我也可以播放在线视频,但不能从应用程序的资产文件夹播放,但我有一个解决方法。

      manifest.xml 中需要以下许可:

      <uses-permission android:name="android.permission.INTERNET"></uses-permission> <!-- where required -->
      <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
      

      有趣的是,我发现我只能在静态加载 html 时从 assets 文件夹运行 SWF 播放器,即当我创建一个 html 文件并使用 loadUrl() 直接从 assets 文件夹加载它时。当使用 loadDataBaseUrl 方法加载 html 数据时,似乎有一些东西阻止了对应用程序目录的访问。

      要成功从本地设备播放视频,需要一个静态 html 文件,并且视频必须位于 sdcard 上。我唯一的结论是,出于安全原因,assets 文件夹禁止使用嵌入式插件。

      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% 有效的解决方案,但您必须在调用 loadUrl 以动态替换视频文件名之前将 html 文件写入 sdcard。此外,您应该将资产文件夹中的视频复制到 sdcard 上的相同路径中(正如您从我的示例中看到的那样,我创建了一个名为 FLVplayer 的文件夹。

      在运行 Froyo(2.2) 的三星 Galaxy Tab 上进行的测试

      更新

      我包含了一个已经过测试和工作的完整活动。这需要将 Flash 播放器、FLV 文件和 index.html 文件的副本放在 sdcard 根目录上名为“FLVplayer”的文件夹中,您可以使用文件资源管理器复制该文件夹。您可以编辑各种实用程序函数来修改从资产文件夹复制文件的行为

      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);
              }
          }
        }
      
      }
      

      附录

      我相信有一种方法可以绕过安全问题,方法是拦截各种文件的 URL,并使用 WebViewClient.shouldInterceptRequest() 直接从资产文件夹返回数据,但这需要 API 11,因此不适合作为通用解决方案。

      【讨论】:

      • 感谢您的回答。我试过你的答案,它显示请安装 adobe flush player 插件。那我该怎么办
      • 我用这个synesthesia.it/playing-flash-flv-videos-in-android-applications链接播放flv视频。 flv 视频是在 HTC 而不是三星 Galaxy Ace 中播放的。所以然后我尝试了你的代码,它显示请安装 adobe 刷新播放器插件。请告诉我我必须改变什么。
      • 你需要安装 adobe flash player ...我应该在 Galaxy Ace 上工作没有问题
      • 我从 android 市场找到了 adobe flash player。当点击安装时,它显示 adobe flash player 已从 android 市场中删除。所以请给我下载adobe flash player的链接
      • 好的,感谢您提供链接,但它没有安装在三星 Galaxy Ace 中。我不知道是什么问题。
      【解决方案4】:

      这里有一个快速提示。 我知道模拟器不支持闪存,许多廉价的安卓手机也不支持闪存。因此,当您进行测试时,请确保您在支持闪存的手机中进行测试。

      【讨论】:

      • 你是对的,但我也在手机中测试过,但无法成功。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      • 1970-01-01
      • 2014-08-02
      • 2012-01-18
      相关资源
      最近更新 更多