Skip to content

Releases: ampache/ampache

7.10.5

Choose a tag to compare

@lachlan-00 lachlan-00 released this 13 Oct 23:15
fdfa649

7.10.5

php8.5
dd3884fc10277ff7f04e0ea8c5da2ccd ./ampache-7.10.5_all_php8.5.zip
fad417b600388153c70ec9c631efb8d6 ./ampache-7.10.5_all_php8.5_squashed.zip
1120754790678166b107707238077045 ./ampache-7.10.5_all_php8.5_client.zip

php8.4
979e2b65608adb26642d4013827d9651 ./ampache-7.10.5_all_php8.4.zip
bbc359d7e34120304ea7e8f835954158 ./ampache-7.10.5_all_php8.4_squashed.zip
0911cf0a6587b689aa09046ee4241801 ./ampache-7.10.5_all_php8.4_client.zip

php8.3
6b2b1263f79f52c584995956f6a230cb ./ampache-7.10.5_all_php8.3.zip
38daed2ebbbd8b8709275e3661b51176 ./ampache-7.10.5_all_php8.3_squashed.zip
c2aa928d20d2a4525958a7573e97d8ae ./ampache-7.10.5_all_php8.3_client.zip

php8.2
65c782cdd11401a4b77ce4bd05d899db ./ampache-7.10.5_all_php8.2.zip
50341f9460b4e2f32da11690bb3a7e61 ./ampache-7.10.5_all_php8.2_squashed.zip
d6c0b497ac63ea18efbf7e58895f2617 ./ampache-7.10.5_all_php8.2_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
b1bafb0b603a3075254060824eade023 ./ampache-7.10.5_public.zip
905a3589a8e59cad04474e3de08e3676 ./ampache-7.10.5_squashed.zip
0d6d92816cf5265a8ee52d0c6f287ef1 ./ampache-7.10.5_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

Ampache 7.10.5

