Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem to load flv video in webview

Tags:

android

flash

I want to load .flv video in webview.

I have taken help from this link, but the problem is I'm not able to view video in emulator.

This is my code:

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

}

I got this error in 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>

Update

this is new image

like image 859
Nikunj Patel Avatar asked Jul 06 '11 12:07

Nikunj Patel


2 Answers

You don't state clearly what your Android version, however I can confirm that the flash plugin does load and the movie player does intilaize with the swirly shape graphic. I can engage it into fullscreen mode. I am also able to play online video but not from the application's assets folder, however I do have a workaround.

The following permissinos are required in your manifest.xml:

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

Interestingly I discovered I was only able to run the SWF player from the assets folder when the html was statically loaded i.e when I created an html file and loaded that directly from the assets folder using loadUrl(). There seems to be something blocking access to the application directory when html data is loaded using the loadDataBaseUrl method.

To succesfully get video to play from the local device a static html file and the video must be co-located on the sdcard. My only conclusion is that the assets folder is off limits to the embedded plugin for security reasons.

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    Log.d(TAG, "No SDCARD");
} else {
    webView.loadUrl("file://"+Environment.getExternalStorageDirectory()+"/FLVplayer/index.html");
    }

And here is the html file

<!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>

This is a 100% working solution but you would have to write your html file to the sdcard before calling loadUrl to dynaamically replace the video file name. In addition you should copy the video from your assets folder into the same path on the sdcard (as you can see from my exaple I created a folder called FLVplayer.

Test performed on Samsung Galaxy Tab running Froyo(2.2)

UPDATE

I am including a complete activity that has been tested and working. This expects a copy of the Flash player, the FLV file and the index.html file to be placed in a folder called "FLVplayer" on the root of your sdcard which you can copy across using the file explorer. You can edit the various utility functions to modify the behaviour to copy the files from your assetes folder

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

I believe there may be a way to bypass the security issues by intercepting the URL of the various files and returning the data directly from the assets folder using WebViewClient.shouldInterceptRequest() but that requires API 11 so not suitable as a generic solution.

like image 90
Moog Avatar answered Nov 08 '22 06:11

Moog


This is worked for me for local sdcard files

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

    }
like image 1
raj Avatar answered Nov 08 '22 06:11

raj