ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚑️
https://capacitorjs.com
MIT License
11.76k stars 993 forks source link

bug: Serving local videos occasionally fails on Android #6021

Open brospars opened 1 year ago

brospars commented 1 year ago

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 srcis 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

Ionitron commented 1 year ago

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 πŸ’™

brospars commented 1 year ago

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)
brospars commented 1 year ago

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:

Capture d’écran 2022-10-25 aΜ€ 11 01 33

Edit: sorry I'm adding stuff while I'm debugging WebViewLocalServer.java, when the error occur I am getting WebResourceResponseheaders 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

jcesarmobile commented 1 year ago

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?

brospars commented 1 year ago

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.

jcesarmobile commented 1 year ago

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.

brospars commented 1 year ago

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.

FONAU commented 1 year ago

@brospars Did you manage to solve this issue? I'm getting the same behavior but with local audio files

brospars commented 1 year ago

@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...

kyleabens commented 1 year ago

@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

visuallization commented 1 year ago

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: Screenshot at Mar 15 11-37-13

And this is how it looks like for a failed mp3: Screenshot at Mar 15 11-36-55

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: Screenshot at Mar 15 14-38-22

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?

visuallization commented 1 year ago

Ps. The fetch for u1b_7 and u1b_8 was working in the last screenshot. However u1b_5 and u1b_6 failed.

visuallization commented 1 year ago

I just noticed there are a few similar issues which just got closed but never fixed, so this seems to be a recurring problem.

utajum commented 1 year ago

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?

LuviaGames commented 1 year ago

Just tried with Capacitor 4.7.3 and the issue still persists as described in #5839

Anyone has a workaround?

steinjak commented 1 year ago

@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.

brospars commented 1 year ago

Could you ellaborate on how to do that with local files ?

JaHollTV commented 1 year ago

any update?

goforu commented 11 months ago

any update?

jackcoral89 commented 11 months ago

Anyone had the similar problem with iPadOS 17.0.3 on iPad? As a mentioned in this issue #6790.

Thx

tobium commented 11 months ago

we have this problem on iOS17 too. big blocker

derWebdesigner commented 8 months ago

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.

luis-orantes commented 4 weeks ago

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.

jackcoral89 commented 4 weeks ago

I saw the problem only in iPad and I solved it by rebooting the iPad. For now, the problem is no longer there. πŸ€·β€β™‚οΈ