From d512a285857495dadef526970a858c2ec6360519 Mon Sep 17 00:00:00 2001 From: lachlan Date: Tue, 23 Apr 2024 12:37:05 +1000 Subject: [PATCH 1/3] Update PlayerMethod.php make type and state optional --- .../Api/Method/Api4/RecordPlay4Method.php | 2 +- .../Api/Method/Api5/RecordPlay5Method.php | 2 +- src/Module/Api/Method/PlayerMethod.php | 28 +++++++++++-------- src/Module/Api/Method/RecordPlayMethod.php | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Module/Api/Method/Api4/RecordPlay4Method.php b/src/Module/Api/Method/Api4/RecordPlay4Method.php index a5f95627e2..a573d5917b 100644 --- a/src/Module/Api/Method/Api4/RecordPlay4Method.php +++ b/src/Module/Api/Method/Api4/RecordPlay4Method.php @@ -47,7 +47,7 @@ final class RecordPlay4Method * * id = (integer) $object_id * user = (integer|string) $user_id OR $username //optional - * client = (string) $agent //optional + * client = (string) $agent Default: 'api' //optional * date = (integer) UNIXTIME() //optional */ public static function record_play(array $input, User $user): bool diff --git a/src/Module/Api/Method/Api5/RecordPlay5Method.php b/src/Module/Api/Method/Api5/RecordPlay5Method.php index 2c018ff28f..389ef36b6c 100644 --- a/src/Module/Api/Method/Api5/RecordPlay5Method.php +++ b/src/Module/Api/Method/Api5/RecordPlay5Method.php @@ -48,7 +48,7 @@ final class RecordPlay5Method * * id = (integer) $object_id * user = (integer|string) $user_id OR $username //optional - * client = (string) $agent //optional + * client = (string) $agent Default: 'api' //optional * date = (integer) UNIXTIME() //optional */ public static function record_play(array $input, User $user): bool diff --git a/src/Module/Api/Method/PlayerMethod.php b/src/Module/Api/Method/PlayerMethod.php index 051fdcfa4f..fef92ee171 100644 --- a/src/Module/Api/Method/PlayerMethod.php +++ b/src/Module/Api/Method/PlayerMethod.php @@ -46,30 +46,27 @@ final class PlayerMethod /** * player - * MINIMUM_API_VERSION=6.3.2 + * MINIMUM_API_VERSION=6.4.0 * * Inform the server about the state of your client. (Song you are playing, Play/Pause state, etc.) * Return the `now_playing` state when completed * * filter = (integer) $object_id - * type = (string) $object_type ('song', 'podcast_episode', 'video') - * state = (string) 'play', 'stop' + * type = (string) $object_type ('song', 'podcast_episode', 'video'), DEFAULT 'song'//optional + * state = (string) 'play', 'stop', DEFAULT 'play' //optional * time = (integer) current song time in whole seconds, DEFAULT 0 //optional - * client = (string) $agent //optional + * client = (string) $agent, DEFAULT 'api' //optional */ public static function player(array $input, User $user): bool { - if (!Api::check_parameter($input, array('filter', 'type', 'state'), self::ACTION)) { + if (!Api::check_parameter($input, array('filter'), self::ACTION)) { return false; } ob_end_clean(); $object_id = (int)$input['filter']; - $type = $input['type']; - $state = $input['state']; + $type = $input['type'] ?? 'song'; - // validate client string or fall back to 'api' - $agent = scrub_in((string)($input['client'] ?? 'api')); // confirm the correct data if (!in_array(strtolower($type), array('song', 'podcast_episode', 'video'))) { @@ -78,15 +75,15 @@ public static function player(array $input, User $user): bool return false; } - if (!in_array(strtolower($state), array('play', 'pause', 'stop'))) { + + $state = $input['state'] ?? 'play'; + if (!in_array(strtolower($state), array('play', 'stop'))) { /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ Api::error(sprintf('Bad Request: %s', $state), ErrorCodeEnum::BAD_REQUEST, self::ACTION, 'state', $input['api_format']); return false; } - $time = time(); - $position = (array_key_exists('time', $input) && is_numeric(scrub_in((string) $input['time']))) ? (int) scrub_in((string) $input['time']) : 0; //optional $className = ObjectTypeToClassNameMapper::map($type); if ($className === $type || !$object_id) { /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ @@ -104,6 +101,13 @@ public static function player(array $input, User $user): bool return false; } + $time = time(); + $position = (array_key_exists('time', $input) && is_numeric(scrub_in((string) $input['time']))) + ? (int) scrub_in((string) $input['time']) + : 0; + // validate client string or fall back to 'api' + $agent = scrub_in((string)($input['client'] ?? 'api')); + if ($state === 'play') { // make sure the now_playing state is set Stream::garbage_collection(); diff --git a/src/Module/Api/Method/RecordPlayMethod.php b/src/Module/Api/Method/RecordPlayMethod.php index 413d09e7dd..1c9335c65c 100644 --- a/src/Module/Api/Method/RecordPlayMethod.php +++ b/src/Module/Api/Method/RecordPlayMethod.php @@ -49,7 +49,7 @@ final class RecordPlayMethod * * id = (integer) $object_id * user = (integer|string) $user_id OR $username //optional - * client = (string) $agent //optional + * client = (string) $agent Default: 'api' //optional * date = (integer) UNIXTIME() //optional */ public static function record_play(array $input, User $user): bool From 69370c593f5cdb1a5f10b90e6dc0019d6f0d0c31 Mon Sep 17 00:00:00 2001 From: lachlan Date: Tue, 23 Apr 2024 12:40:14 +1000 Subject: [PATCH 2/3] Update CHANGELOG.md --- docs/CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index cb86d0800b..a3f7264117 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -72,6 +72,11 @@ These searches will now use to rules for that object type and then return the so * download: add `bitrate` parameter * playlists: add `include` parameter (**note** this can be massive and slow when searches are included) +### Changed + +* API6 + * Do not translate API `errorMessage` strings [ampache.org](https://ampache.org/api/api-errors) + ### Fixed * ALL @@ -84,11 +89,6 @@ These searches will now use to rules for that object type and then return the so * has_art property missing from songs and albums * playlist_add: couldn't add a single item -### Removed - -* API6 - * Do not translate API `errorMessage` strings [ampache.org](https://ampache.org/api/api-errors) - ## Ampache 6.3.1 ### Added From 590522533de3f33370f088ab454c9ff400467472 Mon Sep 17 00:00:00 2001 From: lachlan Date: Tue, 23 Apr 2024 13:19:12 +1000 Subject: [PATCH 3/3] api docs --- docs/API-Errors.md | 8 +- docs/API-JSON-methods.md | 48 +++++++++--- docs/API-XML-methods.md | 39 +++++++++- docs/API-advanced-search.md | 10 +-- docs/API-media-methods.md | 150 ++++++++++++++++++++++++++++++++++++ docs/API.md | 39 ++++++---- 6 files changed, 261 insertions(+), 33 deletions(-) create mode 100644 docs/API-media-methods.md diff --git a/docs/API-Errors.md b/docs/API-Errors.md index 2d9edfca39..266ec1e9ac 100644 --- a/docs/API-Errors.md +++ b/docs/API-Errors.md @@ -6,14 +6,16 @@ description: "API documentation" Ampache's API errors are loosely based around the HTTP status codes. All errors are returned in the form of an XML/JSON Document however the string error message provided is translated into the language of the Ampache server in question. All services should only use the code value. -For Ampache5 error codes are changing and expanding on the information available to the user/client/application that caused the error. +For API6 error codes are changing and expanding on the information available to the user/client/application that caused the error. -An Ampache5 error has the following parts: +An API6 error has the following parts: * errorCode: numeric code * errorAction: method that caused the error * errorType: further information such as the type of data missing or access level required -* errorMessage: translated error message +* errorMessage: error message (US English string Ampache 6.4.0+ **OR** Translated string Ampache 6.0.0 => 6.3.1) + +**NOTE** Prior to Ampache 6.4.0 the API errorMessage text was translated into the server locale. All future versions will not translate the string. ## Rules Regarding errors diff --git a/docs/API-JSON-methods.md b/docs/API-JSON-methods.md index c417302930..2c3ada475f 100644 --- a/docs/API-JSON-methods.md +++ b/docs/API-JSON-methods.md @@ -14,6 +14,9 @@ Binary methods will also return: * HTTP 400 responses for a bad or incomplete request * HTTP 404 responses where the requests data was not found +* HTTP 416 responses where the stream is unable to return the requested content-range + +For information about about how playback works and what a client can expect from Ampache check out [API Media Methods](https://ampache.org/api/api-media-methods) ## Auth Methods @@ -170,7 +173,7 @@ Register as a new user if allowed. (Requires the username, password and email.) |------------|---------|-----------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | NO | -| 'email' | string | e.g. user@gmail.com | NO | +| 'email' | string | e.g. `user@gmail.com` | NO | | 'fullname' | string | | YES | * return object @@ -1694,7 +1697,35 @@ Get what is currently being played by all users. "error": "" ``` -[Example](https://raw.githubusercontent.com/ampache/python3-ampache/api6/docs/xml-responses/now_playing.xml) +[Example](https://raw.githubusercontent.com/ampache/python3-ampache/api6/docs/xml-responses/now_playing.json) + +### player + +Inform the server about the state of your client. (Song you are playing, Play/Pause state, etc.) + +Return the `now_playing` state when completed + +| Input | Type | Description | Optional | +|----------|---------|------------------------------------------------------|---------:| +| 'filter' | string | $object_id currently playing/stopping | NO | +| 'type' | string | `song`, `video`, `podcast_episode` (Default: `song`) | YES | +| 'state' | string | `play`, `stop` (Default: `play`) | YES | +| 'time' | integer | current play time in whole seconds (Default: 0) | YES | +| 'client' | string | agent/client name | YES | + +* return array + +```JSON +"now_playing": [] +``` + +* throws object + +```JSON +"error": "" +``` + +[Example](https://raw.githubusercontent.com/ampache/python3-ampache/api6/docs/xml-responses/player.json) ### playlists @@ -2371,21 +2402,21 @@ Each type is a grouping of object types so allow single search calls to be made * album * artist -song_artist +* song_artist * song * album * song_artist -album_artist +* album_artist * song * album * album_artist -podcast +* podcast * podcast * podcast_episode -video +* video * video | Input | Type | Description | Optional | @@ -2398,7 +2429,6 @@ video | 'offset' | integer | Return results starting from this index position | YES | | 'limit' | integer | Maximum number of results to return | YES | - * return array ```JSON @@ -2992,7 +3022,7 @@ Create a new user. (Requires the username, password and email.) |------------|---------|-----------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | NO | -| 'email' | string | e.g. user@gmail.com | NO | +| 'email' | string | e.g. `user@gmail.com` | NO | | 'fullname' | string | | YES | | 'disable' | boolean | `0`, `1` | YES | | 'group' | integer | Catalog filter group, default = 0 | YES | @@ -3047,7 +3077,7 @@ Update an existing user. |---------------------|---------|------------------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | YES | -| 'email' | string | e.g. user@gmail.com | YES | +| 'email' | string | e.g. `user@gmail.com` | YES | | 'fullname' | string | | YES | | 'website' | string | | YES | | 'state' | string | | YES | diff --git a/docs/API-XML-methods.md b/docs/API-XML-methods.md index 49da3884cc..e924133c35 100644 --- a/docs/API-XML-methods.md +++ b/docs/API-XML-methods.md @@ -14,6 +14,9 @@ Binary methods will also return: * HTTP 400 responses for a bad or incomplete request * HTTP 404 responses where the requests data was not found +* HTTP 416 responses where the stream is unable to return the requested content-range + +For information about about how playback works and what a client can expect from Ampache check out [API Media Methods](https://ampache.org/api/api-media-methods) ## Auth Methods @@ -180,7 +183,7 @@ Register as a new user if allowed. (Requires the username, password and email.) |------------|---------|-----------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | NO | -| 'email' | string | e.g. (user@gmail.com) | NO | +| 'email' | string | e.g. `user@gmail.com` | NO | | 'fullname' | string | | YES | * return @@ -1750,6 +1753,36 @@ Get what is currently being played by all users. [Example](https://raw.githubusercontent.com/ampache/python3-ampache/api6/docs/xml-responses/now_playing.xml) +### player + +Inform the server about the state of your client. (Song you are playing, Play/Pause state, etc.) + +Return the `now_playing` state when completed + +| Input | Type | Description | Optional | +|----------|---------|------------------------------------------------------|---------:| +| 'filter' | string | $object_id currently playing/stopping | NO | +| 'type' | string | `song`, `video`, `podcast_episode` (Default: `song`) | YES | +| 'state' | string | `play`, `stop` (Default: `play`) | YES | +| 'time' | integer | current play time in whole seconds (Default: 0) | YES | +| 'client' | string | agent/client name | YES | + +* return + +```XML + + + +``` + +* throws + +```XML + +``` + +[Example](https://raw.githubusercontent.com/ampache/python3-ampache/api6/docs/xml-responses/player.xml) + ### playlists This returns playlists based on the specified filter @@ -3044,7 +3077,7 @@ Create a new user. (Requires the username, password and email.) |------------|---------|-----------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | NO | -| 'email' | string | e.g. (user@gmail.com) | NO | +| 'email' | string | e.g. `user@gmail.com` | NO | | 'fullname' | string | | YES | | 'disable' | boolean | `0`, `1` | YES | | 'group' | integer | Catalog filter group, default = 0 | YES | @@ -3103,7 +3136,7 @@ Update an existing user. |---------------------|---------|------------------------------------------|---------:| | 'username' | string | $username | NO | | 'password' | string | hash('sha256', $password) | YES | -| 'email' | string | e.g. (user@gmail.com) | YES | +| 'email' | string | e.g. `user@gmail.com` | YES | | 'fullname' | string | | YES | | 'website' | string | | YES | | 'state' | string | | YES | diff --git a/docs/API-advanced-search.md b/docs/API-advanced-search.md index bd44815a98..b39be493c1 100644 --- a/docs/API-advanced-search.md +++ b/docs/API-advanced-search.md @@ -19,12 +19,12 @@ This is passed as a type argument and will only return this object in results * [song](https://ampache.org/api/advanced-search/song-advanced-search) * [album](https://ampache.org/api/advanced-search/album-advanced-search) * [artist](https://ampache.org/api/advanced-search/artist-advanced-search) -* song_artist (**NOTE** same rules as artist but only returns song artists) (**5.5.2+**) -* album_artist (**NOTE** same rules as artist but only returns album artists) (**5.5.2+**) +* song_artist (**NOTE** same rules as artist but only returns song artists) +* album_artist (**NOTE** same rules as artist but only returns album artists) * [label](https://ampache.org/api/advanced-search/label-advanced-search) * [playlist](https://ampache.org/api/advanced-search/playlist-advanced-search) -* [podcast](https://ampache.org/api/advanced-search/podcast-advanced-search) (**Ampache 5.5.0+**) -* [podcast_episode](https://ampache.org/api/advanced-search/podcast-episode-advanced-search) (**Ampache 5.5.0+**) +* [podcast](https://ampache.org/api/advanced-search/podcast-advanced-search) +* [podcast_episode](https://ampache.org/api/advanced-search/podcast-episode-advanced-search) * [genre](https://ampache.org/api/advanced-search/genre-advanced-search) * tag (*Alias of genre) * [user](https://ampache.org/api/advanced-search/user-advanced-search) @@ -161,7 +161,7 @@ Searching 'anywhere' searches song title, song filename, song genre, album title | possible_duplicate | Possible Duplicate | is_true | song, album, artist | | possible_duplicate_album | Possible Duplicate Albums | is_true | song, album, artist | | username | Username | text | user | -| category | Category | text | label, genre | +| category | Category | text | label, genre | ### Available operator values diff --git a/docs/API-media-methods.md b/docs/API-media-methods.md new file mode 100644 index 0000000000..d49913c12b --- /dev/null +++ b/docs/API-media-methods.md @@ -0,0 +1,150 @@ +--- +title: "API6 Media Methods" +metaTitle: "API6 Media Methods" +description: "API documentation" +--- + +It can be confusing about what Ampache does and what you need to do as an API client. + +This page will document a few things about how playback works and what a client can expect from Ampache. + +There are 2 binary data methods used for basic playback function: + +* stream [json](https://ampache.org/api/api-json-methods#stream) and [xml](https://ampache.org/api/api-xml-methods#stream) +* download [json](https://ampache.org/api/api-json-methods#download) and [xml](https://ampache.org/api/api-xml-methods#download) + +And there are 3 helper functions which allow you to manage playback history and state but do not return media. + +* scrobble [json](https://ampache.org/api/api-json-methods#scrobble) and [xml](https://ampache.org/api/api-xml-methods#scrobble) +* record_play [json](https://ampache.org/api/api-json-methods#record_play) and [xml](https://ampache.org/api/api-xml-methods#record_play) +* player (Ampache 6.4.0+) [json](https://ampache.org/api/api-json-methods#player) and [xml](https://ampache.org/api/api-xml-methods#player) + +Finally, you can also call the function now_playing to get details about what your user is currently stremaing. ([json](https://ampache.org/api/api-json-methods#now_playing) and [xml](https://ampache.org/api/api-xml-methods#now_playing)) + +## Explaining stream + +Stream is used to play a song in the same way as the Webplayer. + +The URL generated by stream will match the URL property in all song object repsonses + +```JSON +"url": "https:\/\/music.com.au\/play\/index.php?ssid=cfj3f237d563f479f5223k23189dbb34&type=song&oid=115&uid=4&transcode_to=mp3&player=api&name=Chi.Otic%20-%20Are%20we%20going%20Crazy.mp3", +``` + +```XML + +``` + +When you play a song; `stream` will: + +* Record a play in the database which is recorded as a `stream` +* If you stream a new song too quickly the last song will be marked as `skip` +* Play count is incremented **UP** for a stream and back **DOWN** for a skip + +It is very important to note that play history is compared to the client string. You can play a song on a browser, start a subsonic stream and then an api client stream right after and all 3 plays will be recorded as streams because they are different clients. + +## Explaining download + +A download is not considered a stream and does not go through the same stat checks. + +When you `download` a song: + +* Record the action as a `download` +* A download does not perform skip checks and ignores any recent play history +* Play counts are **NOT** incremented. + +Download is used for caching files without the server thinking you've played 40 songs in 3 minutes. + +Use the helper functions when playing downloads so you can informa the server when you actually play the files you download. + +## The Ampache media playback process + +Stat checks happen every time you call a `stream` or `download` **URL** (including part stream content-range calls) + +e.g. `https://music.com.au/play/index.php?ssid=cfj3f237d563f479f5223k23189dbb34&type=song&oid=54&uid=4&player=api&name=Synthetic%20-%20Red-GreenSmoke.mp3` + +When you use the API `stream`/`download` calls you are redirected to the play_url for the object. (Ampache calls them play_url's because they redirect to the `/play/` directory of the Ampache site) + +The checks are there to stop duplicate stats being recorded or spam from repeated calls to the same URL. + +If you are only using the `stream` action, Ampache will perform these checks for you. + +If you cache your files locally with `download` or are using a different client you can use the helper functions to notify the server. + +The Ampache config file also allows you configure what you consider to be a skip. + +The `skip_timer` setting is what the server uses to decide whether the new play is going to override the last play. + +```TXT +; Skip Timer Threshold +; This allows custom times to decide when a track is skipped +; Allows an integer to denote seconds, or a float to denote percentage +; POSSIBLE VALUES: +; 20 = 20 seconds. +; 0.3 = 30% +; DEFAULT: 20 +;skip_timer = 20 +``` + +Example, when using the default settings: + +* You stream TRACK1 +* You start to stream TRACK2 within the 10 seconds after TRACK1 started +* TRACK1 will change to a skip +* TRACK2 will be marked as your current `now_playing` track. + +## Explaining scrobble + +The `scrobble` and `record_play` methods are used for recording plays from saved information/data. + +They're generally not used during playback as the `stream` action manages that process. + +Scrobble uses parameters similar to how the Last.fm API works. (Which is why it's called scrobble.) + +The idea is that if you are using a different player where you aren't able to get the object id you can scrobble to your Ampache server. + +Scrobble is useful for plugins in different music players as an alternative to Last.fm or Libre.fm clients. + +Example streaming plugin for rhythmbox written a few years ago. [rhythmbox-ampache-fm](https://github.com/lachlan-00/rhythmbox-ampache-fm) + +## Explaining record_play + +`record_play` does the same thing as `scrobble` but only requires the object id of the song instead of searching by string data. + +This is useful with playing cached/downloaded songs from an API client that has access to the id. + +If you are playing a downloaded file or a cached version of the file there is no `stream` or `download` action happening. + +To tell the server what you're doing and to record a stream you would call record_play when you start a track. + +Example: + +* I cache song with the id 1240 using a `download` action +* I play the mp3 that was saved in my file cache +* That mp3 play is **NOT** a `stream` so I use record_play to set the stream in the database + +## Explaining player + +There is a new method for Ampache 6.4.0+ called player. [json](https://ampache.org/api/api-json-methods#player) and [xml](https://ampache.org/api/api-xml-methods#player) + +Player is all about giving the server an active status of what the client is doing. + +Player does a bit more than scrobble and record_play allowing me to do a few more things + +* Support for more media types. (`podcast_episode` and `video` objects instead of just songs) +* Update `now_playing` data (remove on stop add it back on play) +* Shift last item play time on resumption of playback. (e.g. i pause a song at 20 seconds for a day and restart the song. the item will shift to NOW - 20 seconds as i haven't played any other song.) + +It's similar to `scrobble`/`record_play` but the play/stop parameter gives me a bit more information about what you're doing + +## Final thoughts + +Hopefully that helps you understand what happens when you are streaming or downloiading form Ampache servers. + +The idea is that you shouldn't have to think about anything when you `stream`. The server will do all the checks and updates for you. + +When you `download`, you need to tell the server that you're playing a cached file. + +Use `scrobble`/`record_play`/`player` to tell the server what you're doing. + +Once you tell the server that you're playing with `stream`/`scrobble`/`record_play`/`player` methods the server will update the play status/history depending on your your data and current playback status. diff --git a/docs/API.md b/docs/API.md index 6f5d5d34ea..9a87f2aa7d 100644 --- a/docs/API.md +++ b/docs/API.md @@ -33,7 +33,7 @@ After each release, a documentation page will be created to allow pruning old fe Ampache supports the last major release of each API version. You can also check out the [past releases](https://ampache.org/api/versions/) page for some historical detail but **DO NOT** use these pages as a guide for API development. -## Changelog API develop +## API Changelog Take a look at the [API Changelog](https://ampache.org/api/api-changelog) to keep an eye on changes between versions @@ -222,8 +222,8 @@ All Auth methods return HTTP 200 responses * handshake * goodbye * ping -* register **Api6** -* lost_password **Api6.1** +* register +* lost_password **Ampache 6.1.0+** ### Non-Data Methods @@ -246,17 +246,18 @@ All Data methods return HTTP 200 responses * artist * artist_albums * artist_songs +* bookmark **Ampache 6.1.0+** * bookmark_create * bookmark_delete * bookmark_edit -* browse **Api6** +* browse * catalogs * catalog * catalog_action -* catalog_add **Api6** -* catalog_delete **Api6** +* catalog_add +* catalog_delete * catalog_file -* catalog_folder **Api6** +* catalog_folder * deleted_podcast_episodes * deleted_songs * deleted_videos @@ -272,6 +273,7 @@ All Data methods return HTTP 200 responses * get_bookmark * get_indexes * get_similar +* index **Ampache 6.3.0+** * labels * label * label_artists @@ -279,14 +281,17 @@ All Data methods return HTTP 200 responses * licenses * license * license_songs -* list **Api6** (Replaces get_indexes) +* list (Replaces get_indexes) * live_streams * live_stream -* live_stream_create **Api6** -* live_stream_delete **Api6** -* live_stream_edit **Api6** +* live_stream_create +* live_stream_delete +* live_stream_edit +* now_playing **Ampache 6.3.1+** +* player **Ampache 6.4.0+** * playlists * playlist +* playlist_add **Ampache 6.3.0+** * playlist_add_song * playlist_create * playlist_delete @@ -308,6 +313,8 @@ All Data methods return HTTP 200 responses * rate * record_play * scrobble +* search_group **Ampache 6.3.0+** +* search **Ampache 6.3.0+** (alias for [advanced_search](https://ampache.org/api/api-advanced-search)) * search_songs * shares * share @@ -330,9 +337,11 @@ All Data methods return HTTP 200 responses * user * user_create * user_delete -* user_edit **Api6** (Replaces user_update) -* user_update +* user_edit (Replaces user_update) +* user_playlists **Ampache 6.3.0+** * user_preference +* user_smartlists **Ampache 6.3.0+** +* user_update * videos * video @@ -340,12 +349,16 @@ All Data methods return HTTP 200 responses All binary methods will not return XML/JSON responses. they will either return the requested file/data or an HTTP error code. +For information about about how playback works and what a client can expect from Ampache check out [API Media Methods](https://ampache.org/api/api-media-methods) + @return (HTTP 200 OK) @throws (HTTP 400 Bad Request) @throws (HTTP 404 Not Found) +@throws (HTTP 416 Range Not Satisfiable) + * download * get_art * stream