play MP4 video fail, which contains 'elst' box and be encrypted by cenc-aes-ctr
Version
Media3 1.0.0 / ExoPlayer 2.18.5
More version details
Backgound
I use ExoPlayer v2.11.8 to play a mp4 video, which contains 'elst' box and be encrypted by cenc-aes-ctr.
Not Fragment Mp4. Parse encryption codes are copied to Mp4Extractor.java and other files. Tested on ExoPlayer 2.11.8. The lastest version,
AtomParsers.java, codes about 'elst' and 'stbl' are same.
Bug Detail
I debuged the source code, and figured out the reson: AtomParsers.java#L725
copyMetadata |= editedSampleCount != sampleCount;
If track contains elst box, editedSampleCount != sampleCount, leading to will only copy samples between startIndex ~ endIndex.
copyMetadata |= editedSampleCount != sampleCount;
// Calculate edited sample timestamps and update the corresponding metadata arrays.
long[] editedOffsets = copyMetadata ? new long[editedSampleCount] : offsets;
int[] editedSizes = copyMetadata ? new int[editedSampleCount] : sizes;
int editedMaximumSize = copyMetadata ? 0 : maximumSize;
int[] editedFlags = copyMetadata ? new int[editedSampleCount] : flags;
long[] editedTimestamps = new long[editedSampleCount];
long pts = 0;
int sampleIndex = 0;
......
return new TrackSampleTable(
track,
editedOffsets,
editedSizes,
editedMaximumSize,
editedTimestamps,
editedFlags,
editedDurationUs);
And then the sampleCount > out.sampleCount check will fail :
int sampleCount = saiz.readUnsignedIntToInt();
if (sampleCount > out.sampleCount) {
throw ParserException.createForMalformedContainer(
"Saiz sample count "
+ sampleCount
+ " is greater than fragment sample count"
+ out.sampleCount,
/* cause= */ null);
}
My solution
If track is encrypted, then only scale the time, and use all samples to build TrackSampleTable, and return.
- if (track.editListDurations.length == 1 && track.editListDurations[0] == 0) {
+ if ( (track.editListDurations.length == 1 && track.editListDurations[0] == 0 )
+ || track.getSampleDescriptionEncryptionBox(0) != null // **add this line, to copy all samples**
+ ) {
// The current version of the spec leaves handling of an edit with zero segment_duration in
// unfragmented files open to interpretation. We handle this as a special case and include all
// samples in the edit.
long editStartTime = checkNotNull(track.editListMediaTimes)[0];
for (int i = 0; i < timestamps.length; i++) {
timestamps[i] =
Util.scaleLargeTimestamp(
timestamps[i] - editStartTime, C.MICROS_PER_SECOND, track.timescale);
}
durationUs =
Util.scaleLargeTimestamp(duration - editStartTime, C.MICROS_PER_SECOND, track.timescale);
return new TrackSampleTable(
track, offsets, sizes, maximumSize, timestamps, flags, durationUs);
}
I don't know if it is a good modification, since I know little about mp4 extractor things.
Do EXO have a better solution? Thanks.
Devices that reproduce the issue
All devices
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
play MP4 video , which contains 'elst' box and be encrypted by cenc-aes-ctr
Expected result
Can play OK.
Actual result
Play fails.
Media
I cannot provide the commercial video, sorry about that.
I'm still trying to make a video file.
Bug Report
- [X] You will email the zip file produced by
adb bugreportto [email protected] after filing this issue.
@rohitjoins @tianyif Any update on this? Thanks.
@rohitjoins @tianyif Any update?
@rohitjoins @tianyif Any?
Hi @I-m-SuperMan,
I haven't had the chance to look closely at the issue. It would be nice if you could share media to reproduce this issue. If you're unable to share the test content publicly, please send them to [email protected] with the subject
Issue #1303. Please also update this issue to indicate you've done this.
Hey @I-m-SuperMan. We need more information to resolve this issue but there hasn't been an update in 14 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!