capacitor
capacitor copied to clipboard
bug: Serving local videos occasionally fails on Android
Bug Report
Capacitor Version
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 4.4.0
@capacitor/core: 4.4.0
@capacitor/android: 4.4.0
@capacitor/ios: 4.4.0
Installed Dependencies:
@capacitor/cli: 3.5.1
@capacitor/core: 3.5.1
@capacitor/android: 3.5.1
@capacitor/ios: 3.5.1
[success] iOS looking great! 👌
[success] Android looking great! 👌
Platform(s)
Android
Current Behavior
On iOS : the video plays without a problem. On Android : the video plays but we get a network error from time to time that stop the video and "crashes" the player (we have to change page and come back to replay it again). Sometimes the video won't play at all.
GET http://localhost/_capacitor_file_/data/user/0/com.myapp/files/videoXYZ.mp4 net::ERR_FAILED
Expected Behavior
The video play thoroughly on android.
Code Reproduction
We use a html5 video player in an Ionic/Angular app to play local video like such:
<video *ngIf="src" #video disablePictureInPicture playsinline preload="auto" [src]="src"></video>
Where src
is set using an input : Capacitor.convertFileSrc('video/videoXYZ.mp4')
@Component({
selector: 'video-player',
templateUrl: './video-player.component.html',
styleUrls: ['./video-player.component.scss'],
})
export class VideoPlayerComponent implements OnInit, AfterViewInit {
@ViewChild('video', {static: false}) videoRef: ElementRef;
@Input() src: string;
// ...
}
Other Technical Details
We can have multiple videos on the same page. And the bug seems to happen more often when we seek through multiple videos quickly.
npm --version
output: 8.7.0
node --version
output: v14.19.0
This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.
Please see the Contributing Guide for how to create a Code Reproduction.
Thanks! Ionitron 💙
Here is an example : https://github.com/brospars/bugvid
Exact same bug on android emulator and real device. Sometimes videos load properly sometimes I get GET http://localhost/_capacitor_file_/data/user/0/com.myapp/files/videoXYZ.mp4 net::ERR_FAILED
Edit: Sometimes I don't get the net::ERR_FAILED
but the video play/pause instalty and I get this error in logcat:
2022-10-24 14:50:53.877 31853-31891/io.ionic.starter E/chromium: [ERROR:android_image_reader_utils.cc(19)] Failed to create android native fence sync object.
2022-10-24 14:50:53.877 31853-31891/io.ionic.starter E/EGL_emulation: tid 31891: eglCreateSyncKHR(2095): error 0x3004 (EGL_BAD_ATTRIBUTE)
Just for the sake of it I upgraded to the latest versions of everything on the v4
branch: https://github.com/brospars/bugvid/tree/v4
The bug is still present on Android emulator (Pixel 4 API 29) and real devices, it's not happening everytime but after closing/reopening the app multiple time (once the download has ended) I get:
Edit: sorry I'm adding stuff while I'm debugging WebViewLocalServer.java
, when the error occur I am getting WebResourceResponse
headers that seem wrong
// Range seems wrong : 1055736-1055735 => video bug
{Accept-Ranges=bytes, Cache-Control=no-cache, Content-Range=bytes 1055736-1055735/1055736}
// Range is correct : 0-1589247 => video works
{Accept-Ranges=bytes, Cache-Control=no-cache, Content-Range=bytes 0-1589247/1589248}
This makes me think it could be coming from this part of the code : https://github.com/ionic-team/capacitor/blob/main/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java#L202-L232
Thanks for the sample app, but I can't reproduce. Can you provide more information? What's the WebView version of the devices/emulators where you have tested? Where you say "after closing/reopening the app multiple time", do you mean killing it and reopening or just putting it into the background?
Hi, Thanks for taking your time testing it. I use Android Pixel 4 emulator with API 29 and a real device a Nokia 6.1 on Android 10.
I mean shutting it off and on using Android Studio. And sometimes the video won't start and you can see network errors in crime dev tools.
I've also added breakpoints when the range is wrong (like shown in my previous comment) but with no luck the response go through and end up in chrome WebView native code that I can't debug.
I'm asking for the WebView version, not the Android version, it's the version you can see in chrome://inspect/#devices between brackets, i.e. for me it's 91.0.4472.114
WebView in io.ionic.starter (91.0.4472.114).
The "shutting it off and on using Android Studio" is even more confusing.
Sorry I misread your comment. I have the same version for the emulator 91.0.4472.114
and 106.0.5249.126
for my device.
@brospars Did you manage to solve this issue? I'm getting the same behavior but with local audio files
@FONAU I ended up not using the html5 video
element for Android but instead a native video player plugin : https://github.com/jepiqueau/capacitor-video-player
It's not ideal (way less customization, mandatory fullscreen, etc) but at least it works everytime...
@brospars do mind sharing your code? Anytime I pass the url which is the local path that starts with 'content://' on Android it fails to play
We do experience a similar issue on Android with mp3 files where they would sometimes load and sometimes won't.
This is how the network tab looks like for a successful mp3:
And this is how it looks like for a failed mp3:
Also when logging the android logs with logcat and adding some comments in capacitor's WebViewLocalServer.java
in shouldInterceptRequest
and handleLocalRequest
I see the following:
So you can see the files which failed to be fetched, are fetched twice. At first fetch the byte range seems to look fine: 0-9003 out of 9004 total
. But the second fetch for the same resource seems to be broken: 9004 - 9003
. The end byte is lower than the start byte, which can't be right.
Has anyone got an idea what is going on here?
Ps. The fetch for u1b_7
and u1b_8
was working in the last screenshot. However u1b_5
and u1b_6
failed.
I just noticed there are a few similar issues which just got closed but never fixed, so this seems to be a recurring problem.
- https://github.com/ionic-team/capacitor/issues/5839
- https://github.com/ionic-team/capacitor/issues/2978
Howdy,
I want to report that this problem has been happening for over a year. The issue initially started with capacitor 3. We are now forced to upgrade to capacitor 4 from capacitor 2 due to recent changes in the minimum target SDK by Google.
I had hopes that by upgrading to capacitor 4 (from scratch), this issue would be resolved, but it's still present when serving mp3 files.
Any hopes to get a bump on PR https://github.com/ionic-team/capacitor/pull/5956?
Just tried with Capacitor 4.7.3 and the issue still persists as described in #5839
Anyone has a workaround?
@LuviaGames ,
We use the following workaround, as described in PR #5956
For the next person facing this: We circumvent the issue by downloading the media file without streaming (using Angular HTTP service, fetch() would probably also work) and map it to a resource URL (URL.createObjectURL(blob)) that we point our media elements to.
Could you ellaborate on how to do that with local files ?
any update?
any update?
Anyone had the similar problem with iPadOS 17.0.3 on iPad? As a mentioned in this issue #6790.
Thx
we have this problem on iOS17 too. big blocker
Quick hint that solved it for me after hours and hours of investigation: preload="none"
Or to be more exact I am using preload="{{ isAndroid ? 'none' : 'auto' }}"
because videos are randomly not playing if they are preloaded on Android but on iOS there is a short ugly flickering without the preloading so I am only setting the value for Android. I hope this helps although I can't explain it. I just saw buffering issues in Android Studio and the app trying to load the file but nothing happened.
This is to confirm that newer version of capacitor/android still have the issue. I am using Capacitor/Android 6.1.0.
Could somebody tell if this happens only in Android? or if the issue is also present in iOS
Also that the fix given by @derWebdesigner fix the issue
preload="none"
but a fix should be created.
I saw the problem only in iPad and I solved it by rebooting the iPad. For now, the problem is no longer there. 🤷♂️