Fixed (7.10.5)

  • An outdated database bounced login.php to update.php, which requires a session and bounced back to login.php, looping forever instead of showing the login form (#4547)
  • Downgrading from Ampache8 left the rightbar_always_show preference behind; it's now removed like the other Ampache8-only preferences

7.10.4

Choose a tag to compare

@lachlan-00 lachlan-00 released this 12 Oct 03:54
6566172

Replaced

NOTE Replaced with 7.10.5

7.10.4

php8.5
6c2a2fdf3525487850d324522ce53a64 ./ampache-7.10.4_all_php8.5.zip
d5c7f0f8884dec6cd308ec82d816085e ./ampache-7.10.4_all_php8.5_squashed.zip
6cbb7934f4a88bbf9c3ef2a5f9fee1eb ./ampache-7.10.4_all_php8.5_client.zip

php8.4
ad6bb5a3bf9cb1b7319549fa12e17c1e ./ampache-7.10.4_all_php8.4.zip
5cf67cbf0e12a8864f79ba8956df2d13 ./ampache-7.10.4_all_php8.4_squashed.zip
eb99b297294b050a9c8c2f607bc52564 ./ampache-7.10.4_all_php8.4_client.zip

php8.3
4deb165963068349d000e227e9ffb662 ./ampache-7.10.4_all_php8.3.zip
90755d202e733b7197ceecc15be1bef4 ./ampache-7.10.4_all_php8.3_squashed.zip
580e3885c238a4e9c6c5589fca9c7564 ./ampache-7.10.4_all_php8.3_client.zip

php8.2
572b0084a0c1c46896ad92fbafba7893 ./ampache-7.10.4_all_php8.2.zip
c906ce94d17c9d19b97400f419ca0277 ./ampache-7.10.4_all_php8.2_squashed.zip
786667a6218413abb84e384e9d33f54c ./ampache-7.10.4_all_php8.2_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
45465dfdebbbe810d2e3e4bbd15494e4 ./ampache-7.10.4_public.zip
037cff8a1042880ffe0f4641638ec038 ./ampache-7.10.4_squashed.zip
53b46587c07c8cebb5c4b971ba0db5cc ./ampache-7.10.4_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

Ampache 7.10.4

Added (7.10.4)

  • Config version 88
    • Added allow_lost_password (default false) to gate the Lost Password feature

Changed (7.10.4)

  • Updated Composer and NPM packages

Fixed (7.10.4)

  • Subsonic search3 rejected a missing or empty query (regression since 7.10.0), breaking clients (e.g. Substreamer) that load the full library through an empty search; restored the same "browse everything" behaviour search2 already has
  • A local catalog file move/rename resolved the wrong catalog id for songs, videos and podcast episodes, using a lookup meant for a different case (#4527)
  • http authentication no longer accepts a client-supplied HTTP_REMOTE_USER header as an identity; only the server-set REMOTE_USER is trusted
  • Header-authenticated session ids were md5(username), guessable from a username; now derived from the credential
  • update.php skipped auth based on a request parameter, letting anyone reach the update dispatcher
  • batch.php skipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filter
  • lost_password is now disabled by default, and blocked for Content Manager, Manager and Admin accounts
  • Password comparisons in the API handshake (API3-6), token login, remember-me login, and apikey/stream-token/reset-token lookups are now constant-time, closing a timing side-channel on login
  • Subsonic updateshare on a share you don't own reported success without changing anything, instead of the access-denied error it now gives
  • A stale, expired or out-of-range art picker selection (image.php?type=session) crashed instead of serving an empty response

API 6.9.2 Build 6

Changed (692006)

  • lost_password (ALL)
    • Disabled by default; requires allow_lost_password to be enabled
    • Also blocked for Content Manager and Manager accounts

Fixed (692006)

  • Session id after header auth was md5(username); now derived from the credential
  • handshake (ALL)
    • Password comparison is now constant-time, closing a timing side-channel

8.2.2

Choose a tag to compare

@lachlan-00 lachlan-00 released this 02 Oct 22:10
a5bacfe

8.2.2

php8.5
5e741be96fbbc8193fe347f209baa344 ./ampache-8.2.2_php8.5.zip
5e741be96fbbc8193fe347f209baa344 ./ampache-8.2.2_all_php8.5.zip
175bf0892e2784db788a95953e30ef4e ./ampache-8.2.2_all_php8.5_squashed.zip
7122e7fc961f6850ebb86cf50231a117 ./ampache-8.2.2_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
0b6f41a7b4d135fdf786e42a0f563b4e ./ampache-8.2.2.zip
0b6f41a7b4d135fdf786e42a0f563b4e ./ampache-8.2.2_public.zip
d8d0f3d1cadc63e7e88805441b4cb25f ./ampache-8.2.2_squashed.zip
091576959bdb294c9010369275a57925 ./ampache-8.2.2_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.2.2.zip is a copy of ampache-8.2.2_public.zip and ampache-8.2.2_php8.5.zip is a copy of ampache-8.2.2_all_php8.5.zip.

The shorter names become the default for the public structure in Ampache9; the _public and _all names will be kept for the rest of the 8.x series.

Ampache 8.2.2

Releasing again quickly to make sure the experience on 8.2.x is as solid as possible. This also means you get access to some of the bigger features I was planning on keeping a bit longer but they do look great!

Added (8.2.2)

  • Preferences
    • One page for your own preferences, the server's, and an admin editing another account
    • The shipped default and the server value beside each preference, with one-click restore
    • Inline help on ~130 preferences, with links to the documentation
    • A filter box, plus filters for "differs from default" and "unsaved"
    • A section jump list, and a catch-all section for preferences that belong to none
    • Warnings when another preference, or a config setting, silently cancels the one being set
    • A confirmation listing every change before it is written
    • Export all preferences, a JSON download of the whole configuration
    • Plugins can explain their own preferences through PluginPreferenceHelpInterface
    • The Update button stays inert until something on the page actually changed
  • Database 821002
    • Corrected the integer/string type on eight preferences that are switches
    • Removed sidebar_order_video, which never ordered anything: the sidebar has no video section
    • Removed allow_personal_info_agent, unread since 4.3.0, where the agent column became admin-only
    • Converted preference.category from a plain varchar to an enum of its seven real values
    • Shrank preference.subcategory from varchar(128) to varchar(32) and pinned it to utf8mb3

Changed (8.2.2)

  • Browse lists
    • Browse lists are laid out as two-line rows on a narrow screen instead of a table that scrolls sideways: songs, albums, artists, playlists, smart playlists, playlist contents, labels, radio stations, videos, podcasts and their episodes
    • The Songs, Top Tracks and Similar Songs panels of an artist page follow the same layout
    • A chevron on each row folds out the remaining columns, one row open at a time, with the cover art shown large and every action named
    • The column headers become a strip of sort links; a header you cannot sort by is dropped, and a row left with none of them disappears
    • Play, add to playlist and the row actions no longer wait for a hover
  • Preferences
    • The confirmation names which changes the per-row Apply to All writes into every existing account
    • Access levels are read from Preference::DEFAULTS rather than a second list that had fallen out of step with it
    • Resetting levels to default now also covers the 29 preferences the old list left out
    • admin/users.php?action=show_preferences renders the shared preferences screen
    • The default preset is read from Preference::DEFAULTS instead of a copy that had drifted on eleven values and was missing thirty-five preferences
    • Whether a setting is a switch is read from its declared type, so the debug page no longer relies on a list that had fallen behind

Removed (8.2.2)

  • preferences.php?action=user, which required admin but only ever showed your own preferences
  • Ui::createPreferenceInput() and Ui::showPreferenceBox(), replaced by a type-driven renderer
  • The Preference::DEFAULT_LEVELS constant, replaced by Preference::defaultLevels()

Fixed (8.2.2)

  • Dragging to reorder a playlist or a song list now works on a touch screen
  • Preferences
    • The account tab could never be saved, every submit answering 403
    • api_force_version did not offer version 8, so a resubmit silently reset it to 0
    • localplay_level and upload_access_level did not offer the Guest level
    • The Last.fm and Libre.fm authorisation callback accepted a forged link
    • Last.fm and Libre.fm session keys were shown in plain text and carried into exports
    • Last.fm and Libre.fm could never be authorised a first time: the link was hidden, and the callback refused
  • login.php redirected straight back to update.php with a pending database update, looping forever (ERR_TOO_MANY_REDIRECTS) instead of showing the login form

8.2.1

Choose a tag to compare

@lachlan-00 lachlan-00 released this 02 Oct 07:01
11f2bb5

Replaced

NOTE Replaced with 8.2.2

8.2.1

php8.5
0ab327e4796a35cb0932287c60b4c075 ./ampache-8.2.1_php8.5.zip
0ab327e4796a35cb0932287c60b4c075 ./ampache-8.2.1_all_php8.5.zip
d3b097af24301eedb974da0d3fc26a0c ./ampache-8.2.1_all_php8.5_squashed.zip
6f085ce7a751133096e25180b45df23f ./ampache-8.2.1_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
317dadc7043ef8285b2a3b684aa6abc1 ./ampache-8.2.1.zip
317dadc7043ef8285b2a3b684aa6abc1 ./ampache-8.2.1_public.zip
c2f3317083bf2bee554a43f7aef7fd97 ./ampache-8.2.1_squashed.zip
0fbedce32ec3d3bfff0e8d33cbae1f2a ./ampache-8.2.1_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.2.1.zip is a copy of ampache-8.2.1_public.zip and ampache-8.2.1_php8.5.zip is a copy of ampache-8.2.1_all_php8.5.zip.

Ampache 8.2.1

Fixed (8.2.1)

  • Database 810030
    • Restored the transcoding type on encode_target, encode_video_target, encode_player_webplayer_target and encode_player_api_target, fixing the missing encode-format dropdown on those preferences that Migration810028 caused in 8.2.0

Ampache 8.2.0

Jellyfin API Third-party Jellyfin clients can now browse and stream Ampache libraries through a new optional Jellyfin-compatible API. https://ampache.org/docs/configuration/jellyfin/

Added (8.2.0)

  • Database 810029
    • Added an index on recommendation_item.recommendation for the similar artists/songs lookup
    • Added musicbrainz_server and musicbrainz_throttle preferences to support custom MusicBrainz mirrors and configurable request throttling
    • Added jellyfin_backend_enable preference
    • Added jellyfin_quick_connect table and quickconnect_enable preference for QuickConnect pairing
    • Corrected the bool type on home_recently_played_all and show_wrapped
    • Corrected preference.name's collation to match user_preference.name, fixing an "Illegal mix of collations" error in admin:updateDatabase
    • Added embed_player preference, offering a player to sites that link here
    • Pinned object_type to utf8mb3 on folder_map, collection, collection_map, playlist_folder_map, object_count_archive and object_count_summary, matching every other object_type column
    • Removed the dead tvshow/tvshow_season values from the object_type enum on cache_object_count, cache_object_count_run, image, object_count, rating, tag_map, user_activity and user_flag
    • Converted object_type from a plain varchar to an enum of its real, verified values on album_map, artist_map, catalog_map, folder_map, collection_map, bookmark, tmp_playlist, tmp_playlist_data, recommendation, user_shout and collection
    • Widened bookmark/tmp_playlist's object_type enum to the same playable-media list as playlist_data/tmp_playlist_data, so a new playable type needs no further migration
    • Converted playlist_folder_map.object_type, preference.type and stream_playlist.type from a plain varchar to an enum of their real, verified values
  • Jellyfin
    • Added Jellyfin-compatible API support for Finamp, Symfonium and Gelly
    • Disabled by default. Enable with jellyfin_backend_enable
    • Supports audio streaming, direct play and transcoding
    • Supports login, browsing, artwork, streaming, lyrics, recommendations, favourites, ratings, playback resume/reporting and playlist management
    • Added QuickConnect device pairing with a dedicated approval page. Disabled by default via quickconnect_enable
  • Rightbar
    • Added Shuffle button for queue randomisation
    • Added Play Next and Play Last buttons to enqueue the current queue in web player and Localplay sessions
    • Added drag-and-drop reordering of the queue
  • Playlist Folders
    • Added a web UI to browse, create, rename, move and delete playlist folders, and to file playlists/smart playlists into them
  • The Personal Favorites home plugin now shows ratings and favourite status for playlists and smart playlists
  • Smart playlists and random searches now show generated mosaic cover art on their own page, like playlists already do
  • Config version 100
    • Added stream_proxy option (default true) to control live stream proxying

Changed (8.2.0)

  • Updated Seafile SDK to dev-master
  • Updated Composer and NPM dependencies
  • wanted_types now includes single and ep by default
  • Rightbar action buttons now use a fixed four-column grid
  • Grid action icons now display in the bottom-right corner
  • Artist Songs now loads via AJAX within the artist page. Legacy URLs redirect to the new tab
  • A password change or API key rotation now ends the sessions that credential had opened
  • bin/cli run:updateDb now compares every table and column against resources/sql/ampache.sql and only reports/fixes the ones that don't match, instead of unconditionally rewriting every table and column to one global charset; id/token/enum columns the schema pins to utf8mb3 are left alone

Fixed (8.2.0)

  • Subsonic search3 rejected an empty query (regression since 7.10.0/8.1.0); restored search2's "browse everything" behaviour
  • Last.fm and Libre.fm session keys were shown in plain text
  • Notifications displayed their own quotes, and were inserted as markup rather than as text
  • A site_title holding a closing script tag broke the page scripts
  • A stored theme_name reached get_theme() as a path segment without being confined to the themes directory
  • A preference written in one request was still read back stale in that same request
  • The slideshow armed itself without the Flickr plugin
  • Subsonic getIndexes returned an empty index on any library whose folder_map has not been rebuilt
  • Garbage collection incorrectly removed parent-only folders
  • Fixed missing Subsonic sub-folder listings
  • Fixed MariaDB error 1020 when using innodb_snapshot_isolation
  • Improved support for databases with autocommit disabled
  • Fixed false PDO error detection when error code was 00000
  • Fixed raw LICENSE tag handling for Vorbis metadata
  • Sanitised licence external links and blocked non-HTTP(S) URLs
  • Fixed folder handling in the Subsonic API
  • Fixed missing song lyrics
  • Database exceptions now include query and driver error details
  • Fixed admin:updateDatabase failures during partial migrations
  • Fixed now-playing polling continuing after page navigation
  • Restored "Save as Smart Playlist" for existing smart playlists
  • Fixed downloads failing when no files were available
  • Fixed proof-of-work loops after endpoint errors
  • Fixed private playlist share links rejecting visitors
  • Fixed withdrawn albums appearing in artist, API and UPnP listings
  • Fixed ineffective Enabled search rule on album disks
  • Added withdrawn status indicators to disk listings
  • Fixed managers being unable to view withdrawn tracks on artist song pages
  • Fixed missing generated artwork when custom_blankalbum is enabled
  • RSS artwork for a song/podcast episode with no cover now falls back to its album/podcast artwork instead of the placeholder
  • RSS artwork for an album with no cover of its own now falls back to the album artist's artwork instead of showing the placeholder
  • http authentication no longer accepts a client-supplied HTTP_REMOTE_USER header as an identity; only the server-set REMOTE_USER is trusted
  • Fixed withdrawn releases appearing in Recent, Popular, Trending and statistics views
  • Fixed withdrawn releases appearing in recently played views and feeds
  • Added visual highlighting for withdrawn items
  • Fixed run:updateCatalog -ca reimporting unchanged files
  • Fixed deleted_songs API always returning an empty result
  • Subsonic
    • Optimised genre lookups in getMusicDirectory
    • Optimised video and podcast tag loading
    • Unexpected API errors now return proper error responses
    • Reduced memory usage when browsing large folders
  • Fixed catalog scans leaving progress streams open after errors
  • Fixed DAAP requests returning empty responses on unexpected errors
  • Fixed sidebar section toggle inconsistencies
  • Fixed wanted_missing_albums errors when MusicBrainz data omitted secondary-types
  • Fixed live stream interruptions caused by PHP execution time limits
  • Fixed the ListenBrainz plugin double-prefixing a URL that already had a scheme
  • A MusicBrainz mirror given as a bare host is now assumed http instead of rejected
  • Restored the artist "Songs" tab's full-page view, which had regressed to a redirect
  • Header-authenticated session ids were md5(username), guessable from a username; now derived from the credential
  • update.php skipped auth based on a request parameter, letting anyone reach the update dispatcher
  • batch.php skipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filter
  • lost_password is now disabled by default, and blocked for Content Manager, Manager and Admin accounts
  • cleanup:sortSongs used the whole server's song count (not the catalog's) and the chunk index as a row offset, silently skipping songs on every catalog-wide run
  • Writing tags to a FLAC/Vorbis file could crash and leave the comment block partially written when adding a new per-user rating tag
  • print:tags crashed on any file not yet scanned into a catalog, including its own documented usage example
  • run:updateCatalogFile -r|--rename could never succeed; it looked up the destination catalog from a song row that the rename itself was meant to create
  • run:convertFilenames walked every local catalog instead of the one named on the command line
  • export:playlist never created its output directory and kep...
Read more

8.2.0

Choose a tag to compare

@lachlan-00 lachlan-00 released this 02 Oct 05:22
da56084

Replaced

NOTE Replaced with 8.2.2

8.2.0

php8.5
86cb524ca96f9c5e9e0a9af8523edf34 ./ampache-8.2.0_php8.5.zip
86cb524ca96f9c5e9e0a9af8523edf34 ./ampache-8.2.0_all_php8.5.zip
017afb32ce4a4508ae816cf39217a260 ./ampache-8.2.0_all_php8.5_squashed.zip
540856bac0f8a0d3160ffcecaca29372 ./ampache-8.2.0_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
39a0f4371aeabf5473c667f3f110bfce ./ampache-8.2.0.zip
39a0f4371aeabf5473c667f3f110bfce ./ampache-8.2.0_public.zip
066e72fa7a5b922331d08eb3edf9870a ./ampache-8.2.0_squashed.zip
d0487b861d7f4374d205bafda1275c0b ./ampache-8.2.0_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.2.0.zip is a copy of ampache-8.2.0_public.zip and ampache-8.2.0_php8.5.zip is a copy of ampache-8.2.0_all_php8.5.zip.

The shorter names become the default for the public structure in Ampache9; the _public and _all names will be kept for the rest of the 8.x series.

Ampache 8.2.0

Jellyfin API Third-party Jellyfin clients can now browse and stream Ampache libraries through a new optional Jellyfin-compatible API. https://ampache.org/docs/configuration/jellyfin/

Added (8.2.0)

  • Database 810029
    • Added an index on recommendation_item.recommendation for the similar artists/songs lookup
    • Added musicbrainz_server and musicbrainz_throttle preferences to support custom MusicBrainz mirrors and configurable request throttling
    • Added jellyfin_backend_enable preference
    • Added jellyfin_quick_connect table and quickconnect_enable preference for QuickConnect pairing
    • Corrected the bool type on home_recently_played_all and show_wrapped
    • Corrected preference.name's collation to match user_preference.name, fixing an "Illegal mix of collations" error in admin:updateDatabase
    • Added embed_player preference, offering a player to sites that link here
    • Pinned object_type to utf8mb3 on folder_map, collection, collection_map, playlist_folder_map, object_count_archive and object_count_summary, matching every other object_type column
    • Removed the dead tvshow/tvshow_season values from the object_type enum on cache_object_count, cache_object_count_run, image, object_count, rating, tag_map, user_activity and user_flag
    • Converted object_type from a plain varchar to an enum of its real, verified values on album_map, artist_map, catalog_map, folder_map, collection_map, bookmark, tmp_playlist, tmp_playlist_data, recommendation, user_shout and collection
    • Widened bookmark/tmp_playlist's object_type enum to the same playable-media list as playlist_data/tmp_playlist_data, so a new playable type needs no further migration
    • Converted playlist_folder_map.object_type, preference.type and stream_playlist.type from a plain varchar to an enum of their real, verified values
  • Jellyfin
    • Added Jellyfin-compatible API support for Finamp, Symfonium and Gelly
    • Disabled by default. Enable with jellyfin_backend_enable
    • Supports audio streaming, direct play and transcoding
    • Supports login, browsing, artwork, streaming, lyrics, recommendations, favourites, ratings, playback resume/reporting and playlist management
    • Added QuickConnect device pairing with a dedicated approval page. Disabled by default via quickconnect_enable
  • Rightbar
    • Added Shuffle button for queue randomisation
    • Added Play Next and Play Last buttons to enqueue the current queue in web player and Localplay sessions
    • Added drag-and-drop reordering of the queue
  • Playlist Folders
    • Added a web UI to browse, create, rename, move and delete playlist folders, and to file playlists/smart playlists into them
  • The Personal Favorites home plugin now shows ratings and favourite status for playlists and smart playlists
  • Smart playlists and random searches now show generated mosaic cover art on their own page, like playlists already do
  • Config version 100
    • Added stream_proxy option (default true) to control live stream proxying

Changed (8.2.0)

  • Updated Seafile SDK to dev-master
  • Updated Composer and NPM dependencies
  • wanted_types now includes single and ep by default
  • Rightbar action buttons now use a fixed four-column grid
  • Grid action icons now display in the bottom-right corner
  • Artist Songs now loads via AJAX within the artist page. Legacy URLs redirect to the new tab
  • A password change or API key rotation now ends the sessions that credential had opened
  • bin/cli run:updateDb now compares every table and column against resources/sql/ampache.sql and only reports/fixes the ones that don't match, instead of unconditionally rewriting every table and column to one global charset; id/token/enum columns the schema pins to utf8mb3 are left alone

Fixed (8.2.0)

  • Subsonic search3 rejected an empty query (regression since 7.10.0/8.1.0); restored search2's "browse everything" behaviour
  • Last.fm and Libre.fm session keys were shown in plain text
  • Notifications displayed their own quotes, and were inserted as markup rather than as text
  • A site_title holding a closing script tag broke the page scripts
  • A stored theme_name reached get_theme() as a path segment without being confined to the themes directory
  • A preference written in one request was still read back stale in that same request
  • The slideshow armed itself without the Flickr plugin
  • Subsonic getIndexes returned an empty index on any library whose folder_map has not been rebuilt
  • Garbage collection incorrectly removed parent-only folders
  • Fixed missing Subsonic sub-folder listings
  • Fixed MariaDB error 1020 when using innodb_snapshot_isolation
  • Improved support for databases with autocommit disabled
  • Fixed false PDO error detection when error code was 00000
  • Fixed raw LICENSE tag handling for Vorbis metadata
  • Sanitised licence external links and blocked non-HTTP(S) URLs
  • Fixed folder handling in the Subsonic API
  • Fixed missing song lyrics
  • Database exceptions now include query and driver error details
  • Fixed admin:updateDatabase failures during partial migrations
  • Fixed now-playing polling continuing after page navigation
  • Restored "Save as Smart Playlist" for existing smart playlists
  • Fixed downloads failing when no files were available
  • Fixed proof-of-work loops after endpoint errors
  • Fixed private playlist share links rejecting visitors
  • Fixed withdrawn albums appearing in artist, API and UPnP listings
  • Fixed ineffective Enabled search rule on album disks
  • Added withdrawn status indicators to disk listings
  • Fixed managers being unable to view withdrawn tracks on artist song pages
  • Fixed missing generated artwork when custom_blankalbum is enabled
  • RSS artwork for a song/podcast episode with no cover now falls back to its album/podcast artwork instead of the placeholder
  • RSS artwork for an album with no cover of its own now falls back to the album artist's artwork instead of showing the placeholder
  • http authentication no longer accepts a client-supplied HTTP_REMOTE_USER header as an identity; only the server-set REMOTE_USER is trusted
  • Fixed withdrawn releases appearing in Recent, Popular, Trending and statistics views
  • Fixed withdrawn releases appearing in recently played views and feeds
  • Added visual highlighting for withdrawn items
  • Fixed run:updateCatalog -ca reimporting unchanged files
  • Fixed deleted_songs API always returning an empty result
  • Subsonic
    • Optimised genre lookups in getMusicDirectory
    • Optimised video and podcast tag loading
    • Unexpected API errors now return proper error responses
    • Reduced memory usage when browsing large folders
  • Fixed catalog scans leaving progress streams open after errors
  • Fixed DAAP requests returning empty responses on unexpected errors
  • Fixed sidebar section toggle inconsistencies
  • Fixed wanted_missing_albums errors when MusicBrainz data omitted secondary-types
  • Fixed live stream interruptions caused by PHP execution time limits
  • Fixed the ListenBrainz plugin double-prefixing a URL that already had a scheme
  • A MusicBrainz mirror given as a bare host is now assumed http instead of rejected
  • Restored the artist "Songs" tab's full-page view, which had regressed to a redirect
  • Header-authenticated session ids were md5(username), guessable from a username; now derived from the credential
  • update.php skipped auth based on a request parameter, letting anyone reach the update dispatcher
  • batch.php skipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filter
  • lost_password is now disabled by default, and blocked for Content Manager, Manager and Admin accounts
  • cleanup:sortSongs used the whole server's song count (not the catalog's) and the chunk index as a row offset, silently skipping songs on every catalog-wide run
  • Writing tags to a FLAC/Vorbis file could crash and leave the comment block partially written when adding a new per-user rating tag
  • print:tags crashed on any file not yet scanned into a catalog, including its own documented usage example
  • run:updateCatalogFile -r|--rename could never succeed; it looked up the destination catalog from a song row that the rename itself was meant to create
  • run:convertFilenames walked every local catalog instead of the one named on the command line
  • export:playlist never created its output directory and kept going anyway, failing a second time trying to write the playlist file
  • export:albumArt walked every catalog on the server instead of the one named on...
Read more

7.10.3

Choose a tag to compare

@lachlan-00 lachlan-00 released this 15 Sep 23:26
9c55c2b

Ampache 7.10.3

Fixed (7.10.3)

  • Localplay access was never actually checked (any user passed) and Subsonic jukeboxControl checked nothing. Now they are gated on the user's access level
  • A disabled account could still authenticate: Gatekeeper::getUser() (the api key path Subsonic itself uses), the Subsonic username/password login, and an RSS feed's token all resolved a disabled user as if it were active
  • Subsonic
    • Private playlists and searches leaked through several endpoints: web smartlist, getPlaylist/getPlaylists
    • setRating/setStar shared the API's rate/flag bugs, since both call into the same Rating/Userflag models: an out-of-range rating was stored as-is instead of clamped to 0-5, popularity weight could be drained below 0, and a future-dated flag pinned a favourite until real time caught up
  • WebDAV login accepted a disabled account and never bound the authenticated user, so catalog_filter_group wasn't applied to WebDAV browsing

API 6.9.2 Build 5

This version is being released for Ampache7 only

To ensure that there are no issues with clients checking for single int versions
we will keep on 6.9.x and resume build number versioning until Ampache 8

NOTE API8 has been removed from the codebase for Ampache 7.

Fixed (692005)

  • ALL
    • handshake: A disabled user account could still complete the handshake and receive a valid session. NOTE the same fix landed in Ampache8, which serves every version as well
    • Setting api_force_version reopened an API version the admin had disabled, bypassing the api_enable_3..api_enable_6 check. NOTE the same fix landed in Ampache8, which serves every version as well
    • stats: The user_id/username override handed back another user's streamtoken embedded in each item's play url; the response now carries the caller's own token. NOTE the same fix landed in Ampache8, which serves every version as well
    • rate: An out-of-range value (e.g. 127) was stored as-is instead of being clamped to 0-5, and repeatedly rating 0 could drain an object's popularity weight below 0. NOTE the same fix landed in Ampache8, which serves every version as well
    • timeline, friends_timeline: Listed activity against songs, videos, albums and other catalog-scoped objects the caller's own catalog filter excludes; those entries are now omitted from the result. NOTE the same fix landed in Ampache8, which serves every version as well
  • stats (API3, API4, API5, API6)
    • Naming another user's username/user_id with filter=recent ignored their allow_personal_info_recent opt-out. On Ampache8, only API3, API4 and API5 needed this fix because API6/API8 share one implementation that already checked it; on Ampache7, API6 has its own separate implementation which had the same gap, so it is included here too
  • API3
    • playlist, playlist_songs: A private playlist you neither own nor collaborate on was readable by anyone who guessed its id. NOTE the same fix landed in Ampache8, which serves this version as well
  • API5
    • ping: server_details returned server-wide catalog counts scoped to user id 0 when the auth token didn't resolve to a real user, instead of being rejected. NOTE the same fix landed in Ampache8, which serves this version as well
  • flag (API4, API5, API6)
    • A future date parameter pinned a favourite to the top of every newest list until real time caught up. NOTE the same fix landed in Ampache8, which serves these versions as well
  • playlist_add (API6)
    • A private playlist or smartlist named as the source object was expanded into the caller's own playlist, leaking its songs; a non-public source you neither own nor collaborate on is now refused. NOTE the same fix landed in Ampache8, which serves this version as well
  • search_group (API6)
    • The REST route search/{search_type}/groups delivers {search_type} as filter, but the method only read type, so it always searched all regardless of the path. NOTE the same fix landed in Ampache8, which serves this version as well
  • REST (ALL)
    • A REST call's path-derived type (e.g. playlist, from playlists/{playlist_id}/{add|remove}/) always overwrote a type sent in the request body, for every action the REST router type-tags this way. NOTE the same fix landed in Ampache8, which serves these versions as well
  • friends_timeline (API3, API4)
    • Returned the caller's own activity instead of the activity of the users they follow, calling getActivities() instead of getFriendsActivities(). NOTE the same fix landed in Ampache8, which serves these versions as well

8.1.0

Choose a tag to compare

@lachlan-00 lachlan-00 released this 11 Sep 03:06
18ce45d

8.1.0

php8.5
e0530840eddcbcc36e077db18a10dc95 ./ampache-8.1.0_php8.5.zip
e0530840eddcbcc36e077db18a10dc95 ./ampache-8.1.0_all_php8.5.zip
2f0221c5f4f320bdb3c4dc9f4fc36c40 ./ampache-8.1.0_all_php8.5_squashed.zip
cba49525100e83c2e8d63123c243c538 ./ampache-8.1.0_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
351520b240aec56d7a130cd64b3b7bb5 ./ampache-8.1.0.zip
351520b240aec56d7a130cd64b3b7bb5 ./ampache-8.1.0_public.zip
e84a1752f56e354f97e8fcd497e17012 ./ampache-8.1.0_squashed.zip
ccdd3b5b54f18fc8e2fb771d28c5cf8b ./ampache-8.1.0_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.1.0.zip is a copy of ampache-8.1.0_public.zip and ampache-8.1.0_php8.5.zip is a copy of ampache-8.1.0_all_php8.5.zip.

The shorter names become the default for the public structure in Ampache9; the _public and _all names will be kept for the rest of the 8.x series.

Ampache 8.1.0

Subsonic Users The Subsonic API now fully implements folder browsing.

Populate your catalog folders using the cli (php bin/cli run:updateCatalog -s) or the "Scan All Folders" command in the UI.

Album database grouping Allow custom grouping using the new config option album_grouping_fields.

Run a Catalog verify after changing this setting to update your Albums. NOTE Using album_grouping_fields is not recommended.

Name and Year are recorded but all other dropped columns are not kept. Year will be recorded as the first Song it reads on create even if other years differ.

Added (8.1.0)

  • Proof of work checks in front of the endpoints bots hammer
    • Off by default; set pow_mode to guest or all to enable it
    • pow_protected picks the endpoints: the registration form, batch (zip) downloads and single track downloads
    • The browser solves a sha256 puzzle before it is let through, tuned with pow_difficulty (8-26) and pow_ttl
    • pow_exempt_level waves trusted users through in all mode; pow_log_failures records what gets blocked
    • Needs JavaScript and Web Workers: it stops crawlers, not a determined attacker, so pair it with a rate limit
  • Database 810001
    • New show_composer preference (off by default) for a Composer column on playlist media and Song rows
  • Database 810010
    • New folder.time column with the summed duration of everything below each folder, subfolders included, rolled up the same way as total_count/total_skip; the API folder browse response now reports it as time on the browsed folder and on each item in its contents
  • Remote and Subsonic catalogs now build folder data during a scan (-s, or "Scan Folders"/"Scan All Folders"), so folder browsing works for them like local catalogs
  • Add Time column on folder browses
    • php bin/cli run:updateCatalog -s skips the folder count/time rollup on a run that finds no changes
    • If a folder's counts or duration look stale, run garbage collection (-t, or admin/catalog.php?action=garbage_collect) to force a refresh
  • A Time column on playlist browses, sortable via last_duration
  • Config version 99
    • New album_grouping_fields option controlling which fields decide whether two songs share an album row, so pressings that only differ by barcode/catalog_number/version (or any other field) can be grouped together instead of split into separate albums
    • Not recommended: a dropped field is written as NULL rather than stored from whichever song scanned first, so albums it merges together lose that value entirely; every such match logs a warning (not shown in the UI)
    • name and year can be dropped from the list too, though doing so can merge albums you didn't mean to merge
    • catalog is always matched and isn't part of the list; an album is always scoped to its catalog
    • Server-wide, not a user preference; defaults to today's full field set (name,year,prefix,mbid,mbid_group,album_artist,release_type,release_status,original_year,barcode,catalog_number,version)
  • Drawn cover art for items that have none: an album gets a record, an artist a medallion, an orphaned song a waveform, a playlist a tracklist. Built as SVG so one response serves every size, seeded from the item's name so a tile is stable. Off by default, per-user opt-in; a configured custom_blankalbum always takes precedence when present
  • Dynamic page titles carrying the artist or album in context, with a user preference to show a page-type icon in the tab title
  • A SVG favicon, an apple-touch-icon for phone home screens, and a link-preview image, each replaced on their own when an admin customises them
  • A branding section under the server settings gathering the favicon, logos, login artwork and the two new icons in one place, plus a site description for link previews
  • An Uploaded column on the upload browses, sortable
  • A browser-measured HTTP compression check on the test page
  • Folder and collection pages describe themselves in a shared link, like the other object pages do
  • Database 810011
    • New album.enabled and artist.enabled, carrying the name and the promise song.enabled already had, so a release can be withdrawn without deleting it and losing its playlist entries, ratings and play history
    • Set from a State menu in the album, artist and song edit dialogs by a catalog manager, who keeps seeing what is disabled; disabling an album or artist carries down to its songs, and enabling carries back
    • Disabled items leave every browse, smartlist, API, Subsonic and RSS listing, and carry a marker in the rows only a manager still sees. An Enabled search rule lists them
    • A song can still be enabled or disabled on its own; the next change of its album or artist state writes over it

Changed (8.1.0)

  • Database 810002
    • Covering index on image for the art cache lookup, so it can be answered from the index alone; drops the now-redundant object_id key it replaces
  • Folder garbage collection now also removes folders with nothing left inside them, including root folders
  • Folder play-count rollups now write in bulk instead of one query per folder, and a scan skips garbage collection when nothing changed
  • Serving a cover no longer opens a full session: no last_seen write, no serialized-session rewrite, and a cookie-less request (a crawler, a link preview) no longer leaves a session row behind
  • Session::extend no longer rewrites the expire column on every request
  • Visitors who never queue anything no longer get a tmp_playlist row, dashboard and mashup boxes no longer write a tmp_browse row they never store, and a page view no longer creates a broadcast stream session
  • Gettext loads the catalogue only when something is translated, and reads a prebuilt PHP array the opcache holds rather than parsing the .mo each request
  • The Subsonic artist and playlist lists, the genre and artist-name lookups, the smartlist name lists and reverse-geocoding all warm their caches once per page instead of once per row
  • Server-wide user counters are batched into one statement per key
  • The set of generated art sizes is bounded, and a missing cover is served the placeholder that fits rather than the full-size original
  • A remote custom_blankalbum is handed to the browser as a url it caches once, rather than fetched server-side on every miss
  • The Subsonic, OpenSubsonic and API 6/8 playlist listings now serve the stored last_count/last_duration, the way their smartlist branch always has, instead of recounting each row with two joined queries
  • The API song, album, artist and playlist pages, the Subsonic and OpenSubsonic lists, and the UPnP browse lists read a fixed number of queries whatever the page size. Genres, moods, ratings, art, labels, disks and smartlist owners are read once for the page
  • The XML API output reads the page's song art rows once instead of once per song
  • The home page reads its highlighted songs from the page-wide cache, and cover metadata is read without the image blob nor file
  • A request looks a user up once by API key or username, however many times it asks
  • The recently played lists use more cache, speed improvement
  • The preferences rebuild that follows a database update repairs the install once instead of once per user, and the garbage collector only rewrites the preference names that changed. Test on 500 users, went from 248s to 6s
  • user.apikey carries an index, and the hashed-key fallback only reads the users holding a key
  • Play history search rules had no index
  • Whole-table sweeps moved out of the loops (subsonic scrobble, catalog add)
  • docs/examples/nginx-site.conf and apache-site.conf gained example per-IP rate limiting for /login.php, the API handshake and Subsonic

Fixed (8.1.0)

  • Album, album disk and artist song counts no longer include disabled songs, so an album whose tracks are all disabled stops advertising them
  • The page-wide caches for album artists and object genres were never dropped when their maps changed, so a read after a write in the same request answered with the state from before it
  • The OPML export of podcast subscriptions read every podcast in the system regardless of the caller's catalog filter, letting a restricted user enumerate the subscriptions of catalogs they cannot browse
  • A user's timeline, the Friends Timeline widget, and the timeline/friends_timeline API methods listed activity against songs, videos, albums and other catalog-scoped objects the viewer's own catalog filter excludes; those entries are now hidden the same way the Now Playing widget already hides them
  • The public Now Playing page (use_now_playing_embedded, viewable while logged out) still linked an unauthenticated viewer straight to the song/album/artist/video being p...
Read more

8.0.1

Choose a tag to compare

@lachlan-00 lachlan-00 released this 17 Aug 06:29
8ffe682

8.0.1

php8.5
d46a10f1180a2371bce81edef20bc59d ./ampache-8.0.1_php8.5.zip
d46a10f1180a2371bce81edef20bc59d ./ampache-8.0.1_all_php8.5.zip
cd0b327273e05ece07ba22c82eca2ded ./ampache-8.0.1_all_php8.5_squashed.zip
b203dd118806c186d76bbad1ae694a59 ./ampache-8.0.1_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
62bd2e32d644aff871994d8294f68f3c ./ampache-8.0.1.zip
62bd2e32d644aff871994d8294f68f3c ./ampache-8.0.1_public.zip
6bcd0462f4fbc0fc9238032b740a9a0e ./ampache-8.0.1_squashed.zip
4abd77d585bdceb5c4ca57fee23a7829 ./ampache-8.0.1_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.0.1.zip is a copy of ampache-8.0.1_public.zip and ampache-8.0.1_php8.5.zip is a copy of ampache-8.0.1_all_php8.5.zip.

The shorter names become the default for the public structure in Ampache9; the _public and _all names will be kept for the rest of the 8.x series.

Ampache 8.0.1

Added (8.0.1)

  • Translations 2026-08-17
  • Show Catalog name on song pages
  • Increase redirect count on Podcast Episode download from 5 to 10
  • Missing ASF/Windows Media tag for Composer
  • Podcast RSS feeds
    • itunes:image (per-episode too), itunes:author, itunes:explicit and an optional Apple sub-category (rss_subcategory)
    • Optional path-style feed urls (rss_beautiful_url)
    • Feeds are indexable and cacheable (etag/304) by default

Changed (8.0.1)

  • Lock database connection on catalog actions to avoid repeats and deadlocks
  • An unrecognised transcode_TYPE value (e.g. transcode_mp3 = "falsed") no longer counts as enabling transcoding; only allowed, required and false are accepted and anything else is logged and treated as false
  • Invalid transcode_TYPE values are listed on the admin debug page
  • Database 801001
    • Dropped 24 redundant indexes across 15 tables; each repeated the leading columns of a wider key already on the same table
    • album_map, artist_map, folder_map and song_map carried the most, and grow with the catalog
  • Database 801002
    • Convert stream_beautiful_url to an Admin preference
  • Garbage collection actions (admin/catalog.php?action=garbage_collect and php bin/cli run:updateCatalog -t) now run Session::garbage_collection(), cleaning up tmp_playlist/tmp_playlist_data, stream_playlist, song_preview and the query cache, not just library objects
    • Run this at least once after upgrading On a database with cron disabled that's never had this data collected, the first run can be slow
    • Also resets the AUTO_INCREMENT on stream_playlist, playlist_data, tmp_playlist and tmp_playlist_data afterwards, instead of leaving those ids climb forever
  • php bin/cli run:cronProcess's garbage collection now shares the same lock as the other garbage collection triggers, so a scheduled cron run can't race a manual one
  • run:computeCache and run:cronProcess's cache rebuild now take their own lock, so two overlapping runs can't double-count the results or publish a half-rebuilt table
  • UPnP playlist browsing counts a playlist's tracks without loading them, the same way the rest of the app already does
  • Row-prefetch caching (avoiding a query per row) is extended to more listings: Browse now also covers podcast, podcast episode, live stream, label, catalog, collection, folder, user, follower, share, broadcast, private message and wanted-album pages, and the JSON/XML API list endpoints (album, artist, catalog, playlist, podcast, podcast episode, song, tag, video, user, share) now warm the same object/rating/userflag caches before their loop instead of querying per item
  • Art existence/metadata lookups (has_db/has_art) are batch-prefetched the same way during browse and artist/playlist/tag/video listing, instead of querying disk or the database per row
  • Album/album disk/video search read the catalog id straight off the row instead of joining catalog_map, since it's already stored there directly
  • Config version 97
    • New deleted_history_days option (default 0, keep forever); garbage collection prunes deleted_song/deleted_video/deleted_podcast_episode rows older than this many days

Fixed (8.0.1)

  • Many possible nullable database column issues fixed
  • Don't lock the UI on larger click operations. (e.g. Album delete)
  • Redirect to the full login page on session failure
  • Every disk section on a multi-disk album page listed the first disk's songs
  • A multi-disk album shows its [Disk N] label again on the album page, the disk page and in song lists
  • Install Localplay as the system user so it's applied to all users
  • Preferences page
    • preferences.php no longer renders for an unregistered/guest visitor
    • Plugin credential preferences (api keys, tokens, passwords) are write-only in the edit form; the stored value is never echoed back, only replaced
    • The user_preferences API method (and REST preferences) returned those same plugin credential values in the response; they're blanked there too
    • The single-preference lookups (preference, user_preference, preference_create, preference_edit, preference_delete) still returned the raw value for a secret-named preference; Preference::get() now blanks it the same way
  • The account preferences page and the admin user-edit page showed the avatar delete link even when the user had no avatar set
  • An unregistered/guest visitor could upload and import a playlist file, or export every podcast subscription in the system, neither of which checked for a real account; importing a playlist also now verifies the request came from Ampache's own form
  • A user's last-seen date/time on their profile page ignored their allow_personal_info_time preference, unlike the recent-activity list right next to it on the same page
  • The Last.fm/Libre.fm grant-access link on the preferences page was missing its api_key, so granting access failed
  • Cancel/confirmation dialogs (show_confirmation, show_confirmation_with_return, show_continue)
    • A callback url that merely contained the web path as a substring, rather than actually being absolute, had the web path prepended again and was mangled
    • return_referer() could return the current request's own url when client-side navigation had already rewritten the address bar, sending Cancel back to the page it was on instead of the previous one
    • The referer had already been html-escaped once before reaching the link builder, so its & was escaped a second time
  • The admin debug preferences page showed several boolean preferences (api_enable_8, cli_no_color, playlist_art_mosaic, public_images, show_collection, show_folder, user_create_apikey) with the wrong input type, because they were missing from Preference::is_boolean()
  • Outbound fetches
    • Now check every redirect hop against the same private-address rule as the initial url, not just the url as given; applies to remote/radio stream playback, art fetching, and the Lyrist and YOURLS plugins
    • The LrcLib and AudioMuse-AI plugins didn't check the configured server url at all before fetching from it; they now do
  • A podcast feed's own <title> was used unsanitized as a folder name, so a hostile feed containing ../ could create directories and write episode files outside the catalog
  • Upload's target-folder check accepted any resolved path that merely started with the catalog path as a string (e.g. a sibling music-private folder next to music), rather than requiring it to actually be inside the catalog directory
  • Core::generate_random_key() hashed a predictable seed instead of drawing directly from a secure random source; it backs session ids, api keys and the CSRF form token, and now uses random_bytes() for the full 128 bits
  • Browse
    • A handful of filters (rating, folder's id, song's top50 artist match, playlist's smartlist id list) built their WHERE/IN value without the surrounding quotes Dba::escape() expects; the value is quoted like every other escaped filter now
  • The upload_script post-processing hook (opt-in, off by default) substituted the uploaded file's own client-supplied name into %FILE% and ran the result as a shell command; a filename carrying shell metacharacters could run arbitrary commands as the web server user. The filename is shell-escaped before substitution now
  • Login compared the stored password hash to the submitted one with ==/in_array() instead of a constant-time comparison; both now use hash_equals()
  • Logging in with a referrer pointing at a host that merely starts with the site's own url (e.g. yoursite.com.attacker.net) was honoured as a same-site redirect after a successful login; the referrer's host is now compared exactly
  • A song or video title containing a " broke out of the quoted Content-Disposition filename on download, letting extra parameters be appended; the character is stripped like the linebreak/comma/semicolon it already strips
  • The theme_name/theme_color preferences were only checked for existing on disk, not for staying inside the themes directory; both are now rejected outright if they contain a path separator
  • A profile self-update could smuggle in catalog_filter_group alongside the fields the form actually offers, silently reassigning the user's own catalog visibility group; it's stripped from the request like access already was
  • The session, _remember and _user/_lang cookies were missing HttpOnly, so any XSS could read them and steal the session directly instead of just acting within the page; it's set on every auth-bearing cookie now
  • Browse
    • The regex_match/regex_not_match filter value reaches SQL REGEXP as-is with no length limit; it's now capped at 100 charac...
Read more

7.10.2

Choose a tag to compare

@lachlan-00 lachlan-00 released this 17 Aug 01:13
e5dca5f

7.10.2

php8.5
77d2f3097a54429ddba869fc371ce021 ./ampache-7.10.2_all_php8.5.zip
19c5b44ba071005d827f64b115df3c58 ./ampache-7.10.2_all_php8.5_squashed.zip
1e8d6744db74f662df5120187106d898 ./ampache-7.10.2_all_php8.5_client.zip

php8.4
1c0344fbfad351c40350dadd14b5b565 ./ampache-7.10.2_all_php8.4.zip
23d262b583a3d4de0765f9e2fa5b6f37 ./ampache-7.10.2_all_php8.4_squashed.zip
11e9f178b3b96026fa922d6d81cee6c6 ./ampache-7.10.2_all_php8.4_client.zip

php8.3
fba13cd6ea3e2f448d19bdd023156d30 ./ampache-7.10.2_all_php8.3.zip
7dfd45f9a729c3636a36216a561c8eeb ./ampache-7.10.2_all_php8.3_squashed.zip
e02935a9ff281a5649b953397011f706 ./ampache-7.10.2_all_php8.3_client.zip

php8.2
193202e0fa08feee17cb08af4be66d94 ./ampache-7.10.2_all_php8.2.zip
9a0d2e7233446d720b7fdcde61491d65 ./ampache-7.10.2_all_php8.2_squashed.zip
b4ed10e610596913116783461b64d281 ./ampache-7.10.2_all_php8.2_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
31bdeb5a1f997452e4d723a7e631ffea ./ampache-7.10.2_public.zip
e57431eea5abac54e88a393868167f28 ./ampache-7.10.2_squashed.zip
832a18f7dadff9b9b3aabef9ce36cb48 ./ampache-7.10.2_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

Ampache 7.10.2

Fixed (7.10.2)

  • API authorization did not require the api key to identify the user; Gatekeeper::getUser() fell back to the user request parameter when the key did not match a user
    • A request carrying an unknown key was still resolved to whoever the user parameter named
  • Subsonic
    • createPlaylist sent with a playlistId rewrites that playlist, but unlike updatePlaylist it never checked who owned it, so any user could overwrite another user's playlist
    • The same owner check now applies, and an id that does not exist returns a not-found error instead of creating a list
  • Transcoding
    • The resolution playback option was substituted into %RESOLUTION% and handed to a shell unchecked; only a literal WIDTHxHEIGHT is accepted now and anything else falls back to the default
    • quality is cast to an int before it is used in the bitrate calculation
  • Playlist, smartlist and genre names were written into the search and genre-row templates without escaping
  • Every play, skip and play-count rollback ran an update against folder and folder_map, which are Ampache8 tables, so counting a song, video or podcast episode logged an SQL error on tables that do not exist in Ampache7
  • Renaming a smart playlist from the web interface did nothing, because the edit action passed the POSTed id along as a string and Search takes an int (#4426)
  • Activating the 7digital plugin created none of its preferences, so it could not be configured; the check meant to skip preferences that already exist was inverted, and only ran the insert when there was nothing to insert
  • The Headphones plugin's headphones_api_url and headphones_api_key preferences were installed at User level, so any regular user could point the server at an arbitrary internal address; both are now Manager level, matching every other plugin url preference
  • Core::generate_random_key() hashed a predictable seed instead of drawing directly from a secure random source; it backs session ids, api keys and the CSRF form token, and now uses random_bytes() for the full 128 bits
  • Browse
    • A handful of filters (rating, song's top50 artist match) built their WHERE value without the surrounding quotes Dba::escape() expects; the value is quoted like every other escaped filter now
  • The upload_script post-processing hook (opt-in, off by default) substituted the uploaded file's own client-supplied name into %FILE% and ran the result as a shell command; a filename carrying shell metacharacters could run arbitrary commands as the web server user. The filename is shell-escaped before substitution now
  • Login compared the stored password hash to the submitted one with ==/in_array() instead of a constant-time comparison; both now use hash_equals()
  • Logging in with a referrer pointing at a host that merely starts with the site's own url (e.g. yoursite.com.attacker.net) was honoured as a same-site redirect after a successful login; the referrer's host is now compared exactly
  • A song or video title containing a " broke out of the quoted Content-Disposition filename on download, letting extra parameters be appended; the character is stripped like the linebreak/comma/semicolon it already strips
  • The theme_name/theme_color preferences were only checked for existing on disk, not for staying inside the themes directory; both are now rejected outright if they contain a path separator
  • A profile self-update could smuggle in catalog_filter_group alongside the fields the form actually offers, silently reassigning the user's own catalog visibility group; it's stripped from the request like access already was
  • The session, _remember and _user/_lang cookies were missing HttpOnly, so any XSS could read them and steal the session directly instead of just acting within the page; it's set on every auth-bearing cookie now
  • API and stream session keys were built from mt_rand()/uniqid() instead of a secure random source; they now use the same Core::generate_random_key() the login CSRF token and web session already relied on
  • Browse
    • The regex_match/regex_not_match filter value reaches SQL REGEXP as-is with no length limit; it's now capped at 100 characters against a catastrophic-backtracking pattern
  • A share's secret was compared with != instead of a constant-time comparison, so two "magic hash" values (0e followed only by digits) could match each other regardless of their actual digits; it now uses hash_equals()
  • Database
    • Downgrading from Ampache8 removes the broadcast_private, show_mood and hide_moods preferences instead of leaving them in the preferences list
    • headphones_api_url/headphones_api_key are raised to Manager level for existing installs

8.0.0

Choose a tag to compare

@lachlan-00 lachlan-00 released this 11 Aug 21:23

8.0.0

php8.5
3ae3a235247076ef6c457be293d5c0f7 ./ampache-8.0.0_php8.5.zip
3ae3a235247076ef6c457be293d5c0f7 ./ampache-8.0.0_all_php8.5.zip
ad8d4f4d019dd57ef98da4b8fa1f679c ./ampache-8.0.0_all_php8.5_squashed.zip
29771b14274752e5e8361a615899773b ./ampache-8.0.0_all_php8.5_client.zip

UNSUPPORTED Code only release. (Requires composer and npm install)
f20a0a5ea76581a43380d909f88f543d ./ampache-8.0.0.zip
f20a0a5ea76581a43380d909f88f543d ./ampache-8.0.0_public.zip
3abfa0996cf51d96fb3088178f3adb30 ./ampache-8.0.0_squashed.zip
82bfea25b45325ff26d9e2c77c96c337 ./ampache-8.0.0_client.zip

Zip Version information

If you aren't familiar which the project make sure you know which zip you need to download.

ampache-8.0.0.zip is a copy of ampache-8.0.0_public.zip and ampache-8.0.0_php8.5.zip is a copy of ampache-8.0.0_all_php8.5.zip.

The shorter names become the default for the public structure in Ampache9; the _public and _all names will be kept for the rest of the 8.x series.

Ampache 8.0.0

You can downgrade to Ampache7 if you try this out and have issues, using the cli (bin/cli admin:updateDatabase -e).

NOTE The /rest rewrite rules changed a lot in this release. Use php bin/installer htaccess -e to update your htaccess files (or the Write buttons on the install/update page). The rest/.htaccess configured? check reports a file left over from an older release, so it will tell you when this is needed.

  • Ampache 8 requires PHP 8.5+
  • This version adds a new Folder domain which functions as a virtual filesystem browsing layer over catalog files.
  • A very major PHPStan level 8 / Rector / PER-CS3x0 hardening pass across the code.

Added (8.0.0)

  • Translations 2026-08-11
  • OpenID Connect (OIDC) login
    • New oidc auth method; add it to auth_methods to enable it (keep mysql so local accounts can still log in)
    • Configure a single provider (Keycloak, Entra ID, Authentik, Google, Okta, ...) with the new oidc_* config keys
    • Authorization code flow with PKCE (S256); users are matched by the oidc_username_claim claim and provisioned through the existing auto_create / auto_user / external_auto_update settings, exactly like LDAP
    • The redirect uri to register with the provider is <web_path>/oidc/; it carries no query string and needs no webserver configuration
    • Point logout_redirect at the provider's end_session_endpoint to sign out of the provider as well
  • Folder Browsing
    • Folder domain/model for browsing the catalog as a virtual folder tree
    • New show_folder preference to show/hide the "Folders" link in the sidebar
  • Play history consolidation
    • New stats_consolidate_threshold config option; the number of days of detailed play history to keep in object_count (0, the default, disables consolidation)
    • New cleanup:consolidateStats CLI command aggregates older plays into object_count_summary and moves the detail rows to object_count_archive; dry-run unless -e is given
    • New cleanup:restoreStats CLI command puts the archived detail back and regenerates the album, album_disk, artist and podcast rows from it
    • Nothing is discarded: media rows keep their exact date, agent and location for streams, skips and downloads, so a consolidate/restore cycle is lossless
    • Play counts, played flags and streamed data size stay exact while consolidated; period-based statistics (trending, recent, graphs, Last.fm export), smart playlist play-history rules and play count sorting only see the retained window
    • Example systemd unit and timer in docs/examples
  • Mini player
    • New /m/ page showing only the home category plugins and the web player, for small screens and simple accounts
    • New mini_player preference locks a user into that page; it hides the rest of the interface but is not an access control, user access levels still decide what data is reachable
    • Logging in returns you to the page you originally asked for, including index.php#page.php?... links
    • New Mini player button on the login form, next to Register and Lost Password, to land there after logging in
  • Multi select
    • New Multi-Select browse option in the View menu turns the checkboxes on; they stay hidden until you ask for them
    • Checkboxes on the playlist items and collection items lists select several entries at once, and the header checkbox selects the whole page
    • Ctrl/Cmd+click toggles a row and Shift+click selects a range, anywhere on the row that is not itself a button or a link
    • A selection can be played, played next, played last, added to the temporary playlist, added to another playlist, or removed from the playlist in a single action, from a bar that stays in view while you scroll the list
    • Removing a selection sends one request and renumbers the list once, instead of one request and one full renumber for every entry
    • A mixed collection groups the selection by type before acting on it, so playing a selection of albums and songs together works from one bar
    • The same checkboxes, gestures and action bar on the song lists, which covers the songs browse as well as the song lists on album, artist and search pages
    • A selection of songs can be downloaded as a single zip, when allow_zip_types includes song and batch download is permitted
    • batch.php accepts a comma separated id list, so one zip can hold the medias of several items instead of only one
  • Broadcasting is documented and easier to get working
    • New docs/BROADCAST.md covers the whole feature: the config, the bin/cli run:websocket server it needs, reverse proxy and TLS, and how to test each step
    • New docs/examples/ampache_websocket.service systemd unit, so the websocket server can run as a service like the other jobs
    • The websocket address defaults to wss:// when Ampache is served over https; a plain ws:// default was blocked by the browser as mixed content and reported nothing on the page
    • The broadcast socket also accepts connections from the host in web_path, not only the host in websocket_address; a mismatch was refused with 403 that never appeared in the interface
    • run:broadcast (a UPnP announcement) and run:websocket (broadcasting) now say which is which in their help
    • New broadcast_private preference (Streaming) decides whether a user's new broadcasts require a listener session; it is on by default, matching what every broadcast did before, and can now be turned off per user
    • The Broadcasts browse has All and Live views; a broadcast only counts as live when it is started and still holds the key a listener connects with
    • Starting the websocket server clears any broadcast a previous server left marked as running, so a crash no longer leaves rows claiming to be live forever
    • Garbage collection clears the state of broadcasts that cannot be running, leaving a broadcast that still holds its listener key alone in case it is live
  • Song previews work again
    • New iTunes and Deezer plugins find a 30 second sample for a wanted album's tracks; neither needs an api key or an account
    • Neither provider indexes MusicBrainz ids, so a track is matched on artist and title and a wrong match is possible
  • A "Create Playlist" button on the playlists browse. Until now a playlist could only come into existence as a side effect of adding something to one
  • Database
    • New api_enable_8 preference to enable/disable API v8 responses per user
    • New database tables folder and folder_map
    • New database tables object_count_summary and object_count_archive
    • folder added to the object_type enum on several tables (cache_object_count, cache_object_count_run, image, object_count, and others)
    • New user.subsonic_secret column holding the per-user Subsonic password
    • New database tables collection and collection_map
    • New database tables playlist_folder and playlist_folder_map, holding a private per-user tree that organises playlists, smartlists and collections
    • New maintained last_played column on album, album_disk, artist, podcast, podcast_episode, song and video, written on the same statement that increments the play counter and backfilled from the existing play history (live counts, archived detail and consolidated summaries)
    • collection added to the object_type enum on image, object_count, cache_object_count, cache_object_count_run, object_count_summary and object_count_archive, so a collection carries its own art and play statistics
    • collection added to the object_type enum on rating and user_flag, so a collection can be rated and flagged
    • New position_ms, playback_rate and state columns on now_playing, holding what an OpenSubsonic client reports through reportPlayback
    • New artist.lastfm_url column keeping the last.fm page url with the rest of the cached artist info
    • label_asso gains a nullable album column and its artist column becomes nullable, so a label can be associated with an album as well as an artist
    • New song_data.bpm column holding the tagged beats per minute
  • Subsonic
    • OpenSubsonic implementation audited against the published specification on 2026-08-07; the audited build is committed as docs/openapi-opensubsonic.json and pinned by a test so a refreshed copy prompts a re-audit instead of drifting silently
    • New transcoding extension: getTranscodeDecision (POST, with the client's playback capabilities as a JSON body) reports whether a file can be played as-is, and getTranscodeStream serves the result. The decision is derived from the same transcode settings that serve the bytes, and its transcodeParams token is signed with secret_key so a client cannot choose its own output format ...
Read more