capacitor icon indicating copy to clipboard operation
capacitor copied to clipboard

bug: Serving local videos occasionally fails on Android

Open brospars opened this issue 2 years ago • 24 comments

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

brospars avatar Oct 24 '22 07:10 brospars

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 💙

Ionitron avatar Oct 24 '22 08:10 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)

brospars avatar Oct 24 '22 12:10 brospars

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

brospars avatar Oct 25 '22 09:10 brospars

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?

jcesarmobile avatar Oct 31 '22 14:10 jcesarmobile

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.

brospars avatar Oct 31 '22 14:10 brospars

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.

jcesarmobile avatar Oct 31 '22 14:10 jcesarmobile

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 avatar Nov 03 '22 10:11 brospars

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

FONAU avatar Jan 19 '23 00:01 FONAU

@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 avatar Jan 19 '23 09:01 brospars

@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

kyleabens avatar Jan 27 '23 16:01 kyleabens

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 avatar Mar 15 '23 14:03 visuallization

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

visuallization avatar Mar 15 '23 14:03 visuallization

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

visuallization avatar Mar 15 '23 15:03 visuallization

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?

utajum avatar Mar 16 '23 04:03 utajum

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

Anyone has a workaround?

LuviaGames avatar Apr 20 '23 08:04 LuviaGames

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

steinjak avatar May 11 '23 11:05 steinjak

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

brospars avatar May 11 '23 11:05 brospars

any update?

JaHollTV avatar May 29 '23 14:05 JaHollTV

any update?

goforu avatar Sep 25 '23 09:09 goforu

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

Thx

jackcoral89 avatar Oct 09 '23 14:10 jackcoral89

we have this problem on iOS17 too. big blocker

tobium avatar Oct 11 '23 09:10 tobium

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.

derWebdesigner avatar Dec 17 '23 21:12 derWebdesigner

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.

luis-orantes avatar Aug 10 '24 02:08 luis-orantes

I saw the problem only in iPad and I solved it by rebooting the iPad. For now, the problem is no longer there. 🤷‍♂️

jackcoral89 avatar Aug 10 '24 07:08 jackcoral89