Repository navigation
Releases: ampache/ampache
Release list
7.10.5
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.phptoupdate.php, which requires a session and bounced back tologin.php, looping forever instead of showing the login form (#4547) - Downgrading from Ampache8 left the
rightbar_always_showpreference behind; it's now removed like the other Ampache8-only preferences
7.10.4
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(defaultfalse) to gate the Lost Password feature
- Added
Changed (7.10.4)
- Updated Composer and NPM packages
Fixed (7.10.4)
- Subsonic
search3rejected a missing or emptyquery(regression since 7.10.0), breaking clients (e.g. Substreamer) that load the full library through an empty search; restored the same "browse everything" behavioursearch2already 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)
httpauthentication no longer accepts a client-suppliedHTTP_REMOTE_USERheader as an identity; only the server-setREMOTE_USERis trusted- Header-authenticated session ids were
md5(username), guessable from a username; now derived from the credential update.phpskipped auth based on a request parameter, letting anyone reach the update dispatcherbatch.phpskipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filterlost_passwordis 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
updateshareon 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_passwordto be enabled - Also blocked for Content Manager and Manager accounts
- Disabled by default; requires
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
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/stringtype 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.categoryfrom a plainvarcharto anenumof its seven real values - Shrank
preference.subcategoryfromvarchar(128)tovarchar(32)and pinned it toutf8mb3
- Corrected the
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 Allwrites into every existing account - Access levels are read from
Preference::DEFAULTSrather 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_preferencesrenders the shared preferences screen- The
defaultpreset is read fromPreference::DEFAULTSinstead 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
- The confirmation names which changes the per-row
Removed (8.2.2)
preferences.php?action=user, which required admin but only ever showed your own preferencesUi::createPreferenceInput()andUi::showPreferenceBox(), replaced by a type-driven renderer- The
Preference::DEFAULT_LEVELSconstant, replaced byPreference::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_versiondid not offer version 8, so a resubmit silently reset it to 0localplay_levelandupload_access_leveldid 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.phpredirected straight back toupdate.phpwith a pending database update, looping forever (ERR_TOO_MANY_REDIRECTS) instead of showing the login form
8.2.1
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
transcodingtype onencode_target,encode_video_target,encode_player_webplayer_targetandencode_player_api_target, fixing the missing encode-format dropdown on those preferences thatMigration810028caused in 8.2.0
- Restored the
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.recommendationfor the similar artists/songs lookup - Added
musicbrainz_serverandmusicbrainz_throttlepreferences to support custom MusicBrainz mirrors and configurable request throttling - Added
jellyfin_backend_enablepreference - Added
jellyfin_quick_connecttable andquickconnect_enablepreference for QuickConnect pairing - Corrected the
booltype onhome_recently_played_allandshow_wrapped - Corrected
preference.name's collation to matchuser_preference.name, fixing an "Illegal mix of collations" error inadmin:updateDatabase - Added
embed_playerpreference, offering a player to sites that link here - Pinned
object_typetoutf8mb3onfolder_map,collection,collection_map,playlist_folder_map,object_count_archiveandobject_count_summary, matching every otherobject_typecolumn - Removed the dead
tvshow/tvshow_seasonvalues from theobject_typeenum oncache_object_count,cache_object_count_run,image,object_count,rating,tag_map,user_activityanduser_flag - Converted
object_typefrom a plainvarcharto anenumof its real, verified values onalbum_map,artist_map,catalog_map,folder_map,collection_map,bookmark,tmp_playlist,tmp_playlist_data,recommendation,user_shoutandcollection - Widened
bookmark/tmp_playlist'sobject_typeenum to the same playable-media list asplaylist_data/tmp_playlist_data, so a new playable type needs no further migration - Converted
playlist_folder_map.object_type,preference.typeandstream_playlist.typefrom a plainvarcharto anenumof their real, verified values
- Added an index on
- 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 Favoriteshome 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_proxyoption (defaulttrue) to control live stream proxying
- Added
Changed (8.2.0)
- Updated Seafile SDK to
dev-master - Updated Composer and NPM dependencies
wanted_typesnow includessingleandepby 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:updateDbnow compares every table and column againstresources/sql/ampache.sqland 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 toutf8mb3are left alone
Fixed (8.2.0)
- Subsonic
search3rejected an emptyquery(regression since 7.10.0/8.1.0); restoredsearch2'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_titleholding a closing script tag broke the page scripts - A stored
theme_namereachedget_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
getIndexesreturned an empty index on any library whosefolder_maphas 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
LICENSEtag 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:updateDatabasefailures 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
Enabledsearch 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_blankalbumis 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
httpauthentication no longer accepts a client-suppliedHTTP_REMOTE_USERheader as an identity; only the server-setREMOTE_USERis 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 -careimporting unchanged files - Fixed
deleted_songsAPI 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
- Optimised genre lookups in
- 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_albumserrors when MusicBrainz data omittedsecondary-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
httpinstead 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.phpskipped auth based on a request parameter, letting anyone reach the update dispatcherbatch.phpskipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filterlost_passwordis now disabled by default, and blocked for Content Manager, Manager and Admin accountscleanup:sortSongsused 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:tagscrashed on any file not yet scanned into a catalog, including its own documented usage examplerun:updateCatalogFile -r|--renamecould never succeed; it looked up the destination catalog from a song row that the rename itself was meant to createrun:convertFilenameswalked every local catalog instead of the one named on the command lineexport:playlistnever created its output directory and kep...
8.2.0
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.recommendationfor the similar artists/songs lookup - Added
musicbrainz_serverandmusicbrainz_throttlepreferences to support custom MusicBrainz mirrors and configurable request throttling - Added
jellyfin_backend_enablepreference - Added
jellyfin_quick_connecttable andquickconnect_enablepreference for QuickConnect pairing - Corrected the
booltype onhome_recently_played_allandshow_wrapped - Corrected
preference.name's collation to matchuser_preference.name, fixing an "Illegal mix of collations" error inadmin:updateDatabase - Added
embed_playerpreference, offering a player to sites that link here - Pinned
object_typetoutf8mb3onfolder_map,collection,collection_map,playlist_folder_map,object_count_archiveandobject_count_summary, matching every otherobject_typecolumn - Removed the dead
tvshow/tvshow_seasonvalues from theobject_typeenum oncache_object_count,cache_object_count_run,image,object_count,rating,tag_map,user_activityanduser_flag - Converted
object_typefrom a plainvarcharto anenumof its real, verified values onalbum_map,artist_map,catalog_map,folder_map,collection_map,bookmark,tmp_playlist,tmp_playlist_data,recommendation,user_shoutandcollection - Widened
bookmark/tmp_playlist'sobject_typeenum to the same playable-media list asplaylist_data/tmp_playlist_data, so a new playable type needs no further migration - Converted
playlist_folder_map.object_type,preference.typeandstream_playlist.typefrom a plainvarcharto anenumof their real, verified values
- Added an index on
- 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 Favoriteshome 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_proxyoption (defaulttrue) to control live stream proxying
- Added
Changed (8.2.0)
- Updated Seafile SDK to
dev-master - Updated Composer and NPM dependencies
wanted_typesnow includessingleandepby 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:updateDbnow compares every table and column againstresources/sql/ampache.sqland 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 toutf8mb3are left alone
Fixed (8.2.0)
- Subsonic
search3rejected an emptyquery(regression since 7.10.0/8.1.0); restoredsearch2'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_titleholding a closing script tag broke the page scripts - A stored
theme_namereachedget_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
getIndexesreturned an empty index on any library whosefolder_maphas 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
LICENSEtag 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:updateDatabasefailures 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
Enabledsearch 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_blankalbumis 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
httpauthentication no longer accepts a client-suppliedHTTP_REMOTE_USERheader as an identity; only the server-setREMOTE_USERis 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 -careimporting unchanged files - Fixed
deleted_songsAPI 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
- Optimised genre lookups in
- 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_albumserrors when MusicBrainz data omittedsecondary-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
httpinstead 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.phpskipped auth based on a request parameter, letting anyone reach the update dispatcherbatch.phpskipped catalog scoping for stream-session requests, allowing bulk download outside the catalog filterlost_passwordis now disabled by default, and blocked for Content Manager, Manager and Admin accountscleanup:sortSongsused 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:tagscrashed on any file not yet scanned into a catalog, including its own documented usage examplerun:updateCatalogFile -r|--renamecould never succeed; it looked up the destination catalog from a song row that the rename itself was meant to createrun:convertFilenameswalked every local catalog instead of the one named on the command lineexport:playlistnever created its output directory and kept going anyway, failing a second time trying to write the playlist fileexport:albumArtwalked every catalog on the server instead of the one named on...
7.10.3
Ampache 7.10.3
Fixed (7.10.3)
- Localplay access was never actually checked (any user passed) and Subsonic
jukeboxControlchecked 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/setStarshared the API'srate/flagbugs, since both call into the sameRating/Userflagmodels: 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
- Private playlists and searches leaked through several endpoints: web smartlist,
- WebDAV login accepted a disabled account and never bound the authenticated user, so
catalog_filter_groupwasn'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_versionreopened an API version the admin had disabled, bypassing theapi_enable_3..api_enable_6check. NOTE the same fix landed in Ampache8, which serves every version as well stats: Theuser_id/usernameoverride handed back another user'sstreamtokenembedded 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 wellrate: An out-of-range value (e.g.127) was stored as-is instead of being clamped to 0-5, and repeatedly rating0could drain an object's popularity weight below0. NOTE the same fix landed in Ampache8, which serves every version as welltimeline,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_idwithfilter=recentignored theirallow_personal_info_recentopt-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
- Naming another user's
- 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_detailsreturned server-wide catalog counts scoped to user id0when 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
dateparameter 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
- A future
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}/groupsdelivers{search_type}asfilter, but the method only readtype, so it always searchedallregardless of the path. NOTE the same fix landed in Ampache8, which serves this version as well
- The REST route
- REST (ALL)
- A REST call's path-derived
type(e.g.playlist, fromplaylists/{playlist_id}/{add|remove}/) always overwrote atypesent 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
- A REST call's path-derived
friends_timeline(API3, API4)- Returned the caller's own activity instead of the activity of the users they follow, calling
getActivities()instead ofgetFriendsActivities(). NOTE the same fix landed in Ampache8, which serves these versions as well
- Returned the caller's own activity instead of the activity of the users they follow, calling
8.1.0
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_modetoguestorallto enable it pow_protectedpicks 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) andpow_ttl pow_exempt_levelwaves trusted users through inallmode;pow_log_failuresrecords what gets blocked- Needs JavaScript and Web Workers: it stops crawlers, not a determined attacker, so pair it with a rate limit
- Off by default; set
- Database 810001
- New
show_composerpreference (off by default) for a Composer column on playlist media and Song rows
- New
- Database 810010
- New
folder.timecolumn with the summed duration of everything below each folder, subfolders included, rolled up the same way astotal_count/total_skip; the API folder browse response now reports it astimeon the browsed folder and on each item in its contents
- New
- 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
Timecolumn on folder browsesphp bin/cli run:updateCatalog -sskips 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, oradmin/catalog.php?action=garbage_collect) to force a refresh
- A
Timecolumn on playlist browses, sortable vialast_duration - Config version 99
- New
album_grouping_fieldsoption controlling which fields decide whether two songs share an album row, so pressings that only differ bybarcode/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)
nameandyearcan be dropped from the list too, though doing so can merge albums you didn't mean to mergecatalogis 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)
- New
- 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_blankalbumalways 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
brandingsection 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
Uploadedcolumn 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.enabledandartist.enabled, carrying the name and the promisesong.enabledalready had, so a release can be withdrawn without deleting it and losing its playlist entries, ratings and play history - Set from a
Statemenu 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
Enabledsearch 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
- New
Changed (8.1.0)
- Database 810002
- Covering index on
imagefor the art cache lookup, so it can be answered from the index alone; drops the now-redundantobject_idkey it replaces
- Covering index on
- 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_seenwrite, no serialized-session rewrite, and a cookie-less request (a crawler, a link preview) no longer leaves a session row behind Session::extendno longer rewrites the expire column on every request- Visitors who never queue anything no longer get a
tmp_playlistrow, dashboard and mashup boxes no longer write atmp_browserow 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
.moeach 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_blankalbumis 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.apikeycarries 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.confandapache-site.confgained 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_timelineAPI 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...
8.0.1
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:explicitand 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_TYPEvalue (e.g.transcode_mp3 = "falsed") no longer counts as enabling transcoding; onlyallowed,requiredandfalseare accepted and anything else is logged and treated asfalse - Invalid
transcode_TYPEvalues 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_mapandsong_mapcarried the most, and grow with the catalog
- Database 801002
- Convert
stream_beautiful_urlto an Admin preference
- Convert
- Garbage collection actions (
admin/catalog.php?action=garbage_collectandphp bin/cli run:updateCatalog -t) now runSession::garbage_collection(), cleaning uptmp_playlist/tmp_playlist_data,stream_playlist,song_previewand 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_INCREMENTonstream_playlist,playlist_data,tmp_playlistandtmp_playlist_dataafterwards, 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 onerun:computeCacheandrun: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_daysoption (default0, keep forever); garbage collection prunesdeleted_song/deleted_video/deleted_podcast_episoderows older than this many days
- New
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.phpno 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_preferencesAPI method (and RESTpreferences) 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_timepreference, 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 fromPreference::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-privatefolder next tomusic), 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 usesrandom_bytes()for the full 128 bits- Browse
- A handful of filters (
rating,folder'sid,song'stop50artist match,playlist's smartlist id list) built theirWHERE/INvalue without the surrounding quotesDba::escape()expects; the value is quoted like every other escaped filter now
- A handful of filters (
- The
upload_scriptpost-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 usehash_equals() - Logging in with a
referrerpointing 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 quotedContent-Dispositionfilename on download, letting extra parameters be appended; the character is stripped like the linebreak/comma/semicolon it already strips - The
theme_name/theme_colorpreferences 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_groupalongside the fields the form actually offers, silently reassigning the user's own catalog visibility group; it's stripped from the request likeaccessalready was - The session,
_rememberand_user/_langcookies were missingHttpOnly, 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_matchfilter value reaches SQLREGEXPas-is with no length limit; it's now capped at 100 charac...
- The
7.10.2
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 theuserrequest parameter when the key did not match a user- A request carrying an unknown key was still resolved to whoever the
userparameter named
- A request carrying an unknown key was still resolved to whoever the
- Subsonic
createPlaylistsent with aplaylistIdrewrites that playlist, but unlikeupdatePlaylistit 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
resolutionplayback option was substituted into%RESOLUTION%and handed to a shell unchecked; only a literalWIDTHxHEIGHTis accepted now and anything else falls back to the default qualityis cast to an int before it is used in the bitrate calculation
- The
- 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
folderandfolder_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
Searchtakes 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_urlandheadphones_api_keypreferences 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 usesrandom_bytes()for the full 128 bits- Browse
- A handful of filters (
rating,song'stop50artist match) built theirWHEREvalue without the surrounding quotesDba::escape()expects; the value is quoted like every other escaped filter now
- A handful of filters (
- The
upload_scriptpost-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 usehash_equals() - Logging in with a
referrerpointing 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 quotedContent-Dispositionfilename on download, letting extra parameters be appended; the character is stripped like the linebreak/comma/semicolon it already strips - The
theme_name/theme_colorpreferences 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_groupalongside the fields the form actually offers, silently reassigning the user's own catalog visibility group; it's stripped from the request likeaccessalready was - The session,
_rememberand_user/_langcookies were missingHttpOnly, 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 sameCore::generate_random_key()the login CSRF token and web session already relied on - Browse
- The
regex_match/regex_not_matchfilter value reaches SQLREGEXPas-is with no length limit; it's now capped at 100 characters against a catastrophic-backtracking pattern
- The
- A share's secret was compared with
!=instead of a constant-time comparison, so two "magic hash" values (0efollowed only by digits) could match each other regardless of their actual digits; it now useshash_equals() - Database
- Downgrading from Ampache8 removes the
broadcast_private,show_moodandhide_moodspreferences instead of leaving them in the preferences list headphones_api_url/headphones_api_keyare raised to Manager level for existing installs
- Downgrading from Ampache8 removes the
8.0.0
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
oidcauth method; add it toauth_methodsto enable it (keepmysqlso 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_claimclaim and provisioned through the existingauto_create/auto_user/external_auto_updatesettings, 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_redirectat the provider'send_session_endpointto sign out of the provider as well
- New
- Folder Browsing
Folderdomain/model for browsing the catalog as a virtual folder tree- New
show_folderpreference to show/hide the "Folders" link in the sidebar
- Play history consolidation
- New
stats_consolidate_thresholdconfig option; the number of days of detailed play history to keep inobject_count(0, the default, disables consolidation) - New
cleanup:consolidateStatsCLI command aggregates older plays intoobject_count_summaryand moves the detail rows toobject_count_archive; dry-run unless-eis given - New
cleanup:restoreStatsCLI command puts the archived detail back and regenerates thealbum,album_disk,artistandpodcastrows from it - Nothing is discarded: media rows keep their exact
date,agentand location for streams, skips and downloads, so a consolidate/restore cycle is lossless - Play counts,
playedflags 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
- New
- Mini player
- New
/m/page showing only thehomecategory plugins and the web player, for small screens and simple accounts - New
mini_playerpreference 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 playerbutton on the login form, next toRegisterandLost Password, to land there after logging in
- New
- Multi select
- New
Multi-Selectbrowse option in theViewmenu 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 andShift+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_typesincludessongand batch download is permitted batch.phpaccepts a comma separatedidlist, so one zip can hold the medias of several items instead of only one
- New
- Broadcasting is documented and easier to get working
- New
docs/BROADCAST.mdcovers the whole feature: the config, thebin/cli run:websocketserver it needs, reverse proxy and TLS, and how to test each step - New
docs/examples/ampache_websocket.servicesystemd 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 plainws://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 inwebsocket_address; a mismatch was refused with403that never appeared in the interface run:broadcast(a UPnP announcement) andrun:websocket(broadcasting) now say which is which in their help- New
broadcast_privatepreference (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
- New
- Song previews work again
- New
iTunesandDeezerplugins 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
- New
- 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_8preference to enable/disable API v8 responses per user - New database tables
folderandfolder_map - New database tables
object_count_summaryandobject_count_archive folderadded to theobject_typeenum on several tables (cache_object_count,cache_object_count_run,image,object_count, and others)- New
user.subsonic_secretcolumn holding the per-user Subsonic password - New database tables
collectionandcollection_map - New database tables
playlist_folderandplaylist_folder_map, holding a private per-user tree that organises playlists, smartlists and collections - New maintained
last_playedcolumn onalbum,album_disk,artist,podcast,podcast_episode,songandvideo, written on the same statement that increments the play counter and backfilled from the existing play history (live counts, archived detail and consolidated summaries) collectionadded to theobject_typeenum onimage,object_count,cache_object_count,cache_object_count_run,object_count_summaryandobject_count_archive, so a collection carries its own art and play statisticscollectionadded to theobject_typeenum onratinganduser_flag, so a collection can be rated and flagged- New
position_ms,playback_rateandstatecolumns onnow_playing, holding what an OpenSubsonic client reports throughreportPlayback - New
artist.lastfm_urlcolumn keeping the last.fm page url with the rest of the cached artist info label_assogains a nullablealbumcolumn and itsartistcolumn becomes nullable, so a label can be associated with an album as well as an artist- New
song_data.bpmcolumn holding the tagged beats per minute
- New
- Subsonic
- OpenSubsonic implementation audited against the published specification on 2026-08-07; the audited build is committed as
docs/openapi-opensubsonic.jsonand pinned by a test so a refreshed copy prompts a re-audit instead of drifting silently - New
transcodingextension:getTranscodeDecision(POST, with the client's playback capabilities as a JSON body) reports whether a file can be played as-is, andgetTranscodeStreamserves the result. The decision is derived from the same transcode settings that serve the bytes, and itstranscodeParamstoken is signed withsecret_keyso a client cannot choose its own output format ...
- OpenSubsonic implementation audited against the published specification on 2026-08-07; the audited build is committed as