Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to ignore an EOFException? #2024

Closed
laurencedawson opened this issue Nov 1, 2016 · 6 comments
Closed

Possible to ignore an EOFException? #2024

laurencedawson opened this issue Nov 1, 2016 · 6 comments

Comments

@laurencedawson
Copy link

I'm trying to play a few "flakey" MP4 files that are throwing an EOFException.

Is it possible to ignore an EOFException and attempt to play the file regardless of this?

Thanks

@andrewlewis
Copy link
Collaborator

Could you elaborate on what you mean by "flakey"? Are the files truncated?

We may need an example file to investigate further so please share one, and also the output of adb logcat just after you see the error. Thanks.

@laurencedawson
Copy link
Author

When playing the video I'm getting:

11-01 15:58:29.960: E/LoadTask(16638): Unexpected exception loading stream
11-01 15:58:29.960: E/LoadTask(16638): java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.util.ParsableBitArray.readBits(ParsableBitArray.java:162)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.util.CodecSpecificDataUtil.parseAacAudioSpecificConfig(CodecSpecificDataUtil.java:90)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.AtomParsers.parseAudioSampleEntry(AtomParsers.java:879)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.AtomParsers.parseStsd(AtomParsers.java:631)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.AtomParsers.parseTrak(AtomParsers.java:86)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.processMoovAtom(Mp4Extractor.java:325)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.processAtomEnded(Mp4Extractor.java:272)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readAtomPayload(Mp4Extractor.java:263)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:143)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:609)
11-01 15:58:29.960: E/LoadTask(16638):  at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:295)
11-01 15:58:29.960: E/LoadTask(16638):  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
11-01 15:58:29.960: E/LoadTask(16638):  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
11-01 15:58:29.960: E/LoadTask(16638):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
11-01 15:58:29.960: E/LoadTask(16638):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
11-01 15:58:29.960: E/LoadTask(16638):  at java.lang.Thread.run(Thread.java:761)
11-01 15:58:30.100: E/QC-QMI(14565): qmi_client [14565] 2f: failed to locate client data
11-01 15:58:30.103: E/QC-QMI(534): qmuxd: RX on fd=15 returned error=0 errno[2:No such file or directory]
11-01 15:58:30.104: E/QC-QMI(534): QMUX qmux_client_id=2f not found in qmux client list, unable to remove


11-01 15:58:35.425: E/ExoPlayerImplInternal(16638): Source error.
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638): com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: java.io.EOFException
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.read(DefaultHttpDataSource.java:270)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.upstream.DefaultDataSource.read(DefaultDataSource.java:128)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.extractor.DefaultExtractorInput.readFromDataSource(DefaultExtractorInput.java:247)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.extractor.DefaultExtractorInput.readFully(DefaultExtractorInput.java:67)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readAtomHeader(Mp4Extractor.java:195)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:138)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:609)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:295)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at java.lang.Thread.run(Thread.java:761)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638): Caused by: java.io.EOFException
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.skipInternal(DefaultHttpDataSource.java:531)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.read(DefaultHttpDataSource.java:267)
11-01 15:58:35.425: E/ExoPlayerImplInternal(16638):     ... 12 more
11-01 15:58:35.426: E/reddit_sync(16638): Error: com.google.android.exoplayer2.ExoPlaybackException



This is the URL of the content I'm trying to play:

https://cdn-e1.streamable.com/video/mp4-mobile/3jul.mp4?token=1479219343_dc4d0379eaff9e9d24d2e780e41c1fe1a4f3a34b

I've tried loading the URL directly and also caching the file locally and then loading the content both to no avail.


Finally I've run the source through ffmpeg just in case that helps

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'TEST':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.56.100
  Duration: 00:00:29.87, start: 0.023220, bitrate: 1610 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 1538 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

@laurencedawson
Copy link
Author

I've spoken with the video host and they have informed me this was down to a bug in ffmpeg:

"The audio codec was being interpreted as ER Parametric instead of AAC. The underlying issue was an issue in the newest version of ffmpeg."

The link provided above has since been fixed but this link still has the same behaviour:

https://cdn-e1.streamable.com/video/mp4-mobile/3jul.mp4?token=1479228420_9600e7ae0bb49ded546a009b7b869f892636acc7


If the issue is down to the audio encoding being incorrect which in turn is down to ffmpeg (and seems to be troubling other hosting sites too), is it possible to get a more elegant notification of this in ExoPlayer?

For example a callback that the audio stream is invalid with an option to ignore the audio and just play the video? The use case here is for small looping clips that often do not even require audio but having just the video stream play is better than telling the user EOFException.

Thanks

@ojw28
Copy link
Contributor

ojw28 commented Nov 2, 2016

I think having elegant failures for this kind of thing in general would require us to do a huge amount of validation on the stream as we're processing it, which is quite expensive, would add a lot of weight to the codebase, and probably doesn't represent a good trade-off.

If this problem is widespread across multiple providers then we could consider an elegant failure specifically for this case. I somewhat doubt it is though. I'd expect most streaming providers to catch this kind of thing when testing a new ffmpeg version, before adopting it. I'd also expect a streaming provider to fairly quickly re-transcode any bad content they've produced, thereby rectifying the issue. Is that accurate, or do you really think we need to be handling this? If so, please provide concrete numbers / data to justify :).

As an aside, could you link to the corresponding ffmpeg issue? It would be good to know the root cause and the exact versions of ffmpeg in which the issue was present.

@laurencedawson
Copy link
Author

I've maybe seen a few thousand badly encoded MP4s over the last week.

The provider for these MP4s was Gfycat.com and if you want to message me privately (contact@laurencedawson.com) I can make the introduction to their team to discuss the issue.

@ojw28
Copy link
Contributor

ojw28 commented Nov 6, 2016

As per above, unless the issue is affecting multiple providers or is widespread, I think we're happy to assume the problem will be cleared up as that provider re-transcodes any bad content they've produced. Closing for now. A link to the ffmpeg issue would still be appreciated.

@ojw28 ojw28 closed this as completed Nov 6, 2016
@google google locked and limited conversation to collaborators Jun 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants