I am attempting to play an HTML5 video within my WebView app. It works as expected on every device I have tested that is running Android 5.x, but does not work on any device running 4.x, meaning it essentially doesn't work at all.
I have turned on hardware acceleration and I have set a WebChromeClient as the docs say to do, but the video still will not play.
In order to support inline HTML5 video in your application, you need
to have hardware acceleration turned on, and set a WebChromeClient.
AndroidManifest.xml
<application>
android:hardwareAccelerated="true"
...
</application>
MyFragment.java
webView = new WebView(getActivity(), null, this);
webView.setWebChromeClient(new WebChromeClient());
Is there something else I need to do that is not documented in the developer reference?
The problem is WebKit poorly handles redirects for videos. There are videos within webpages from my company's proprietary API. When a video is clicked, the call goes to our API, then redirects to Amazon S3 to get the actual video file. WebKit then tries to "chunk" the video (instead of pre-loading the entire thing) as you would expect. However, S3 has already done that, which causes the playback to be completely broken.
Android 5.x works fine because WebView is based upon Chromium starting in 4.4, which handles the redirect appropriately.
Related
I've got a problem playing Youtube(or any) video in react-native's webview on android device. iOS works just fine.
I've already looked at several SO related questions, but everyone seem to suggest two things:
webview.setWebChromeClient(new WebChromeClient()); which is as far as I am concerned default in react-native's webview since few versions later
enable hardware acceleration android:hardwareAccelerated="true" in AndroidManifest.xml (which I have done)
All I got is a rendered player with controls and everything, but black screen.
I'm trying to get my web-app (hiit-fit-training.com) to run inside of an android web view. It works fines visually but has some issues with the sound. . Inside the web app I use a third party TTS service (responsiveVoice) and a simple beep:
var audio = new Audio( '../assets/_sound/beep.mp3' );
audio.play();
The beep has never played in the web-app and the TTS voice worked occasionally in the baconreader android app web-view. They both work perfectly inside of android Chrome. Neither sound sources work in my web-view though..
Although most likely different, pointing the web-view at youtube, I discovered it can play youtubes audio.
Are there any workarounds or suggestions on how to implement my sound effects?
Figured it out by looking through the console and discovered a security setting:
Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
It can be solved by using the following setting:
myWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
I have an Android KitKat application with an embedded WebView. The page contains an html5 video element. The video loads fine, but play() has no effect until I tap the play button on the screen, and then play() and pause() work fine. I have also tried myWebView.setWebChromeClient(new WebChromeClient());, but this makes no difference. Also, this same page works fine in Chrome browsers on Mac and Linux.
Well, I found the problem. Android 4+ will not allow autoplay of video or programmatic start of play without first having the user tap the play button on the screen. This is so the user will implicitly acknowledge the use of bandwidth by manually activating playback. While I understand why this would be reasonable for a phone user with a cell connection, my application is a television with an Android HDMI stick. This is a very unfortunate restriction. See more here: Autostart html5 video using android 4 browser
EDIT: There is a workaround - while the stock browser cannot achieve this, using an embedded WebView gives you a little more control:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient());
myWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
This solved the problem!
I'm using WebViews in my apps, and many users reported some issues. It appears that most of them seem to happen on 4.1.1, not before.
The configuration:
A Webview, inside a HW accelerated activity.
JS enabled, Plugins enabled, File access enabled, DOM storage enabled.
Custom WebChromeClient and WebViewClient.
Webview has a transparent background (0X00000000) but removing it seems to have no good improvement.
The problem:
Random black outs when showing some URLs: black out meaning, the activity just dies, there is no JAVA exception.
Usually, logs report a SIGSEGV, in glDrawArrays(), but could also be somewhere else (not enough information from users).
A workaround?
Simply disable the HW acceleration on the webview! Yeah, no more black out, that's right... But then (even if we consider this workaround is just so so, as the display performance decreases quite a lot):
A new problem:
Without HW acceleration, HTML5 videos (youtube) are not working: Sound starts, but video doesn't.
A solution could be to catch a playback starting event, to make the video play in a videoView, the same way we can do for fullscreen playback (using onShowCustomView, see Playing HTML5 video on fullscreen in android webview). Nevertheless, I'm currently not able to catch such an event. Please note that I'm not owner of the HTML pages, and the HTML code cannot be changed to append some kind of Javascript code in it.
Questions:
Does anyone has the same kind of crash, using HW acceleration + webview, on many devices? If so, how do you solve that?
About the workaround, deos anyone know how to solve this problem? Would be great to do like on IOS: clicking on the does not try to play the video inline, but instead it just opens the video application.
Thanks for reading!
In my Android app I'd like the user to tap an image once, have a youtube video play automatically and when the video is done the user is immediately returned to the app. What's the best way to do this in Android?
I tried using intents. This works in that the video comes up on what I think is a youtube web page. However playing the video requires another tap. I'd like to avoid this if possible.
I tried the whole MediaPlayer, prepareAsync, setOnPreparedListener and never got it to work. For some reason onPrepared was never called. No exceptions were thrown. I'm using the emulator to test and I'm new to Android so I'm not sure if the behavior will be different on physical devices.
I got this working well on iOS by getting creative with webviews. I'm hoping it's more straightforward on Android. The docs sure make it sound straight forward.
Cheers!
Update: Everything below is still correct, but the official YouTube API for Android is now available.
By far, the easiest way to play a YouTube video on Android is to simply fire an Intent to launch the native Android YouTube app. Of course, this will fail if you are not on a certified Google device, that doesn't have the complement of Google apps. (The Kindle Fire is probably the biggest example of such a device). The problem with this approach is that the user will not automatically wind up back at your app when the video finishes; they have to press the Back button, and at this point you've probably lost them.
As a second option, you can use the MediaPlayer API to play YouTube videos. But there are three caveats with this approach:
1) You need to make a call to YouTube's GData webservice API, passing it the ID of the video. You'll get back a ton of metadata, along with it the RTSP URL that you should pass to MediaPlayer to play back an H.264-encoded stream. This is probably the reason why your attempt to use MediaPlayer failed; you probably weren't using the correct URL to stream.
2) The GData/MediaPlayer approach will only play back low-resolution content (176x144 or similar). This is a deliberate decision on the part of YouTube, to prevent theft of content. Of course, this doesn't provide a very satisfactory experience. There are back-door hacks to get higher resolution streams, but they aren't supported on all releases of Android and using them is a violation of YouTube's terms of service.
3) The RTSP streams can be blocked by some internal networks/firewalls, so this approach may not work for all users.
The third option is to embed a WebView in your application. There two approaches you can take here:
1) You can embed a Flash object and run the standard desktop Flash player for YouTube. You can even use the Javascript API to control the player, and relay events back to the native Android app. This approach works well, but unfortunately Flash is being deprecated on the Android platform, and will not work for Android 4.1 and later.
2) You can embed a <video> tag to play YouTube via HTML5. Support for this varies between various releases of Android. It works well on Android 4.0 and later; earlier releases have somewhat spotty HTML5 <video> support. So, depending upon what releases of Android your application must support, you can take a hybrid approach of embedding HTML5 on Android 4.x or later, and Flash for all earlier versions of Android.
There are several threads here on StackOverflow about using HTML5 to play YouTube video; none of them really describe the entire process you must follow in one place. Here's links to a few of them:
Android - How to play Youtube video in WebView?
How to embed a YouTube clip in a WebView on Android
Play Youtube HTML5 embedded Video in Android WebView
All of this will get dramatically easier in the weeks/months to come; at Google I/O 2012, they presented/demoed a new YouTube API for Android that will support direct embedding of YouTube content in your application, with full support back to Android 2.2 (about 95% of the Android userbase as of this writing). It can't arrive fast enough.