Play basmallah when a gapless surah repeats back to ayah 1#3698
Conversation
onPlayerCompleted sought straight to ayahTimings[getCurrentAyah()] when a gapless surah ended and range repeat reset the queue to ayah 1 of the same surah. For ayah 1 that is ayahTimings[1], the start of ayah 1 after the basmallah, so the basmallah was skipped on every loop. Route the seek through getSeekPosition(false), matching every other gapless path (updateAudioPlayPosition, processSkipRequest, playAudio), which returns ayahTimings[0] for ayah 1 when not repeating a single ayah. This also removes the qari dependency. Some gapless reciters (e.g. Saud Ash-Shuraym) have surah files trimmed to end exactly at the ayah=999 marker, so STATE_ENDED fires before the polling path can detect end-of-sura and onPlayerCompleted becomes the only handler. With the seek routed through getSeekPosition(false) the basmallah plays regardless of which handler runs. Fixes quran#3697.
|
Dear Brother @ahmedre Kindly find time and review this, the changes only cover 3 lines of code, I tested this on a xiaomi 15u. |
|
|
New Dependencies Removed Dependencies Upgraded Dependencies |
| // seek to the proper place. so let's seek anyway. route through getSeekPosition | ||
| // so that when we loop back to ayah 1 of a surah, the basmallah (ayahTimings[0]) | ||
| // is played instead of skipping straight to ayah 1 (ayahTimings[1]). | ||
| val seekPosition = getSeekPosition(false) |
There was a problem hiding this comment.
the reason this works is really this part of that method:
return if (ayah == 1 && !isRepeating) {
gaplessSuraData.ayahTimings[0]
} else timebecause you pass repeating as false and ayah is 1, it'll return the 0th ayah timings (hence the basmala).
Fixes #3697.
When a gapless surah is played on range repeat, the basmallah is skipped every time playback loops back to ayah 1. Reproducible with reciters such as Saud Ash-Shuraym; Husary and Minshawi Murattal are unaffected.
The end of a gapless surah is handled by whichever fires first: the position polling in updateAudioPlayPosition, or onPlayerCompleted on ExoPlayer STATE_ENDED. The polling path detects the end when the playback position reaches ayahTimings[999] and seeks to the basmallah for ayah 1. onPlayerCompleted seeks straight to ayahTimings[getCurrentAyah()], which for ayah 1 is ayahTimings[1] — the start of ayah 1 after the basmallah — so it skips it.
Every other gapless path that begins ayah 1 routes through getSeekPosition(false), which returns ayahTimings[0] (the basmallah) when ayah == 1 and we are not repeating a single ayah. onPlayerCompleted is the only gapless same-sura path that bypasses it.
The race explains the qari dependency. Reciters whose surah files are trimmed to end exactly at the 999 marker leave no window for the polling path, so STATE_ENDED always wins and the basmallah is always skipped. Reciters with audio past the 999 marker let polling handle it and are unaffected.
The fix routes the onPlayerCompleted seek through getSeekPosition(false), so the basmallah plays regardless of which handler wins the race or how the reciter's file is encoded.
Tested with Saud Ash-Shuraym (gapless), Surat As-Saffat 1→182, range repeat = infinity: the basmallah now plays on every loop-back. Before the fix it was skipped on every loop.