Bliss album art manager package for Synology NAS

bliss-UI

 

Bliss is a Java application written by Dan Gravell which can manage file names, tags and album art for your music collection and which can also enforce their consistency. It is designed to be left running once installed so that albums you add later will have these same policies applied to them automatically. It supports a wide range of music formats, and effortlessly deals with very large collections – apparently even ones containing quite obscure recordings. My own collection didn’t really put this to the test, since it doesn’t contain bootlegs, live sets or rarities plus I had also already obtained cover art for it (from back when CoverFlow first graced the screen of my iPhone 2G).

I could see from referrals to this blog that people were asking Dan for a Synology package which he didn’t have the time to investigate, and so I thought that it would make an interesting little project, especially since a NAS is the ideal device to run Bliss on. Although there was already a Howto post on the Synology forums, that guide only really covered getting the basic functionality of Bliss up and running – it was missing the best bits: the filesystem watching and audio fingerprinting features. These depend on natively compiled binaries, but Bliss doesn’t support running on ARM or PowerPC CPUs, and its Intel binaries don’t work on Synology either (the usual problem – glibc too old). Getting these working provided precisely the sort of challenge I like. Not only were they difficult to compile, but getting them integrated into the various OSGi ‘bundles’ that make up Bliss was quite involved too.

Bliss uses an open source library called Chromaprint, itself part of the wider Acoustid project. The aim is to scan an audio file, to produce a fingerprint of the sound, and then to compare this against an open online database such as MusicBrainz.org to identify music regardless of compression codec used. Its author Lukáš Lalinský explains how it works. It turns out that Chromaprint uses some complex maths functions that FFmpeg can provide (specifically Fourier Transform), and FFmpeg’s shared libraries are already included with Synology DSM. I was able to download the sources that were used to build DSM, which then allowed me to build Chromaprint linked to those existing libraries – resulting in a minuscule 84KB build of fpcalc, rather than the statically compiled ones for various OS and CPU architectures included with Bliss, which weigh in at several megabytes. I think I’m finally ‘getting’ what open source is all about, which is nice since that was my objective in experimenting with my NAS. To prevent fpcalc building and linking to its dynamic library libchromaprint.so and to get it to detect FFmpeg properly I had to carefully inspect the Makefiles to find the correct build syntax:
FFMPEG_DIR=/usr/local/i686-linux-gnu cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=NO .
FFMPEG_DIR is the base folder from which CMake will look for lib/libavcodec.so and include/libavcodec/avfft.h.

It’s a bit of a nuisance that on ARM you first have to compile CMake because it doesn’t exist on the Optware ipkg repository, but it was straightforward enough to build. To build the Intel binaries I cross-compiled on a Ubuntu Desktop 12 virtual machine using the Synology toolchain (see the Synology DSM 3rd party developer guide for details).

For watching the filesystem Bliss uses JNotify to hook into the Linux kernel’s inotify subsystem. Getting this compiled was tricky. It seems no one has reported successfully compiling it for an ARM CPU, and JNotify’s author Omry Yadan wasn’t aware of anyone doing this either. The problem is that compilation halts with these errors:

In file included from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
../inotify-syscalls.h:35:1: error: "__NR_inotify_init" redefined
In file included from /opt/include/sys/syscall.h:25,
                 from ../inotify-syscalls.h:4,
                 from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
/opt/include/asm/unistd.h:344:1: error: this is the location of the previous definition
In file included from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
../inotify-syscalls.h:36:1: error: "__NR_inotify_add_watch" redefined
In file included from /opt/include/sys/syscall.h:25,
                 from ../inotify-syscalls.h:4,
                 from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
/opt/include/asm/unistd.h:345:1: error: this is the location of the previous definition
In file included from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
../inotify-syscalls.h:37:1: error: "__NR_inotify_rm_watch" redefined
In file included from /opt/include/sys/syscall.h:25,
                 from ../inotify-syscalls.h:4,
                 from ../net_contentobjects_jnotify_linux_JNotify_linux.c:43:
/opt/include/asm/unistd.h:346:1: error: this is the location of the previous definition

By searching in a very generic way for a solution I found this post on stackoverflow.com which helped me to patch the header inotify-syscalls.h to get around the problem. Since there is no JDK for ARM embedded systems I included the headers from OpenJDK6 which I took from a Ubuntu VM.

Compiling on Intel also required a fix. I was getting the same error as featured in this post on the JNotify user forum on SourceForge.net:
expected specifier-qualifier-list before ‘pid_t’

Despite some people’s apparent success simply rearranging the order of the includes in net_contentobjects_jnotify_linux_JNotify_linux.c this didn’t help me. I’m not sure quite how I stumbled upon it, but I found the solution staring at me on this page:
The size_t, ssize_t, uid_t, gid_t, off_t and pid_t types are defined as described in sys/types.h

I inserted an additional include in for sys/types.h and it compiled ok. It’s worth pointing out that, although all Intel Synology units are x86-64 architecture, the Oracle JRE for Embedded is x86 (32 bit), so I used the i686 toolchain. Synology DSM’s FFmpeg shared libraries are also 32 bit so my build of fpcalc needed to comply with this. Bliss nonetheless expects the binary to be called fpcalc_linux64 since Bliss is detecting the underlying Linux CPU architecture.

Once I had got past the obstacle of compiling the native code, I needed to liaise back and forth with Dan to understand how Bliss was dealing with its libraries and how I could replace the built-in versions. Originally this was quite a kludge but Dan has since abstracted out the native binaries into their own OSGI bundle fragments which makes things a lot easier, and should allow Bliss to survive an in-app update. The Synology package provides the following architecture-specific jar files (with corresponding edits to their manifest). Thank you to Dan for all the quick answers!

  • net.contentobjects.jnotify.linux.amd64-0.94.0.jar
  • net.contentobjects.jnotify.linux.ARM_le-0.94.0.jar
  • net.contentobjects.jnotify.linux.PowerPC-0.94.0.jar
  • com.elsten.bliss.policy.tag.auto.linux.amd64-1.0.0.jar – contains fpcalc.
  • com.elsten.bliss.policy.tag.auto.linux.ARM_le-1.0.0.jar
  • com.elsten.bliss.policy.tag.auto.linux.PowerPC-1.0.0.jar

Here are my fixes to JNotify to get the native library part compiled, since they may help someone else:

 

Patch for native compile of JNotify 0.94 on ARM Synology

diff -crB jnotify-vanilla/inotify-syscalls.h jnotify-arm/inotify-syscalls.h
*** jnotify-vanilla/inotify-syscalls.h	2005-11-30 15:07:56.000000000 +0000
--- jnotify-arm/inotify-syscalls.h	2012-09-14 02:43:44.032130098 +0100
***************
*** 32,40 ****
  # define __NR_inotify_add_watch	152
  # define __NR_inotify_rm_watch	156
  #elif defined (__arm__)
! # define __NR_inotify_init	316
! # define __NR_inotify_add_watch	317
! # define __NR_inotify_rm_watch	318
  #elif defined (__SH4__)
  # define __NR_inotify_init	290
  # define __NR_inotify_add_watch	291
--- 32,46 ----
  # define __NR_inotify_add_watch	152
  # define __NR_inotify_rm_watch	156
  #elif defined (__arm__)
! # ifndef __NR_inotify_init
! #  define __NR_inotify_init     316
! # endif
! # ifndef __NR_inotify_add_watch
! #  define __NR_inotify_add_watch 317
! # endif
! # ifndef __NR_inotify_rm_watch
! #  define __NR_inotify_rm_watch 318
! # endif
  #elif defined (__SH4__)
  # define __NR_inotify_init	290
  # define __NR_inotify_add_watch	291
diff -crB jnotify-vanilla/Release/subdir.mk jnotify-arm/Release/subdir.mk
*** jnotify-vanilla/Release/subdir.mk	2011-02-28 18:07:20.000000000 +0000
--- jnotify-arm/Release/subdir.mk	2012-09-14 02:29:00.000000000 +0100
***************
*** 17,23 ****
  %.o: ../%.c
  	@echo 'Building file: $<'
  	@echo 'Invoking: GCC C Compiler'
! 	gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -O3 -Wall -Werror -c -fmessage-length=0 -fPIC -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
  	@echo 'Finished building: $<'
  	@echo ' '
  
--- 17,23 ----
  %.o: ../%.c
  	@echo 'Building file: $<'
  	@echo 'Invoking: GCC C Compiler'
! 	gcc -I/volume1/public/temp/jdk_include/ -I/volume1/public/temp/jdk_include/linux -O3 -Wall -Werror -c -fmessage-length=0 -fPIC -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
  	@echo 'Finished building: $<'
  	@echo ' '
 

Patch for cross compile of JNotify 0.94 for other Synology CPU architectures, using Ubuntu Desktop 12

diff -crB jnotify-vanilla/net_contentobjects_jnotify_linux_JNotify_linux.c jnotify-i686/net_contentobjects_jnotify_linux_JNotify_linux.c
*** jnotify-vanilla/net_contentobjects_jnotify_linux_JNotify_linux.c	2011-02-28 18:07:20.000000000 +0000
--- jnotify-xcomp/net_contentobjects_jnotify_linux_JNotify_linux.c	2012-09-14 00:41:53.455010206 +0100
***************
*** 36,41 ****
--- 36,42 ----
  #include <sys/time.h>
  #include <sys/select.h>
  #include <sys/ioctl.h>
+ #include <sys/types.h>
  #include <errno.h>
  #include <stdio.h>
  #include <unistd.h>
diff -crB jnotify-vanilla/Release/makefile jnotify-i686/Release/makefile
*** jnotify-vanilla/Release/makefile	2011-02-28 18:07:20.000000000 +0000
--- jnotify-xcomp/Release/makefile	2012-09-14 00:37:56.475007855 +0100
***************
*** 28,34 ****
  libjnotify.so: $(OBJS) $(USER_OBJS)
  	@echo 'Building target: $@'
  	@echo 'Invoking: GCC C Linker'
! 	gcc -shared -o"libjnotify.so" $(OBJS) $(USER_OBJS) $(LIBS)
  	@echo 'Finished building target: $@'
  	@echo ' '
  
--- 28,34 ----
  libjnotify.so: $(OBJS) $(USER_OBJS)
  	@echo 'Building target: $@'
  	@echo 'Invoking: GCC C Linker'
! 	$(CC) -shared -o"libjnotify.so" $(OBJS) $(USER_OBJS) $(LIBS)
  	@echo 'Finished building target: $@'
  	@echo ' '
  
diff -crB jnotify-vanilla/Release/subdir.mk jnotify-i686/Release/subdir.mk
*** jnotify-vanilla/Release/subdir.mk	2011-02-28 18:07:20.000000000 +0000
--- jnotify-xcomp/Release/subdir.mk	2012-09-14 00:37:33.835007731 +0100
***************
*** 17,23 ****
  %.o: ../%.c
  	@echo 'Building file: $<'
  	@echo 'Invoking: GCC C Compiler'
! 	gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -O3 -Wall -Werror -c -fmessage-length=0 -fPIC -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
  	@echo 'Finished building: $<'
  	@echo ' '
  
--- 17,23 ----
  %.o: ../%.c
  	@echo 'Building file: $<'
  	@echo 'Invoking: GCC C Compiler'
! 	$(CC) -I$(TOOLCHAIN)/include -O3 -Wall -Werror -c -fmessage-length=0 -fPIC -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
  	@echo 'Finished building: $<'
  	@echo ' '
 
 

Package instructions

The package can be installed on an unmodified NAS – no hacking or bootstrapping is required. Only Marvell Kirkwood, Intel, and Freescale QorIQ PowerPC CPUs are supported, so please check which CPU your NAS has.

  • Firstly, in the DSM User control panel enable the User Home service.
  • Open the DSM Package Center. In Settings -> Package Sources add my package repository URL which is http://packages.pcloadletter.co.uk
  • Install either one of my Java SE for Embedded Synology packages (Java 6 or Java 7). Only Marvell Kirkwood, Freescale QorIQ, or Intel CPUs are supported. Please read all the notes and instructions on that page carefully.
  • Install Bliss using DSM’s Package Center.
  • The rest is self-explanatory.
 

Package scripts

For information, here are the package scripts so you can see what it’s going to do. You can get more information about how packages work by reading the Synology Package wiki.

installer.sh

#!/bin/sh

#--------BLISS installer script
#--------package maintained at pcloadletter.co.uk

DOWNLOAD_FILE="latest-linux-version"
DOWNLOAD_PATH="http://www.blisshq.com/app"
DOWNLOAD_URL="${DOWNLOAD_PATH}/${DOWNLOAD_FILE}"
DAEMON_USER="`echo ${SYNOPKG_PKGNAME} | awk {'print tolower($_)'}`"
DAEMON_PASS="`openssl rand 12 -base64 2>nul`"
DAEMON_ID="${SYNOPKG_PKGNAME} daemon user"
ENGINE_SCRIPT="bliss.sh"
MIGRATION_FOLDER="${DAEMON_USER}_data_mig"
SYNO_CPU_ARCH="`uname -m`"
NATIVE_BINS_URL="http://packages.pcloadletter.co.uk/downloads/bliss-native-${SYNO_CPU_ARCH}.tgz"   
NATIVE_BINS_FILE="`echo ${NATIVE_BINS_URL} | sed -r "s%^.*/(.*)%\1%"`"
INSTALL_FILES="${DOWNLOAD_URL}"
source /etc/profile

TEMP_FOLDER="`find / -maxdepth 2 -name '@tmp' | head -n 1`"
APP_TEMP="${TEMP_FOLDER}/${SYNOPKG_PKGNAME}"
DAEMON_HOME="`cat /etc/passwd | grep "${DAEMON_ID}" | cut -f6 -d':'`"
PRIMARY_VOLUME="/`echo $TEMP_FOLDER | cut -f2 -d'/'`"


preinst ()
{
  if [ -z ${JAVA_HOME} ]; then
    echo "Java is not installed or not properly configured. JAVA_HOME is not defined. "
    echo "Download and install the Java Synology package from http://wp.me/pVshC-z5"
    exit 1
  fi
  
  if [ ! -f ${JAVA_HOME}/bin/java ]; then
    echo "Java is not installed or not properly configured. The Java binary could not be located. "
    echo "Download and install the Java Synology package from http://wp.me/pVshC-z5"
    exit 1
  fi
  
  #is the User Home service enabled?
  UH_SERVICE=maybe
  synouser --add userhometest Testing123 "User Home test user" 0 "" ""
  UHT_HOMEDIR=`cat /etc/passwd | sed -r '/User Home test user/!d;s/^.*:User Home test user:(.*):.*$/\1/'`
  if echo $UHT_HOMEDIR | grep '/var/services/homes/' > /dev/null; then
    if [ ! -d $UHT_HOMEDIR ]; then
      UH_SERVICE=false
    fi
  fi
  synouser --del userhometest
  #remove home directory (needed since DSM 4.1)
  [ -e /var/services/homes/userhometest ] && rm -r /var/services/homes/userhometest
  if [ ${UH_SERVICE} == "false" ]; then
    echo "The User Home service is not enabled. Please enable this feature in the User control panel in DSM."
    exit 1
  fi
  #fetch the URL for the latest installer version from blisshq.com  
  _download
  DOWNLOAD_URL=`cat ${TEMP_FOLDER}/${DOWNLOAD_FILE}`
  INSTALL_FILES="${DOWNLOAD_URL} ${NATIVE_BINS_URL}"
  #now fetch the installer
  _download
  exit 0
}

_download ()
{
  cd ${TEMP_FOLDER}
  for WGET_URL in ${INSTALL_FILES}
  do
    WGET_FILENAME="`echo ${WGET_URL} | sed -r "s%^.*/(.*)%\1%"`"
    [ -f ${TEMP_FOLDER}/${WGET_FILENAME} ] && rm ${TEMP_FOLDER}/${WGET_FILENAME}
    wget ${WGET_URL}
    if [[ $? != 0 ]]; then
      if [ -d ${PUBLIC_FOLDER} ] && [ -f ${PUBLIC_FOLDER}/${DOWNLOAD_FILE} ]; then
        cp ${PUBLIC_FOLDER}/${DOWNLOAD_FILE} ${TEMP_FOLDER}
      else     
        echo "There was a problem downloading ${WGET_FILENAME} from the official download link, "
        echo "which was \"${WGET_URL}\" "
        echo "Alternatively, you may download this file manually and place it in the 'public' shared folder. "
        exit 1
      fi
    fi
  done
}


postinst ()
{
  #create daemon user
  synouser --add ${DAEMON_USER} ${DAEMON_PASS} "${DAEMON_ID}" 0 "" ""
  
  #determine the daemon user homedir and save that variable in the user's profile
  #this is needed because new users seem to inherit a HOME value of /root which they have no permissions for
  DAEMON_HOME="`cat /etc/passwd | grep "${DAEMON_ID}" | cut -f6 -d':'`"
  su - ${DAEMON_USER} -s /bin/sh -c "echo export HOME=\'${DAEMON_HOME}\' >> .profile"

  #set working folder (/tmp is very small on Synology)
  #and reduce Java prefs system polling frequency to allow hibernation
  su - ${DAEMON_USER} -s /bin/sh -c "echo export VMARGS=\'-Djava.io.tmpdir=${APP_TEMP} -Djava.util.prefs.syncInterval=86400\' >> .profile"
  
  #once again fetch the URL for the latest installer version from blisshq.com
  #and use it to determine the filename we downloaded during preinst
  _download
  DOWNLOAD_FILE=`cat ${TEMP_FOLDER}/${DOWNLOAD_FILE} | sed -r "s%^.*/(.*)%\1%"`

  #run the installer
  cd ${TEMP_FOLDER}
  echo INSTALL_PATH=${SYNOPKG_PKGDEST} > ${TEMP_FOLDER}/bliss-synology.properties
  java -jar ${TEMP_FOLDER}/${DOWNLOAD_FILE} -options ${TEMP_FOLDER}/bliss-synology.properties
  rm ${TEMP_FOLDER}/bliss-synology.properties
  rm ${TEMP_FOLDER}/${DOWNLOAD_FILE}
  sed -i "s%^#!/bin/bash%#!/bin/sh%" ${SYNOPKG_PKGDEST}/bin/${ENGINE_SCRIPT}
  
  #stow jar files containing Synology versions of native code
  #(libjnotify, and fpcalc from the Chromaprint audio fingerprinting library)
  mkdir ${SYNOPKG_PKGDEST}/syno-native
  cd ${SYNOPKG_PKGDEST}/syno-native
  tar xzf ${TEMP_FOLDER}/${NATIVE_BINS_FILE}

  #change owner of folder tree and temp files
  chown -R ${DAEMON_USER} ${SYNOPKG_PKGDEST}
  chown -R ${DAEMON_USER} ${DAEMON_HOME} 
  [ -d ${APP_TEMP} ] && chown -R ${DAEMON_USER} ${APP_TEMP}

  exit 0
}


preuninst ()
{
  #make sure daemon is stopped
  /var/packages/${SYNOPKG_PKGNAME}/scripts/start-stop-status stop
  sleep 6
  
  exit 0
}


postuninst ()
{
  #remove daemon user
  synouser --del ${DAEMON_USER}
  
  #clean up temp
  [ -d ${TEMP_FOLDER}/Bliss ] && rm -r ${TEMP_FOLDER}/Bliss

  exit 0
}


preupgrade ()
{
  #make sure daemon is stopped
  /var/packages/${SYNOPKG_PKGNAME}/scripts/start-stop-status stop
  sleep 6
  
  #if config data exists back it up
  if [ -d ${DAEMON_HOME}/.bliss ]; then
    mkdir ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration
    mv ${DAEMON_HOME}/.bliss ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration
    mv ${DAEMON_HOME}/.java ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration
  fi

  exit 0
}


postupgrade ()
{
  #use the migrated config data from the previous version
  if [ -d ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration/.bliss ]; then
    mv ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration/.bliss ${DAEMON_HOME}
    mv ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration/.java ${DAEMON_HOME}
    rmdir ${SYNOPKG_PKGDEST}/../${DAEMON_USER}_data_migration
    
    #daemon user has been deleted and recreated so we need to reset ownership (new UID)
    chown -R ${DAEMON_USER} ${DAEMON_HOME}
  fi
  
  exit 0
}
 

start-stop-status.sh

#!/bin/sh

#--------BLISS start-stop-status script
#--------package maintained at pcloadletter.co.uk

DAEMON_USER="`echo ${SYNOPKG_PKGNAME} | awk {'print tolower($_)'}`"
DAEMON_ID="${SYNOPKG_PKGNAME} daemon user"
ENGINE_SCRIPT="bliss.sh"
PIDFILE="${SYNOPKG_PKGDEST}/${SYNOPKG_PKGNAME}.pid"
SYNO_CPU_ARCH="`uname -m`"

_findpid ()
{
  ps -w | grep "^ *[0-9]* ${DAEMON_USER} .*java.*-Djava\.io\.tmpdir=/volume1/@tmp/Bliss" | grep -v "grep" | awk '{ print $1 }'
}


case $1 in
  start)
    PID=`_findpid`
    if [ -n "$PID" ]; then
      echo daemon is already running with pid $PID
      exit 1;
    fi
    DAEMON_HOME="`cat /etc/passwd | grep "${DAEMON_ID}" | cut -f6 -d':'`"
    
    #set the current timezone for Java so that log timestamps are accurate
    #we need to use the modern timezone names so that Java can figure out DST
    SYNO_TZ=`cat /etc/synoinfo.conf | grep timezone | cut -f2 -d'"'`
    SYNO_TZ=`grep "^${SYNO_TZ}" /usr/share/zoneinfo/Timezone/tzname | sed -e "s/^.*= //"`
    grep "^export TZ" ${DAEMON_HOME}/.profile > /dev/null \
     && sed -i "s%^export TZ=.*$%export TZ='${SYNO_TZ}'%" ${DAEMON_HOME}/.profile \
     || echo export TZ=\'${SYNO_TZ}\' >> ${DAEMON_HOME}/.profile
    
    #update the package version number in case of an in-app update
    #find must write out to a file because vars cannot be defined in subshells
    #http://mywiki.wooledge.org/BashFAQ/024
    find ${SYNOPKG_PKGDEST}/felix-cache -name "*.info" > /tmp/bliss-v-check.txt
    while IFS="" read -r FILE_TO_PARSE; do
      if [ -e ${FILE_TO_PARSE} ]; then
        if grep "com.elsten.bliss.bundle" ${FILE_TO_PARSE} > /dev/null; then
          BLISS_BUNDLE_DIR="`dirname ${FILE_TO_PARSE}`"
        fi
      fi
    done < /tmp/bliss-v-check.txt
    #read current version
    BLISS_VERSION=`grep "version" /var/packages/${SYNOPKG_PKGNAME}/INFO | sed -r "s/^.*([0-9]{8}).*$/\1/"`
    if [ -d ${BLISS_BUNDLE_DIR} ]; then
      find ${BLISS_BUNDLE_DIR} -name *.jar > /tmp/bliss-v-check.txt
      while IFS="" read -r FILE_TO_PARSE; do
        if [ -e ${FILE_TO_PARSE} ]; then
          DETECTED_VERSION=`unzip -p ${FILE_TO_PARSE} META-INF/MANIFEST.MF | grep Bundle-Version | cut -f4 -d'.' |  cut -c1-8`
        fi
        if [ ${DETECTED_VERSION} -gt ${BLISS_VERSION} ]; then
          BLISS_VERSION=${DETECTED_VERSION}
        fi
      done < /tmp/bliss-v-check.txt
    fi
    rm /tmp/bliss-v-check.txt
    sed -r -i "s/^version=\"[0-9]{8}/version=\"${BLISS_VERSION}/" /var/packages/Bliss/INFO
    
    #update the CPU-specific repository customizations (in case of an in-app update)
    if [ ${SYNO_CPU_ARCH} == "armv5tel" ]; then
      sed -i "s/jnotify\.linux\.x86/jnotify\.linux\.ARM_le/g" ${SYNOPKG_PKGDEST}/bliss-bundle/repository.xml
      sed -i "s/policy\.tag\.auto\.linux\.x86/policy\.tag\.auto\.linux\.ARM_le/g" ${SYNOPKG_PKGDEST}/bliss-bundle/repository.xml
    fi
    if [ ${SYNO_CPU_ARCH} == "ppc" ]; then
      sed -i "s/jnotify\.linux\.x86/jnotify\.linux\.PowerPC/g" ${SYNOPKG_PKGDEST}/bliss-bundle/repository.xml
      sed -i "s/policy\.tag\.auto\.linux\.x86/policy\.tag\.auto\.linux\.PowerPC/g" ${SYNOPKG_PKGDEST}/bliss-bundle/repository.xml
    fi
    
    #overwrite native lib bundles with syno versions (in case of an in-app update)
    cp ${SYNOPKG_PKGDEST}/syno-native/* ${SYNOPKG_PKGDEST}/bliss-bundle

    #start daemon in background mode
    echo "Starting ${SYNOPKG_PKGNAME} ... "
    su - ${DAEMON_USER} -s /bin/sh -c "cd ${SYNOPKG_PKGDEST}/bin && ./${ENGINE_SCRIPT} > ${SYNOPKG_PKGDEST}/bliss.out 2>&1 &"
    sleep 2
    PID=`_findpid`
    if [ -n "$PID" ]; then
      echo $PID > $PIDFILE
      echo "OK"
    else
      echo "FAIL"
      exit 1
    fi

    #set up symlink for the DSM GUI
    if [ -d /usr/syno/synoman/webman/3rdparty ]; then
      ln -s ${SYNOPKG_PKGDEST}/DSM/${SYNOPKG_PKGNAME} /usr/syno/synoman/webman/3rdparty/${SYNOPKG_PKGNAME}
    fi
   
    exit 0
  ;;

  stop)
    echo -n "Stopping daemon ... "
    if [ -f $PIDFILE ] ; then
      kill `cat $PIDFILE`
      sleep 10
    fi
    PID=`_findpid`
    if [ -n "$PID" ]; then
      echo "Still running, killing PID=$PID ... "
      kill -9 $PID
    fi
    rm -f $PIDFILE
    echo "OK"
    
    #remove DSM icon symlink
    if [ -e /usr/syno/synoman/webman/3rdparty/${SYNOPKG_PKGNAME} ]; then
      rm /usr/syno/synoman/webman/3rdparty/${SYNOPKG_PKGNAME}
    fi

    exit 0
  ;;

  status)
    PID=`_findpid`
    if [ -n "$PID" ]; then
      exit 0
    else
      exit 1
    fi
  ;;

  log)
    echo "${SYNOPKG_PKGDEST}/bliss.out"
    exit 0
  ;;
esac
 

Changelog:

  • 20130213-0009 Updated to Bliss 20130213, and will correctly report version in Package Center after an in-app update
  • 20130131-0008 Updated to Bliss 20130131
  • 20121112-0007 Fixes for DSM 4.2
  • 20121112-006 Updated to Bliss 20121112
  • 20121019-005 Updated to Bliss 20121019
  • 20121002-004 Updated to Bliss 20121002
  • 20120830-003 Added support for Freescale QorIQ PowerPC CPUs used in some Synology x13 series products, PowerPC processors in previous Synology generations with older glibc versions are not supported
  • 20120830-002 Hopefully fixed Java prefs polling issue that prevented NAS hibernation
  • 20120830-001 initial public release

 
 
About these ads

218 thoughts on “Bliss album art manager package for Synology NAS

  1. Fab

    1813+ with Java 6 working, but a notice that this app could not start automatically? Not shure what to do because Bliss will also not start automatically. I’m sure it’s me doing something wrong :-)

    Reply
      1. spaanplaat

        Sorry for the late reaction. I had to reinstall java and bliss but on reinstall bliss it would not download the jar file. The jar file had to be downloaded manually and placed in the public folder or it wouldn’t install. I lost my config but at least it works now.

  2. fredericszymanski

    Do we still need Java SE embedded 7 or the package can be run with Java SE embedded 8 ?

    Reply
  3. nicolas

    Hello

    Since Dan, the author, has released a new version (might ne in beta but addresses a few bloking bugs), would it be possible to package it for DSM 5?

    Thanks very much
    Nicolas

    Reply
      1. nicolas

        Good news, thanks !! ( I bought the unlimited fixes but I can’t use it since it crashes after 30mn, and this should be solved in the latest beta…)

        thanks again

  4. Tommie

    Hi Dan, the Bliss version on my Synology device already shows version 20140318. I suppose you’ve already updated Bliss. Could this be?

    Reply
    1. Tommie

      Hi Dan, could you comment on my previous question? Anyway, thanks for all your great work!

      Reply
      1. gravelld

        Sorry, slipped through the cracks. However, I don’t understand the question. Are you asking why is the version so recent? Is this related to the DSM 5.0 issue?

      2. Tommie

        Well, I’ve found out what happened. I’ve originally installed Bliss from your repository. This initially showed version 20130213 of Bliss, but it’s interesting that Bliss has a built-in ‘update’ functionality. Meaning Bliss updated itself to version 20140318 beginning of march, and today to version 20140522.

        All this without using your repository. Does this have any complications or risks?

      3. gravelld

        The only thing I can think of is that updates to patters’ custom builds of the audio fingerprinter would not be included.

      4. Tommie

        Yes, fixed this by loggin in with telnet and user root. Deleted the felix-cache folder. Bliss is working again, thanks!

  5. Will

    How hard would it be to get this running on a Marvell Armada cpu, aka the DS213j? Or is the architecture such that it would be impossible?

    Reply
    1. patters Post author

      It should be possible, but I was getting a weird error while attempting to compile jnotify IIRC. The exact same source compiled fine for the other architectures. I submitted a support ticket to Synology to see if they could help but they couldn’t recreate the problem. I’ll try and take another look when I get some time.

      Reply
      1. Will

        Honestly, that would be amazing. DSM’s audio manager is reading all of my carefully curated (via Musicbee) tags as one huge mess of split albums and “feat.” notes.

        Let me know if there’s any testing or anything I could do to help such a thing along!

      2. gravelld

        Interesting… you could connect MP3Tag or similar to the NAS and try setting the “album artist” tag. Hope that helps…

      3. patters Post author

        I just got it cross compiled using the latest toolchain so I should be able to put a package together. Gotta build fpcalc now.

      4. patters Post author

        Hi Dan, yes that was using the DSM 5.0 toolchain. Synology have changed the version of FFmpeg that’s bundled with the system so my currently available package will lack a functioning fpcalc.

      5. gravelld

        No, I think it’s 0.7 actually. I should upgrade! AFAIK 1.1 should still work.

      6. patters Post author

        Can you (or anyone else with an Armada 370 or Armada XP CPU running DSM 5.0) download this and run it? I’ve compiled it to depend on the FFmpeg libavcodec version that’s included with DSM 5.0.
        cd /volume1/@tmp
        wget http://dl.dropboxusercontent.com/u/1188556/fpcalc1.1-armv7l.tgz
        tar xvzf fpcalc1.1-armv7l.tgz
        cd fpcalc1.1-armv7l
        ./fpcalc

        Does it run?

  6. Pingback: Bliss & Music Management | Rebelpeon

  7. Will

    I (as you might have guessed) have a DS213j running an armada370. Would it help if I were to run/test it? If so just tell me what I’d be looking for and I’ll jump on it — excited to get Bliss up and running.

    Reply
    1. patters Post author

      If you are running DSM 5.0 can you run those commands in my last post from an SSH session (which will download and extract it to a temp folder)? Does fpcalc run without showing an error? Can you post the screen output please?

      Reply
      1. Will

        I went ahead and tried the commands as you requested — got to the second-to-last with no trouble. On the second to last, I got “cannot cd to [etc}” as an error — I went ahead and tried the last command, but it didn’t seem to run anything. Here’s a screen shot of exactly what happened:

        Let me know if that is good news, bad news, or no news at all — and how I can help you from here. Thanks for giving this a shot.

      2. patters Post author

        That’s perfect – thanks. fpcalc has indeed launched and returned the command syntax, demonstrating that it works linking to the DSM 5.0 version of libavcodec.so.55 that’s already on your system (it would have failed with an error if not). I’ve built an ARMv5 version using the same process and I can confirm that it’s fine on my DS111. Now I need to cross compile the binaries for the other Synology CPU architectures – there are five now: armv5te, armv7l, armv7l (with NEON), i686, ppc. Then I should be able to release a new version of the package.

      3. Will

        Hey I just wanted to check back in and see if there was any possibility of that Bliss package for the DS213j on the horizon? Totally understand if it’s a backburner project, just figured it couldn’t hurt to ask.

      4. patters Post author

        Yes, sorry for the long delay. I did manage to get jnotify and fpcalc built for the armada370, so it will happen – just need to find some time to get it packaged.

      5. Will

        No problem! Thanks so much for all your work, I really appreciate it (and so, I imagine, do all the other music tagging enthusiasts with an armada370).

  8. Jappie

    Hi there,

    Given the rather large number of comments above I am taking the liberty to run a question by you to see if you can help me. I’m trying to run Bliss on a DS211+. The installation seems to work fine. After installation the Package Manager also states the app is running but no action on the default Bliss port.
    What I have checked:
    1. That the package is installed in /var/packages/Bliss >> CHECK
    2. That JAVA is correctly installed >> CHECK
    3. Forcing a start from the cli; “sh /var/packages/Bliss/scripts/start-stop-status.sh start”
    AH, something not quite right with a couple of files
    “find: /felix-cache: No such file or directory
    grep: /var/packages//INFO: No such file or directory
    sed: can’t read /bliss-bundle/repository.xml: No such file or directory
    sed: can’t read /bliss-bundle/repository.xml: No such file or directory
    cp: cannot stat `/syno-native/*’: No such file or directory”
    Yet I don’t think this is what makes the app tumble as we can now read:
    “Starting …
    FAIL”
    so for some reason the app fails to start, but not a lot of information in the /var/log/messages:
    “Jul 3 14:52:25 DiskStation PkgSynoMan.cgi: pkgcurltool.cpp:350 https://djfil.servebe er.com/repository/, Failed to request packages, httpResponseCode=404
    Jul 3 14:52:37 DiskStation geticon.cgi: pkgcurltool.cpp:458 http://www.synology.com/ pkg_img/Python/2.7.6-0016/thumb_72.png, Failed to request packages, httpResponse Code=404
    Jul 3 14:54:57 DiskStation geticon.cgi: pkgcurltool.cpp:458 http://www.synology.com/ pkg_img/Python/2.7.6-0016/thumb_72.png, Failed to request packages, httpResponse Code=404″

    It doesn’t seem to help (or at least I can’t find any pointers in this output). Any help much appreciated.

    Cheers Jappie

    Reply
    1. gravelld

      Hi Jappie. It looks like the environment variables that point to bliss’s location are not configured. The paths you quote are not complete:

      find: /felix-cache: No such file or directory
      grep: /var/packages//INFO: No such file or directory
      sed: can’t read /bliss-bundle/repository.xml: No such file or directory
      sed: can’t read /bliss-bundle/repository.xml: No such file or directory

      The smoking gun is the second one which has the double forward slash “//” which suggests some string manipulation has gone awry. But I think all paths there are missing something. The bliss folder should be prepended to the other paths e.g. “/Volumes/@bliss.app/felix-cache” (can’t remember the exact path).

      patters might have more idea what has gone wrong, but maybe this relates to running it from the command line.

      Reply
      1. Jappie

        Hi Gravelld,

        Thanks for your helpful comment and you confirm what I already thought; variables are indeed not properly taken into account. Now the real question is if this is related to running the script from CLI or if there is another cause. FWIW; the variables are in and by themselves not defined in the script and I would almost assume these are “generic” system variables that are used in the same way for other applications, so can not understand why it would fail in this script.

        The variables as they are used in the script are:
        ${SYNOPKG_PKGDEST}/felix-cache
        /var/packages/${SYNOPKG_PKGNAME}/INFO
        ${SYNOPKG_PKGDEST}/bliss-bundle/repository.xml

        Cheers Jappie

      2. patters Post author

        These SYNO variables only exist in the context of the DSM Package Center. This is why running these scripts will fail when you try to run them manually.

      3. Jappie

        Hi patters, thanks for your precious feedback. I understand now that I can’t make the package run from the command line, yet is there any other way to get some useful debugging output as to why the package isn’t working properly even if in the Package console it says it’s started?

        Just to eliminate the most likely causes;
        -I am within the network so no need for port-forwarding for the used port (of the top of my head 3220)
        -Java is installed and properly running

        Any other ideas?
        Cheers Jappie

  9. gravelld

    I thought there was a “log” or “journal” in the Synology interface that shows stdout/stderr from a process? Can you copy/paste that?

    Reply
    1. jappie

      ERROR: Bundle com.elsten.bliss.bootstrapbundle [1] Error starting file:/volume1/@appstore/Bliss/bin/./../bundle/com.elsten.bliss.bootstrapbundle.jar (org.osgi.framework.BundleException: Unresolved constraint in bundle com.elsten.bliss.bootstrapbundle [1]: Unable to resolve 1.0: missing requirement [1.0] osgi.ee; (&(osgi.ee=JavaSE)(version=1.6)))
      org.osgi.framework.BundleException: Unresolved constraint in bundle com.elsten.bliss.bootstrapbundle [1]: Unable to resolve 1.0: missing requirement [1.0] osgi.ee; (&(osgi.ee=JavaSE)(version=1.6))
      at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3826)
      at org.apache.felix.framework.Felix.startBundle(Felix.java:1868)
      at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191)
      at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295)
      at java.lang.Thread.run(Thread.java:744)

      Reply
      1. gravelld

        It looks like it’s looking for Java 6 but cannot find it. Have you changed the installed Java on the NAS?

      2. Jappie

        Hi,

        I just checked and although this maybe a Java related problem, the output from “which java” is this: /volume1/@appstore/java8/ejdk1.8.0/linux_arm_sflt/jre/bin/java
        So it seems to me Java is available but could it be a version incompatibility or conflict?

        Also from the package center I can see the Java installation and looking at the log I find the following:
        java version “1.8.0″
        Java(TM) SE Embedded Runtime Environment (build 1.8.0-b132, headless)
        Java HotSpot(TM) Embedded Client VM (build 25.0-b70, mixed mode)

        System installed locales:
        C
        cs_CZ.utf8
        da_DK.utf8
        de_DE.utf8
        en_US.utf8
        es_ES.utf8
        fr_FR.utf8
        hu_HU.utf8
        it_IT.utf8
        ja_JP.utf8
        ko_KR.utf8
        nb_NO.utf8
        nl_NL.utf8
        pl_PL.utf8
        POSIX
        pt_BR.utf8
        pt_PT.utf8
        ru_RU.utf8
        sv_SE.utf8
        tr_TR.utf8
        zh_CN.utf8
        zh_TW.utf8

        JAVA_HOME=/volume1/@appstore/java8/ejdk1.8.0/linux_arm_sflt/jre
        TZ=Europe/Brussels

        Cheers Jappie

      3. gravelld

        Yes, although in theory bliss will run on Java 8 (e.g. in Windows, Linux etc) it insists it requires Java 6, so it won’t run. You need a way of installing Java 6 and pointing bliss at it… at which point my knowledge of Synology runs out… sorry.

  10. Ivan

    First of all nice blog, congratulations and thank you for maintaining your repository.

    Is there any chance to see a version of Bliss for the Marvel Armada (ARMv7) CPUs? Downloading of album cover art is really a killer feature missing in Audio Station.

    On a side note, is there any reason to maintain your own repository instead of using Synocommunity?

    Thank you.

    Reply
    1. gravelld

      Hey Ivan. I can’t comment on the repository because that’s patters’ domain (literally), but I can comment on bliss because I am the programmer. If you have ways that bliss can better support Synology users (other than support for ARM), please let me know… e.g. specific ways that Audio Station works such as rules about cover art, filenames, specific tags, that sort of thing.

      Reply
      1. nicolas

        Hello,

        I tried to install Bliss today but all that is proposed is a bliss version stated 20130213-0009 …
        I thought I would get an up-to-date version. Is it the last one that has been packaged for synology (Intel-based) ?
        Do I need to compile by myself if I want something more recent?

        Thanks
        Nicolas

      2. thesalan

        Hello Nicolas,
        I’ve just install Bliss yesterday and I noticed this too, but don’t worry, it will install the last version!

    1. thesalan

      I think you can install differents java version (6, 7 and 8) with java manager from synology repo, and choose which you want to use.

      Reply
  11. Erik Lundquist

    Need some help getting Bliss to run. I have had Bliss up & running, but just noticed it was down. When starting I get a “Failed to run package service error”. One time I looked at the Bliss log to see it was not finding Java, this was most likely due to DSM updates. I have reinstalled Java 7 & Bliss, but still get a “Failed to run package service error” with no information in the Bliss Log.

    Any ideas?

    Reply
      1. fredericszymanski

        Update : The Synology interface says “unable to start package” but Bliss is working if you go straight to it’s webpage. I have the version 20141027 running with java 8.

      2. Ashkaan

        Hi Fred,

        I’m not getting that result. It says “unable to start package”, but there’s nothing on the default port of 3220. I checked application.cfg and that is indeed the right port.

        Have you tested 5.1 yet, Dan?

        Thanks!

      3. fredericszymanski

        Completly uninstall Bliss and java and then install java8 and Bliss.
        It would be cool to have a database autosave outside of the bliss folder to avoid the x weeks of re-creating it each time I re-install Bliss on my NAS (after each java update).

      4. patters Post author

        You don’t need to uninstall dependent packages to update Java. Just stop bliss, update Java, then start bliss. Same for DSM updates.

      5. fredericszymanski

        On my DS212j It won’t work and I have to re-install java and Bliss after each DSM update and each java update because bliss won’t start.

      6. gravelld

        If Java 8 is installed, and Java 6/7 is not, I am fairly certain you will need to re-install bliss. The reason is that the framework bliss uses to start (Apache Felix) didn’t support Java 8, until I updated the version in the latest release. This was also affecting Windows and Linux users.

        I’m not 100% sure however if the embedded nature of this JRE *was* supported… but I don’t think so.

      7. Ashkaan

        No go, Guys. I uninstalled Java 7. I installed Java 8 (and put that file from Oracle’s site in public). I installed Bliss and I immediately get, “failed to run package service” (I misquoted before). Any ideas? I’m running DSM 5.1 on 1813+.

      8. gravelld

        Oh, ok, so it’s now working and your previous message is no longer valid? I wonder what the reset did…

      9. Ashkaan

        Yes, my message is no longer valid.

        It does error and show as “Stopped” in DSM, but the site works (and I’m guessing perfectly).

  12. Twilek

    Hi patters,

    are you planning to port the package to the avoton platform? (By the way the Crashplan packages works perfectly so far)

    Reply
  13. MichaelL

    How can I manually update bliss version to 20141027? The update link in bliss is saying I have the latest version 20140917. I’ve already removed Java 6 and installed Java 8.

    Frederic how did you update bliss to 20141027?

    Reply
    1. gravelld

      Also, the in-app update only refreshes its knowledge of the latest version once – the first time you visit the update page on each restart. So you can restart bliss and visit the update page.

      In this case though, it’s best to re-install because Java 8 support cannot be given via an in-app update…

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s