7

I'm building an app with a WebView thats supposed to play a video, that's saved locally. Strangely the video player is not working with local video files. It does play videos saved on a server though.

The local files (html and video) are saved in a folder assets/html_test

Here are the files.

HTML

<div class="video-container">
  <p>Server</p>
  <video poster="video/star.png" controls>
    <source src="http://broken-links.com/tests/media/BigBuck.m4v" />
  </video>
</div>

<div class="video-container">
  <p>local</p>
  <video poster="video/star.png" controls>
    <source src="BigBuck.m4v" />
  </video>
</div>

onCreate in Activity

WebView browser = (WebView) findViewById(R.id.browser);

WebSettings webSettings = browser.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setPluginState(WebSettings.PluginState.ON_DEMAND);
webSettings.setAllowFileAccessFromFileURLs(true);

browser.setWebChromeClient(new WebChromeClient());

browser.loadUrl("file:///android_asset/html_test/video.html");

The first video works, the second one doesn't. I tried different values for the source, neither of them worked for me:

<source src="BigBuck.m4v" />
<source src="file:///android_asset/html_test/BigBuck.m4v" />

Not sure if this is related, but as soon as I press play, logcat puts out this:

01-07 12:19:18.073: E/MediaPlayer(32542): error (1, -2147483648)
01-07 12:19:18.073: E/MediaPlayer(32542): Error (1,-2147483648)

I have no clue what the problem is here. Any help would be much appreciated.

taymless
  • 779
  • 2
  • 9
  • 24
  • I think it should be `file://` and not `file:///`, just confirm about that. – sanjeev mk Jan 07 '13 at 11:31
  • 3
    This error is generally seen because the format of the file you are playing is not supported on Android. http://developer.android.com/guide/appendix/media-formats.html OR: A permission problem? See if this helps : http://www.weston-fl.com/blog/?p=2988 – Vrashabh Irde Jan 07 '13 at 11:36
  • @taymless Can you try with `` instead of ` – sanjeev mk Jan 07 '13 at 11:39
  • @taymless can you tell me how did you solve ur problem..i am having same problem .i want to display video which is store on assets folder..reply soon please –  Feb 22 '13 at 16:53
  • @swapniladsure take a look at the answer I posted and accepted. You have to enable file access to the video file. I copied the file to the external storage, including all HTML assets. It's all explained below... – taymless Feb 22 '13 at 23:42

1 Answers1

4

Slartibartfasts helped me solve this. Since it's just a comment, I'll have to post it myself.

Essentially it's a permission problem. Here is the link he posted. The suggested method for copying files with MODE_WORLD_READABLE is deprecated, use the method described in the link below and save the files in the external storage

I had to copy the files to the external storage, and access the video file there. Since the path to the external storage is different within the several versions of android, I copied the all relevant HTML files (including all JS, graphics and video files). See copying files, scroll down for the answer if you have sub folders.

Here are my copying methods:

private void copyAssets(String path)
{
    String[] files = null;

    try
    {
        files = getAssets().list(path);
    } catch (IOException e)
    {
        e.printStackTrace();
    }

    if (files.length == 0)
        copyFile(path);
    else
    {
        File dir = new File(getExternalFilesDir(null), path);

        if (!dir.exists())
            dir.mkdir();

        for (int i = 0; i < files.length; i++)
        {
            copyAssets(path + "/" + files[i]);
        }
    }
}

private void copyFile(String filename)
{
    InputStream in = null;

    File file;
    OutputStream out = null;

    try
    {
        in = getAssets().open(filename);
    } catch (IOException e)
    {
        Log.e(TAG, "ERROR WITH in = getAssets().open: " + filename);
        e.printStackTrace();
    }

    file = new File(getExternalFilesDir(null), filename);

    try
    {
        out = new FileOutputStream(file);
    } catch (FileNotFoundException e)
    {
        Log.e(TAG, "ERROR WITH out = new FileOutputStream(file);");
        e.printStackTrace();
    }

    byte[] data;

    try
    {
        data = new byte[in.available()];

        in.read(data);
        out.write(data);

        in.close();
        out.close();
    } catch (IOException e1)
    {
        e1.printStackTrace();
    }
}

In my onCreate I call

copyAssets("matrix");

with matrix being the folder in my assets thats holding all files and sub folders.

Community
  • 1
  • 1
taymless
  • 779
  • 2
  • 9
  • 24
  • Hey, thanks for this. I just wanted to verify, your assets were in `file:///android_asset/matrix` in this example? – Matt Grande Apr 07 '14 at 21:14
  • 1
    Yeah, that's the path the files were in, before I copied them. After that the path from `getExternalFilesDir(null)` will vary depending on the OS version. – taymless Apr 14 '14 at 14:43
  • I get a fatal execption: java.lang.OutOfMemoryError – Roel Feb 22 '16 at 12:22