I'm working on a Cordova app, which has a QR code reader. It works by using WebRTC API. I'm trying to get it to autoplay without require user interaction with the page. But it only works sometimes, most of the time it won't autoplay and shows ugly grey square with a play button.
Here's what was done so far.
The video element is muted, set to autoplay and play inline:
const videoElement = document.createElement('video');
videoElement.style.width = `${width}px`;
videoElement.muted = true;
videoElement.playsInline = true;
videoElement.autoplay = true;
return videoElement;
Once the video started, the play() method is executed after 1 second:
let Element = $('video')[0];
Element.autoplay = true;
setTimeout(() => { Element.play() }, 1000);
The Cordova WebView setting which requires user interaction is set to false.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
// enable Cordova apps to be started in the background
Bundle extras = getIntent().getExtras();
if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
moveTaskToBack(true);
}
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
WebView webView = (WebView) appView.getEngine().getView();
WebSettings webSettings = webView.getSettings();
webSettings.setMediaPlaybackRequiresUserGesture(false); // <-- This is the important part
}
Nevertheless, the camera stream still doesn't play automatically once it's created.
After tons and tons attempts, googling and trying different JS camera libraries, I can simply tell that it's not possible to consistently autoplay videos in a Cordova app.
However, there is still solution. But it's completely different approach.
You have to simulate a screen tap. Luckily, it's very easy.
Go to your platforms/android/app/src/main/java/your package/MainActivity.java.
Add the following imports:
import android.os.SystemClock;
import android.view.InputDevice;
import android.view.Menu;
import android.view.MotionEvent;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
webView = (WebView) appView.getEngine().getView();
WebSettings webSettings = webView.getSettings();
webSettings.setMediaPlaybackRequiresUserGesture(false);
webView.addJavascriptInterface(new JSInterface(), "AndroidApp");
class JSInterface
{
@JavascriptInterface
public void SimulateScreenTap()
{
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run()
{
long delta = 100;
long downTime = SystemClock.uptimeMillis();
float x = webView.getLeft() + (webView.getWidth() / 2);
float y = webView.getTop() + (webView.getHeight() / 2);
MotionEvent tapDownEvent = MotionEvent.obtain(downTime, downTime + delta, MotionEvent.ACTION_DOWN, x, y, 0);
tapDownEvent.setSource(InputDevice.SOURCE_CLASS_POINTER);
MotionEvent tapUpEvent = MotionEvent.obtain(downTime, downTime + delta + 2, MotionEvent.ACTION_UP, x, y, 0);
tapUpEvent.setSource(InputDevice.SOURCE_CLASS_POINTER);
webView.dispatchTouchEvent(tapDownEvent);
webView.dispatchTouchEvent(tapUpEvent);
}
});
}
}
AndroidApp.SimulateScreenTap()
.