IosSafeHttpDataSource: use buildUpon().setPosition/setLength (not subrange)
The previous code called dataSpec.subrange(dataSpec.position, length) which *adds* the offset to the existing position rather than setting an absolute bounded slice — that turned every first open() into Range request `bytes=(2*N)-(2*N+chunk-1)`, doubling the offset and still 403'ing for the wrong reason. DataSpec.subrange(offset, length) docs: "position of the new DataSpec will be position + offset". So subrange(0, L) gives a bounded slice at the current position. We want absolute control, so use buildUpon().setPosition(N).setLength(L).build() — explicit, unambiguous. Caught on vc=17 emulator smoke: ExoPlayer logged InvalidResponseCodeException 403 at IosSafeHttpDataSource.kt:58 (the inner.open(bounded) call), meaning the bounded shape was wrong. Player.Listener.onPlayerError DID fire and surface the error in the UI — so that part of the patch works.
This commit is contained in:
parent
3e8109c726
commit
7d2cf5d9bc
1 changed files with 14 additions and 2 deletions
|
|
@ -50,7 +50,13 @@ class IosSafeHttpDataSource(
|
|||
} else {
|
||||
minOf(dataSpec.length, chunkBytes)
|
||||
}
|
||||
val bounded = dataSpec.subrange(dataSpec.position, requestLen)
|
||||
// NOTE: DataSpec.subrange(offset, length) ADDS offset to the existing
|
||||
// position — so subrange(position, length) doubles the position. Use
|
||||
// buildUpon().setLength(...) which preserves position and only bounds
|
||||
// the byte length. This is what makes ExoPlayer's first Range header
|
||||
// come out as `bytes=N-M` (closed, accepted by googlevideo iOS URLs)
|
||||
// instead of `bytes=N-` (open, rejected with 403).
|
||||
val bounded = dataSpec.buildUpon().setLength(requestLen).build()
|
||||
originalSpec = dataSpec
|
||||
totalRead = 0
|
||||
// inner.open() returns the BOUNDED chunk's length. Track it so we
|
||||
|
|
@ -79,7 +85,13 @@ class IosSafeHttpDataSource(
|
|||
}
|
||||
if (remainingOverall <= 0L) return C.RESULT_END_OF_INPUT
|
||||
val nextLen = remainingOverall.coerceAtMost(chunkBytes)
|
||||
chunkRemaining = inner.open(spec.subrange(nextPos, nextLen))
|
||||
// Same as in open() — use buildUpon().setPosition/setLength rather
|
||||
// than subrange() so the absolute position stays meaningful.
|
||||
val nextSpec = spec.buildUpon()
|
||||
.setPosition(nextPos)
|
||||
.setLength(nextLen)
|
||||
.build()
|
||||
chunkRemaining = inner.open(nextSpec)
|
||||
}
|
||||
// Cap the read against what's left in this chunk.
|
||||
val toRead = if (chunkRemaining < 0L) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue