GithubHelp home page GithubHelp logo

rain0r / ampd Goto Github PK

View Code? Open in Web Editor NEW
50.0 50.0 5.0 8.95 MB

A web-based MPD client.

License: GNU General Public License v3.0

TypeScript 51.75% HTML 17.33% Java 28.86% SCSS 1.64% JavaScript 0.42%
angular java mpd mpd-client music-player spring-boot typescript websockets

ampd's People

Contributors

anviar avatar dependabot[bot] avatar rain0r avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ampd's Issues

Browse => Album (empty)

Hi,
everything works fine except the album page which is empty.
I'm using mpd version 0.21.5-3 (raspberry), openjdk 11.0.15 2022-04-19 and ampd-1.4.5.

For local music libraries, queue tab cannot load album art covers from music file's directory

Hi, thanks for sharing this client. Playback and library scanning work like a charm! However I want to report two issues I'm having regarding the cover art support. I would like to help as well, but first things first; I think acknowledging the root of the problem is top priority.

A little filesystem context
I'm running MPD and this client/server stack in a Win10 machine. My music library resides looks like this Music/${audio-format}/${album-folder}/${music-file} and each album folder name is formatted like ${artist} [${year} ${release-type}] ${release-name}/. Each release-name folder may have a front.jpg file acting like the sole cover art.

I run the server with most default settings like so java -jar "-Dmpd.music.directory=F:/Benjamin/Music" .\ampd-1.3.4.jar

The problems

  1. If I play my music files, their local cover art file is ignored and instead the server always tries to fetch another one from the cache, or the web and then caching it that's enabled. Gotta say, that doesn't always work or even matches the album. However when I go browsing each folder, the aforementioned cover art file is correctly read and displayed in the client web interface with no issue whatsoever.

  2. If the album or band name contains symbols that are forbidden to filenames, the server it fails to cache the cover art at all. Take for example, post-punk band DEVO's debut album "Q: Are We Not Men? A: We Are Devo!" and you'll surely understand the issue. The raised exception goes as follows:

2021-10-25 00:22:24.942 ERROR 17328 --- [0.0-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.nio.file.InvalidPathException: Illegal char <:> at index 51: C:\Users\Benjamin\.local\share\ampd\covers\a_DEVO_Q: Are We Not Men? A: We Are Devo!.jpg] with root cause

java.nio.file.InvalidPathException: Illegal char <:> at index 51: C:\Users\Benjamin\.local\share\ampd\covers\a_DEVO_Q: Are We Not Men? A: We Are Devo!.jpg
        at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182) ~[na:na]
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) ~[na:na]
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) ~[na:na]
        at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92) ~[na:na]
        at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229) ~[na:na]
        at java.base/java.nio.file.Path.of(Path.java:147) ~[na:na]
        at java.base/java.nio.file.Paths.get(Paths.java:69) ~[na:na]
        at org.hihn.ampd.server.service.CoverCacheService.buildCacheFullPath(CoverCacheService.java:209) ~[ampd-1.3.4.jar:1.3.4]
        at org.hihn.ampd.server.service.CoverCacheService.loadCover(CoverCacheService.java:94) ~[ampd-1.3.4.jar:1.3.4]
        at org.hihn.ampd.server.service.CoverService.findAlbumCoverForTrack(CoverService.java:74) ~[ampd-1.3.4.jar:1.3.4]
        at org.hihn.ampd.server.controller.CoverController.findAlbumCoverForTrack(CoverController.java:57) ~[ampd-1.3.4.jar:1.3.4]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.8.jar:5.3.8]
        [...]

Hope this can be made sense of. And again, I'd be glad to help if it's not overly complicated. I have a couple ideas on how to fix these, but obviously a lot of questions to make before that.

Reordering playing queue items

Hello,

Thanks for the neat project!

A feature request: it would be nice if you could reorder the items in the playing queue just like you can from other MPD clients.

mpd server with password

Hello,

i wanted to ask if you intend to support mpd-servers with passwords ?

I looked into your code and the underlying code base that you are using and it should be doable.

Personally my understanding of java is not perfect and I'm more of a beginner.
You should only need to change the code for the mpd builder or ?

So like this:

package org.hihn.ampd.server.config;

import org.bff.javampd.server.MPD;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MpdConfiguration {

  @Value("${mpd.server}")
  private String mpdServer;

  @Value("${mpd.port}")
  private int mpdPort;

  @Value("${mpd.password}")
  private String mpdPassword;

  public MPD mpd() {
    if(mpdPassword equals("")) {
         return new MPD.Builder().server(mpdServer).port(mpdPort).build();
    }
    else{
         return new MPD.Builder().server(mpdServer).port(mpdPort).password(mpdPassword).build():
   }
  }
}

Or am i completely wrong?

with regards

Proposal: Hide volume slider, if volume isn't available (output shout)

Hello,
the angular client shows a -1 % and the ampd service throws an exception if trying to change:

2020-06-05 18:07:30.590 ERROR 2368 --- [boundChannel-25] o.h.a.s.controller.WebSocketController : [52@0] {setvol} problems setting volume

org.bff.javampd.server.MPDConnectionException: [52@0] {setvol} problems setting volume

Maybe hiding or deactivating the volume slider is an option if changing the volume isn't available?

Regards
nowrap

Request: move https and backend configuration to ampd.conf

I have tested ampd for a couple of days now and really like it as an mpd client.

There's just some small usability-issues with ampd:

In my use case, i don't want to run ampd locally (client) but on the same machine that runs mpd, making the controls available to any device on the network. I would very much appreciate the ampd.conf to include parameters for the backend address and https on/off options. As of now, it seems these options need to be set while building (properties in pom.xml), making a custom build necessary. If these parameters were saved in ampd.conf, it would be possible to send them to the browser's storage automatically, so using a rather complicated address like "http://host.name/settings?backend=host.name" would not be necessary anymore.

Also running ampd through a reverse proxy to leverage https, authentication, etc. is pretty complicated in the current state, as a https address can't be passed as URL parameter, due to the fact that there's a mechanism in (filename?) that prefixes it with http anyway.

Any chance to have these options in ampd.conf in the future? Maybe even keep the static values from the build and just override if defined in the ampd.conf?

Another small issue I had when running ampd through a reverse proxy is that I didn't succeed rewriting the paths to serve ampd through a URL like "https://host.name/ampd" because some files seem to be pretty static in their referencing and expect to be found in "/". I guess changing this one would be some trouble, so that's not much of a concern right now.

1.5.8 Browse Albums Error

Just updated from 1.4.7 to 1.5.8 and noticed that I get an error now when I browse by album:

{ "headers": { "normalizedNames": {}, "lazyUpdate": null }, "status": 500, "statusText": "OK", "url": "https://my.server.com/ampd/api/albums", "ok": false, "name": "HttpErrorResponse", "message": "Http failure response for https://my.server.com/ampd/api/albums: 500 OK", "error": { "message": "[5@0] {} Space expected after closing '\"'" } }

2022-12-14 09:52:05.049 ERROR 23539 --- [http-nio-0.0.0.0-8080-exec-10] o.h.a.s.util.error.JsonExceptionHandler  : [5@0] {} Space expected after closing '"'

org.bff.javampd.server.MPDConnectionException: [5@0] {} Space expected after closing '"'
        at org.bff.javampd.server.MPDSocket.sendBytes(MPDSocket.java:232) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.server.MPDSocket.sendCommand(MPDSocket.java:105) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:56) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:39) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.song.MPDSongSearcher.find(MPDSongSearcher.java:75) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.song.MPDSongSearcher.find(MPDSongSearcher.java:70) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.song.MPDSongSearcher.find(MPDSongSearcher.java:58) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.song.MPDSongDatabase.findAlbum(MPDSongDatabase.java:40) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.bff.javampd.song.MPDSongDatabase.findAlbum(MPDSongDatabase.java:35) ~[javampd-7.1.0.jar!/:7.1.0]
        at org.hihn.ampd.server.service.AlbumService.lambda$listAllAlbums$0(AlbumService.java:76) ~[classes!/:1.5.8]
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176) ~[na:na]
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) ~[na:na]
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
        at org.hihn.ampd.server.service.AlbumService.listAllAlbums(AlbumService.java:90) ~[classes!/:1.5.8]
        at org.hihn.ampd.server.service.AlbumService$$FastClassBySpringCGLIB$$e0896bb9.invoke(<generated>) ~[classes!/:1.5.8]
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:54) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:366) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:421) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:64) ~[spring-context-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.23.jar!/:5.3.23]
        at org.hihn.ampd.server.service.AlbumService$$EnhancerBySpringCGLIB$$7f810f9a.listAllAlbums(<generated>) ~[classes!/:1.5.8]
        at org.hihn.ampd.server.controller.AlbumController.listAllAlbums(AlbumController.java:30) ~[classes!/:1.5.8]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:670) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

ps thanks for the update, the new advanced search feature is great!

Please improve search functionality.

The search capabilities in v 1.5.3 are very limited and expose only track search.

IMHO all type based queries should be supported in a favour as described in man mpc

   search <type> <query> [<type> <query>]... - Searches for
          substrings in song tags.  Any number of tag type and query combinations can be specified.  Possible tag types are: artist, album, title, track, name, genre, date,  composer,  performer,  com‐
          ment, disc, filename, or any (to match any tag).

Especially if the music library has a size of several thousand songs – in my case >100k – this is IMHO a very helpful feature.

Custom Port

Is it possible to make ampd listen to a different port than 8080?

Is there merit to making ampd a Volumio/Moode plugin?

First off, great work!

I don't like the Volumio/Moode interfaces. Behind the times compared to yours. I suspect this interface can run on an Rpi. Is there merit to making ampd easily installable on those distros, perhaps like a Volumio plugin? Thanks for your answer :)

Playlist edit results in HTTP 404

Hello,

I'm currently looking for a MPD client that has playlist editing functionality. According to the ampd README there seems to be some functionality implemented. It's not working for me though.

Here's a screenshot using FireFox 107 using the interface:
screenshot_2023-01-16-190521

ampd is running inside a docker container on a Gentoo Linux.

The only relevant entry I see in the logs is the following:

2023-01-16 18:05:10.182  WARN 1 --- [0.0-8080-exec-2] o.h.ampd.server.service.PlaylistService  : Could not get info about playlist: Best of 2012 (Anime, Other)

Does playlist handling maybe not work when running inside a container?

With best wishes,
Tobias

Error fetching albums

I run ampd locally and when I click on "Albums" I get the following error and the Albums section is unresponsive

An error occurred
{
"headers": {
"normalizedNames": {},
"lazyUpdate": null
},
"status": 500,
"statusText": "OK",
"url": "http://pi:8080/api/albums",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure response for http://pi:8080/api/albums: 500 OK",
"error": {
"message": "[2@0] {list} Unknown filter type"
}
}

Error when selectign a genre

The app is able to get the list of all genres but when I try to open any of them I get the following error

An error occurred
{
"headers": {
"normalizedNames": {},
"lazyUpdate": null
},
"status": 500,
"statusText": "OK",
"url": "http://pi:8080/api/genre?genre=Adult%20Alternative%20Pop",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure response for http://pi:8080/api/genre?genre=Adult%20Alternative%20Pop: 500 OK",
"error": {
"message": "[2@0] {list} Unknown filter type"
}
}

Attempt to view playlist contents - too few arguments for "search"

2023-05-12 16:32:20.593 ERROR 81575 --- [0.0-8080-exec-5] o.h.ampd.server.service.PlaylistService : Could not get info about playlist: Saturday

