Skip to content

Add audioPlayer 1.0.1.1 for OMP 3.5 - #528

Open
edersotto wants to merge 1 commit into
pkp:mainfrom
OJSBR:audioPlayer-1.0.1.1
Open

Add audioPlayer 1.0.1.1 for OMP 3.5#528
edersotto wants to merge 1 commit into
pkp:mainfrom
OJSBR:audioPlayer-1.0.1.1

Conversation

@edersotto

@edersotto edersotto commented Aug 30, 2026

Copy link
Copy Markdown

Adds Audiobook Player 1.0.1.1, a generic plugin for OMP 3.5 that turns the audio files of a monograph into an audiobook.

See it running

Editora UEMG — an audiobook with 26 tracks, on a live OMP 3.5 installation. Press play on any track and drag the progress bar: that drag is the 206 this plugin exists for. No login needed.

Why this one

An audio publication format in OMP is a list of download links. A reader who wants to listen downloads each track, opens it somewhere else, and has no way to resume where they stopped. The gallery lists nothing for audio in OMP.

The plugin adds a play button next to every audio file on the book page and a player bar with seeking inside the track, previous/next track, playback speed, continuous playback and resume from the last position. The original download button is left untouched.

The part that needed care: HTTP Range

Seeking in a media element requires the server to answer 206 Partial Content. PKPFileService::download() sends Accept-Ranges: none and ignores Range (lib/pkp/classes/services/PKPFileService.php:179), so dragging the progress bar re-downloads the file from byte 0 — we opened pkp/pkp-lib#13250 about that separately.

So the plugin serves the audio itself, implementing RFC 9110 §14.1: closed, open and suffix ranges, 206 with a correct Content-Range, and 416 with Content-Range: bytes */<size> for an unsatisfiable range.

It is not a way around access control

It serves the file from inside the CatalogBookHandler::download hook, which fires after the whole OMP access check has already run — OmpPublishedSubmissionAccessPolicy, the format being available, the publication being published, and the file's direct_sales_price. The plugin inherits the check instead of repeating any part of it, and registers no route of its own.

That is asserted, not asserted-in-prose: one test pins the exact set of hooks the plugin registers, another proves it registers no routing of its own. Verified on a server as well — the same MP3 requested with ?audioStream=1 answers 206 when the file is open, and 404 when the file has no direct sales price, when the format is unavailable and when the publication is not published: identical to the ordinary download in all three cases.

Packaging

  • 13 unit tests / 686 assertions in the PKP ApplicationPlugins suite: the range computation against RFC 9110 §14.1 (closed, open, single-byte, suffix, suffix larger than the file, end past the file, and five unsatisfiable forms that must become 416), audio detection, mimetype resolution when the stored type is generic, access control, and locale integrity.
  • 4 Cypress specs, including a live Range request that must answer 206 and an unsatisfiable one that must answer 416.
  • 38 locales, matching the set carried by the generic plugins PKP maintains.
  • No external dependency; nothing loaded from a CDN. GPL-3.0, PHP 8.2+, tested on OMP 3.5.0-5.

One deployment note

A reverse proxy configured with proxy_cache strips Range before it reaches PHP, which makes a correct implementation look broken. The README documents the nginx snippet that forwards it for this route.

Checks run before opening this

  • xmllint --schema ./plugins.xsd ./plugins.xml --noout — validates.
  • Package URL resolves anonymously and the md5 in the entry matches the published tarball (735e2509397d0a4de995aaed08c4238e).
  • The tarball unpacks as a single audioPlayer/ directory.

Notes

Submitted as reviewed, following what other third-party plugins declare here. Happy to adjust anything in the entry if you would like it different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant