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.
Solution. After searching a lot, I found this thread. I did something similar: Just extend WebView and override onWindowVisibilityChanged . This way, the audio continues to play if the screen is locked or another app is opened.
Alternatives to WebView If you want to send users to a mobile site, build a progressive web app (PWA). If you want to display third-party web content, send an intent to installed web browsers. If you want to avoid leaving your app to open the browser, or if you want to customize the browser's UI, use Custom Tabs.
Beginning October 5, 2021, Facebook Login will no longer support using Android embedded browsers (WebViews) for logging in users.
I read about how to increase performance of WebView by implementing Caching web resources like JS, CSS and image files. You can also static resources in your native application, and by intercepting the Resource requests you can override the default behaviour of WebView.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With