org.bff.javampd.server.MPDConnectionException: [2@0] {search} too few arguments for "search"
at org.bff.javampd.server.MPDSocket.sendBytes(MPDSocket.java:232) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.server.MPDSocket.sendCommand(MPDSocket.java:105) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:56) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:39) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.song.MPDSongSearcher.search(MPDSongSearcher.java:80) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.song.MPDSongSearcher.search(MPDSongSearcher.java:48) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.song.MPDSongSearcher.search(MPDSongSearcher.java:36) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.song.MPDSongDatabase.searchFileName(MPDSongDatabase.java:165) ~[javampd-7.1.0.jar!/:7.1.0]
at org.bff.javampd.playlist.MPDPlaylistDatabase.lambda$listPlaylistSongs$1(MPDPlaylistDatabase.java:72) ~[javampd-7.1.0.jar!/:7.1.0]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
at org.bff.javampd.playlist.MPDPlaylistDatabase.listPlaylistSongs(MPDPlaylistDatabase.java:73) ~[javampd-7.1.0.jar!/:7.1.0]
at org.hihn.ampd.server.service.PlaylistService.getPlaylistInfo(PlaylistService.java:90) ~[classes!/:1.6.5]
at org.hihn.ampd.server.service.PlaylistService$$FastClassBySpringCGLIB$$1f683d30.invoke() ~[classes!/:1.6.5]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:54) ~[spring-context-5.3.26.jar!/:5.3.26]
at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:366) ~[spring-context-5.3.26.jar!/:5.3.26]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:421) ~[spring-context-5.3.26.jar!/:5.3.26]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345) ~[spring-context-5.3.26.jar!/:5.3.26]
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:64) ~[spring-context-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.26.jar!/:5.3.26]
at org.hihn.ampd.server.service.PlaylistService$$EnhancerBySpringCGLIB$$41b3c52.getPlaylistInfo() ~[classes!/:1.6.5]
at org.hihn.ampd.server.controller.PlaylistController.getPlaylist(PlaylistController.java:33) ~[classes!/:1.6.5]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:502) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.26.jar!/:5.3.26]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:596) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.26.jar!/:5.3.26]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.73.jar!/:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.73.jar!/:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Paths with blanks

Hello,
i started using ampd today for our rpg jitsi group as a controller for an icecast stream via mpd.

I have folders with blanks in the name. This throws execeptions:
`
2020-06-05 11:57:51.095 INFO 20704 --- [0.0-8080-exec-1] org.hihn.ampd.server.util.AmpdUtils : Error while search covers in: RPGMix/Clash of the titans

java.nio.file.NoSuchFileException: RPGMix/Clash of the titans
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[na:na]
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[na:na]
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) ~[na:na]
at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:432) ~[na:na]
at java.base/java.nio.file.Files.newDirectoryStream(Files.java:539) ~[na:na]
at org.hihn.ampd.server.util.AmpdUtils.scanDir(AmpdUtils.java:64) ~[ampd-1.1.3.jar:1.1.3]
at org.hihn.ampd.server.service.CoverArtFetcherService.findAlbumCover(CoverArtFetcherService.java:131) ~[ampd-1.1.3.jar:1.1.3]
at org.hihn.ampd.server.controller.CoverController.findCoverByPath(CoverController.java:74) ~[ampd-1.1.3.jar:1.1.3]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]

`

I am not that familiar with java to fix this locally.

Regards
nowrap

Album art (cover.jpg) not being loaded

Hi thank you for taking a look at my issue.

I have ampd 1.5.1. I am unable to get cover art to load, with the following log:

o.hihn.ampd.server.service.CoverService : Could not load art in /${Artist Name}/${Album Name}

Where ${Artist Name} and ${Album Name} are just variable placeholders here for the actual folder names.

For context, I have the following music folder: /media/music with the following general structure:

/media
- /music
-- /Artist Name
--- /Album Name
---- cover.jpg
---- song_1.flac
---- song_2.flac
---- etc.

In other words, in addition to the music files in each directory, there is also a cover.jpg file.

I installed ampd and provided the following application.properties:

mpd.music.directory=/media/music

And when I open the ampd Settings > Backend page, the mpd.music.directory box is empty.

Any suggestions?

Error on Browse

When I go to Browse, I get:

Got an error while browsing /:

Http failure response for https://{MY_URL}/ampd/api/browse?path=/: 500 OK

In the logs:

2022-04-15 13:13:10.441 ERROR 385047 --- [http-nio-0.0.0.0-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.bff.javampd.server.MPDConnectionException: [50@0] {listplaylist} No such playlist] with root cause

org.bff.javampd.server.MPDConnectionException: [50@0] {listplaylist} No such playlist
	at org.bff.javampd.server.MPDSocket.sendBytes(MPDSocket.java:241) ~[javampd-6.2.5.jar!/:6.2.5]
	at org.bff.javampd.server.MPDSocket.sendCommand(MPDSocket.java:108) ~[javampd-6.2.5.jar!/:6.2.5]
	at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:58) ~[javampd-6.2.5.jar!/:6.2.5]
	at org.bff.javampd.command.MPDCommandExecutor.sendCommand(MPDCommandExecutor.java:42) ~[javampd-6.2.5.jar!/:6.2.5]
	at org.bff.javampd.playlist.MPDPlaylistDatabase.countPlaylistSongs(MPDPlaylistDatabase.java:92) ~[javampd-6.2.5.jar!/:6.2.5]
	at org.hihn.ampd.server.service.BrowseService.getPlaylists(BrowseService.java:90) ~[classes!/:1.3.8]
	at org.hihn.ampd.server.service.BrowseService.browse(BrowseService.java:43) ~[classes!/:1.3.8]
	at org.hihn.ampd.server.controller.BrowseController.browseDir(BrowseController.java:27) ~[classes!/:1.3.8]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.18.jar!/:5.3.18]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.6.6.jar!/:2.6.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar!/:5.3.18]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar!/:na]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.60.jar!/:na]

Any ideas of what I have misconfigured?

Running v1.3.8 with context behind an apache reverse proxy. I have port/password/music.directory specified in an application.properties file.
java-11-openjdk
mpd 0.23.6

Websocket requests fail

I hope this isn't too one-off. If it is feel free to close the issue.

When running the ampd, I notice a series of websocket requests attempting to connect to mpd that fail. mpd is running (bind_to_address "localhost", port "6600") and other clients are connected.

When I crank up the log levels, I see the following WARN

2020-05-31 10:06:32.021  WARN 58291 --- [essageBroker-16] org.bff.javampd.server.MPDServerStatus   : Response did not contain status error:
2020-05-31 10:06:32.022  WARN 58291 --- [essageBroker-16] org.bff.javampd.server.MPDServerStatus   : Response did not contain status updating_db:

Upon boot there are a couple of warnings but nothing that I think is related.

I'll take a look at the code to see where the above warnings are dispatched, but posting here in case anyone has run into this before.

Looks like a cool project! Thanks.

Error 400 on cover-urls with brackets

Assuming ampd runs on http://localhost:8080 fetching a cover from the url http://localhost:8080/current-cover?title=What%20They%20Told%20Me%20[%20K%20S%20R%20] returns a error 400.

Adding individual tracks from playlists

It would be nice if you could add individual tracks from a playlist to the queue.

Currently, the browser only allows you to view and add the whole playlist, and clicking on a particular track from the playlist doesn't do anything.

Error: Could not write JSON: For input string: "0.000000"

I'm getting the following error every second. Probably something misconfigured on my part but I'm not good enough with java to know what.

org.springframework.messaging.converter.MessageConversionException: Could not write JSON: For input string: "0.000000" (through reference chain: org.hihn.ampd.server.message.outgoing.StatePayload["serverStatus"]->org.bff.javampd.server.MPDServerStatus["mixRampDb"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: For input string: "0.000000" (through reference chain: org.hihn.ampd.server.message.outgoing.StatePayload["serverStatus"]->org.bff.javampd.server.MPDServerStatus["mixRampDb"]) at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertToInternal(MappingJackson2MessageConverter.java:274) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:201) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.converter.CompositeMessageConverter.toMessage(CompositeMessageConverter.java:96) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.core.AbstractMessageSendingTemplate.doConvert(AbstractMessageSendingTemplate.java:181) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:150) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:129) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:122) ~[spring-messaging-5.3.20.jar!/:5.3.20] at org.hihn.ampd.server.sender.Publisher.publishState(Publisher.java:58) ~[classes!/:1.4.2] at jdk.internal.reflect.GeneratedMethodAccessor58.invoke(Unknown Source) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.20.jar!/:5.3.20] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.20.jar!/:5.3.20] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na] at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na] at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] Caused by: com.fasterxml.jackson.databind.JsonMappingException: For input string: "0.000000" (through reference chain: org.hihn.ampd.server.message.outgoing.StatePayload["serverStatus"]->org.bff.javampd.server.MPDServerStatus["mixRampDb"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.13.3.jar!/:2.13.3] at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:3160) ~[jackson-databind-2.13.3.jar!/:2.13.3] at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertToInternal(MappingJackson2MessageConverter.java:256) ~[spring-messaging-5.3.20.jar!/:5.3.20] ... 18 common frames omitted

Add skip forward/reverse buttons.

Would it be possible to add skip forward/reverse buttons with a configurable amount of time? I like to listen to podcasts and it is really annoying not to be able to skip ads. Right now I am relying on using the position slider but that gets old quick.

Add functionality to edit playlists

ampd should provide options to edit ay playlist. These could be:

  • Add a single track or a range of tracks to an existing or new playlist
  • Remove track(s) from an existing playlist
  • Move a track from one playlist to another

Connection is dropped on song with missing artist tag

Playing a song without artist tag the connection in the web-UI (→ cloud symbol) is switching between connected and
disconnected.

Environment:

  • ampd 1.5.3
  • mpd v 0.23.5
  • openjdk 17.0.4 2022-07-19
  • Debian Bullseye with some backports.

The here played song is tagged with composer but neither with artist, performer or conductur.
The id3 Tags are listed below:

mutagen-inspect /computer42/audio/music-mp3/Wolfgang_Amadeus_Mozart/Wolfgang_Amadeus_Mozart--Mozart_Complete_-_01_-_Fruhe_Symphonien/05--Mozart_Complete_-_01_-_Fruhe_Symphonien--Andante_Symphony_No_4_in_D_KV19_-_Andante.mp3
-- /computer42/audio/music-mp3/Wolfgang_Amadeus_Mozart/Wolfgang_Amadeus_Mozart--Mozart_Complete_-_01_-_Fruhe_Symphonien/05--Mozart_Complete_-_01_-_Fruhe_Symphonien--Andante_Symphony_No_4_in_D_KV19_-_Andante.mp3
- MPEG 1 layer 3, 192000 bps (CBR?), 44100 Hz, 2 chn, 201.22 seconds (audio/mp3)
APIC=cover front,  (image/jpeg, 1227847 bytes)
TALB=Mozart Complete - 01 - Frühe Symphonien
TCOM=Wolfgang Amadeus Mozart
TCON=Classical
TDTG=2015-05-30 00:44:26
TIT2=Andante/Symphony No 4 in D KV19 - Andante
TRCK=005/115

Stacktrace in the console:

022-10-23 12:56:09.602 TRACE 1936275 --- [.0-42080-exec-6] o.h.a.s.s.albumart.AlbumArtService       : Looking for a cover in the directory of file: music-mp3/Wolfgang_Amadeus_Mozart/Wolfgang_Amadeus_Mozart--Mozart_Complete_-_01_-_Fruhe_Symphonien/05--Mozart_Complete_-_01_-_Fruhe_Symphonien--Andante_Symphony_No_4_in_D_KV19_-_Andante.mp3
2022-10-23 12:56:09.609 ERROR 1936275 --- [.0-42080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "String.trim()" because "artist" is null] with root cause

java.lang.NullPointerException: Cannot invoke "String.trim()" because "artist" is null
	at org.hihn.ampd.server.service.cache.CoverCacheService.buildFileName(CoverCacheService.java:119) ~[classes!/:1.5.3]
	at org.hihn.ampd.server.service.cache.CoverCacheService.buildCacheFullPath(CoverCacheService.java:125) ~[classes!/:1.5.3]
	at org.hihn.ampd.server.service.cache.CoverCacheService.loadCover(CoverCacheService.java:81) ~[classes!/:1.5.3]
	at org.hihn.ampd.server.service.albumart.AlbumArtService.findAlbumCoverForTrack(AlbumArtService.java:75) ~[classes!/:1.5.3]
	at org.hihn.ampd.server.controller.CoverController.findAlbumCoverForTrack(CoverController.java:45) ~[classes!/:1.5.3]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at javax.servlet.http.HttpServlet.doHead(HttpServlet.java:241) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:678) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar!/:5.3.23]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar!/:5.3.23]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.65.jar!/:na]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.