diff --git a/.gitignore b/.gitignore index 88a64dc8..54c77670 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,10 @@ local.properties # Eclipse Core .project +# Intellij +*.iml +.idea + # External tool builders .externalToolBuilders/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..64fdcf2a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: java +sudo: required +jdk: + - oraclejdk8 +cache: + directories: + - $HOME/.m2 +install: + - sudo apt-get -qq update + - sudo apt-get -y install lintian fakeroot rpm python-rpm + - git clone https://github.com/rpm-software-management/rpmlint -o rpmlint-1.9 + - sudo make -C rpmlint install +script: + - mvn -Pfull,rpm package install + - mvn -Pfull -pl libresonic-assembly assembly:single diff --git a/BUILD.md b/BUILD.md index 9254e560..d4f639f9 100644 --- a/BUILD.md +++ b/BUILD.md @@ -8,6 +8,7 @@ Requirements * Recent version of [Maven](http://maven.apache.org/). * A JDK installation. 1.8.x series of OpenJDK or Oracle JDK 8+ should work. * Optional: lintian and fakeroot, for .deb package + * Optional: rpm and rpmlint, for .rpm package * Test as follows: ``` @@ -53,14 +54,39 @@ $ Packaged .deb ------------- -You can furthermore go ahead to create a .deb suitable for installation on Debian or Ubuntu. These instructions should similarly work with rpm(for RedHat/CentOS or Fedora), but it is has not been tested. +You can furthermore go ahead to create a .deb suitable for installation on +Debian or Ubuntu. ``` $ mvn -P full -pl libresonic-booter -am install -$ mvn -P full -pl libresonic-installer-debian/ -am install +$ mvn -P full -pl libresonic-installer-debian -am install $ sudo dpkg -i ./libresonic-installer-debian/target/libresonic-*.deb -$ ``` -Good luck! +Packaged RPM +------------ + +Building a RPM package is very similar : + +``` +$ mvn -P full -pl libresonic-booter -am install +$ mvn -P full,rpm -pl libresonic-installer-rpm -am install +$ sudo rpm -ivh libresonic-installer-rpm/target/libresonic-*.rpm +``` +Additional release archives +--------------------------- + +Additional release archives can be built using the following commands : + +``` +$ mvn -Pfull -pl libresonic-assembly assembly:single +``` + +These archives are built in `libresonic-assembly/targets` and include : + +* The source distribution +* The standalone archive (for use without a WAR container) +* The WAR archive (for WAR containers) + +Good luck! diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2f876c..1a7e0f4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ # Libresonic/libresonic # --> +v6.1.beta2 +-------- + + * Metaproject: Jenkins builds! + * More documentation + * Translation updates + * Improve shuffling behaviour + * Lots of small fixes, many more to come + +v6.1.beta1 +---------- + + * Meant as a release candidate; failed to make it past the Primary election. + v6.1-alpha1 ----------- diff --git a/INSTALL.md b/INSTALL.md index c20a948b..40f97083 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -23,7 +23,7 @@ Daily WAR files are built by Jenkins and available [here](https://jenkins.zifnab 1. Download the latest war file: - wget https://jenkins.zifnab.net/job/libresonic/lastSuccessfulBuild/artifact/.repository/org/libresonic/player/libresonic-main/6.1.beta1/libresonic-main-6.1.beta1.war -O /var/lib/tomcat8/webapps/libresonic.war + wget https://jenkins.zifnab.net/job/libresonic/lastSuccessfulBuild/artifact/.repository/org/libresonic/player/libresonic-main/6.1.beta2/libresonic-main-6.1.beta2.war -O /var/lib/tomcat8/webapps/libresonic.war Note that this command copies the war file directly to the Tomcat webapps directory, and renames it to `libresonic.war`. diff --git a/MIGRATE.md b/MIGRATE.md new file mode 100644 index 00000000..3f1e2990 --- /dev/null +++ b/MIGRATE.md @@ -0,0 +1,36 @@ +Upgrade to Libresonic from Subsonic +================ + +This guide helps you to migrate your data from Subsonic to Libresonic. It has been tested with Subsonic 5 to Libresonic 6. + +Install Libresonic as described in INSTALL.md. The author of this guide used the standalone solution without Java Tomcat. + +After installation of Libresonic, the database needs to be migrated. In preperation for that, stop the Libresonic service + + sudo service libresonic stop + +If you ran Subsonic before, your data will be (by default) stored in `/var/subsonic`. Assuming you did not use Libresonic before, we will delete all data from Libresonic + + sudo rm -r /var/libresonic # WARNING: DELETES all Libresonic data (Subsonic data will be kept) + +We then copy Subsonic data to Libresonic location. Be aware that a couple of files need to be renamed: + + sudo cp -a /var/subsonic /var/libresonic + sudo mv /var/libresonic/subsonic_sh.log libresonic_sh.log + sudo mv /var/libresonic/subsonic.log libresonic.log + sudo mv /var/libresonic/subsonic.properties libresonic.properties + sudo mv /var/libresonic/db/subsonic.backup /var/libresonic/db/libresonic.backup + sudo mv /var/libresonic/db/subsonic.data /var/libresonic/db/libresonic.data + sudo mv /var/libresonic/db/subsonic.lck /var/libresonic/db/libresonic.lck + sudo mv /var/libresonic/db/subsonic.log /var/libresonic/db/libresonic.log + sudo mv /var/libresonic/db/subsonic.properties /var/libresonic/db/libresonic.properties + sudo mv /var/libresonic/db/subsonic.script /var/libresonic/db/libresonic.script + +Then start Libresonic service again. + + sudo service libresonic start + +Your old settings will be there. If you wish, you can delete subsonic data + + sudo rm -r /var/subsonic # Optional, THIS WILL DELETE SUBSONIC DATA + diff --git a/documentation/FreeBSD-FreeNAS-Install.md b/documentation/FreeBSD-FreeNAS-Install.md index d03bf5c4..d2960a73 100644 --- a/documentation/FreeBSD-FreeNAS-Install.md +++ b/documentation/FreeBSD-FreeNAS-Install.md @@ -66,15 +66,15 @@ Open a web browser and enter your servers IP address in the url bar followed by You should be greeted by the Apache Tomcat page. Click on the Manager App button on the right of the page and enter the username and password used in step 3. Default was username: admin and password: admin -Scroll down to Deploy and the subheading "WAR file to deploy" hit choose file and select the libresonic.war downloaded in the preamble. After selecting press the deploy button. Scroll up and press start. When the page refreshes a message "OK - Started application at context path /libresonic-v6.1.beta1" should be visible. +Scroll down to Deploy and the subheading "WAR file to deploy" hit choose file and select the libresonic.war downloaded in the preamble. After selecting press the deploy button. Scroll up and press start. When the page refreshes a message "OK - Started application at context path /libresonic-v6.1.beta2" should be visible. ### 6. Navigate to Libresonic In a browser. Take your server IP address and port and append the the context path from above -ie if the War deployed was called libresonic-v6.1.beta1.war navigate to: +ie if the War deployed was called libresonic-v6.1.beta2.war navigate to: - 10.0.0.10:8080/libresonic-v6.1.beta1/ + 10.0.0.10:8080/libresonic-v6.1.beta2/ ### 7. Log into Libresonic diff --git a/documentation/INSTALL.md b/documentation/INSTALL.md index c20a948b..40f97083 100644 --- a/documentation/INSTALL.md +++ b/documentation/INSTALL.md @@ -23,7 +23,7 @@ Daily WAR files are built by Jenkins and available [here](https://jenkins.zifnab 1. Download the latest war file: - wget https://jenkins.zifnab.net/job/libresonic/lastSuccessfulBuild/artifact/.repository/org/libresonic/player/libresonic-main/6.1.beta1/libresonic-main-6.1.beta1.war -O /var/lib/tomcat8/webapps/libresonic.war + wget https://jenkins.zifnab.net/job/libresonic/lastSuccessfulBuild/artifact/.repository/org/libresonic/player/libresonic-main/6.1.beta2/libresonic-main-6.1.beta2.war -O /var/lib/tomcat8/webapps/libresonic.war Note that this command copies the war file directly to the Tomcat webapps directory, and renames it to `libresonic.war`. diff --git a/libresonic-assembly/pom.xml b/libresonic-assembly/pom.xml index 90e020bb..7f2b49bc 100644 --- a/libresonic-assembly/pom.xml +++ b/libresonic-assembly/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-booter/pom.xml b/libresonic-booter/pom.xml index b8bf1a68..fe778dfe 100644 --- a/libresonic-booter/pom.xml +++ b/libresonic-booter/pom.xml @@ -8,7 +8,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-booter/src/main/resources/applicationContext-agent.xml b/libresonic-booter/src/main/resources/applicationContext-agent.xml index 2b2e4856..f4221270 100644 --- a/libresonic-booter/src/main/resources/applicationContext-agent.xml +++ b/libresonic-booter/src/main/resources/applicationContext-agent.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/libresonic-booter/src/main/resources/applicationContext-deployer.xml b/libresonic-booter/src/main/resources/applicationContext-deployer.xml index 07932bb8..86791e3d 100644 --- a/libresonic-booter/src/main/resources/applicationContext-deployer.xml +++ b/libresonic-booter/src/main/resources/applicationContext-deployer.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/libresonic-booter/src/main/resources/applicationContext-mac.xml b/libresonic-booter/src/main/resources/applicationContext-mac.xml index 629d9632..fd908955 100644 --- a/libresonic-booter/src/main/resources/applicationContext-mac.xml +++ b/libresonic-booter/src/main/resources/applicationContext-mac.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/libresonic-installer-debian/pom.xml b/libresonic-installer-debian/pom.xml index eb27e599..ac53d340 100644 --- a/libresonic-installer-debian/pom.xml +++ b/libresonic-installer-debian/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-installer-debian/src/DEBIAN/control b/libresonic-installer-debian/src/DEBIAN/control index 5f6fbf42..08e6f05d 100644 --- a/libresonic-installer-debian/src/DEBIAN/control +++ b/libresonic-installer-debian/src/DEBIAN/control @@ -4,7 +4,7 @@ Section: Multimedia Priority: optional Recommends: ffmpeg Architecture: all -Maintainer: Sindre Mehus +Maintainer: Eugene E. Kashpureff Jr Description: A web-based music streamer, jukebox and Podcast receiver Libresonic is a web-based music streamer, jukebox and Podcast receiver, providing access to your music collection wherever you are. Use it diff --git a/libresonic-installer-mac/pom.xml b/libresonic-installer-mac/pom.xml index 05204b09..432d5085 100644 --- a/libresonic-installer-mac/pom.xml +++ b/libresonic-installer-mac/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-installer-rpm/pom.xml b/libresonic-installer-rpm/pom.xml index c81254c9..74e86211 100644 --- a/libresonic-installer-rpm/pom.xml +++ b/libresonic-installer-rpm/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-installer-windows/pom.xml b/libresonic-installer-windows/pom.xml index 72726ecb..e9567211 100644 --- a/libresonic-installer-windows/pom.xml +++ b/libresonic-installer-windows/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 diff --git a/libresonic-main/libresonic-main.iml b/libresonic-main/libresonic-main.iml deleted file mode 100644 index 4ac8de09..00000000 --- a/libresonic-main/libresonic-main.iml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index 70abbc5c..0d0a6234 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -9,7 +9,7 @@ org.libresonic.player libresonic - 6.1.beta1 + 6.1.beta2 @@ -246,12 +246,6 @@ 1.5.5 - - com.sun.mail - javax.mail - 1.5.5 - - taglibs standard @@ -291,12 +285,6 @@ 2.0.1 - - org.seamless - seamless-http - 1.1.0 - - org.seamless seamless-util diff --git a/libresonic-main/src/main/java/org/libresonic/player/command/PersonalSettingsCommand.java b/libresonic-main/src/main/java/org/libresonic/player/command/PersonalSettingsCommand.java index 81f5d3ec..bea8cd23 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/command/PersonalSettingsCommand.java +++ b/libresonic-main/src/main/java/org/libresonic/player/command/PersonalSettingsCommand.java @@ -57,6 +57,7 @@ public class PersonalSettingsCommand { private boolean songNotificationEnabled; private boolean queueFollowingSongs; private boolean lastFmEnabled; + private int listReloadDelay; private String lastFmUsername; private String lastFmPassword; private boolean isReloadNeeded; @@ -237,6 +238,14 @@ public class PersonalSettingsCommand { this.lastFmEnabled = lastFmEnabled; } + public int getListReloadDelay() { + return listReloadDelay; + } + + public void setListReloadDelay(int listReloadDelay) { + this.listReloadDelay = listReloadDelay; + } + public String getLastFmUsername() { return lastFmUsername; } diff --git a/libresonic-main/src/main/java/org/libresonic/player/command/PlayerSettingsCommand.java b/libresonic-main/src/main/java/org/libresonic/player/command/PlayerSettingsCommand.java index 6ee0a32d..89260232 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/command/PlayerSettingsCommand.java +++ b/libresonic-main/src/main/java/org/libresonic/player/command/PlayerSettingsCommand.java @@ -41,6 +41,7 @@ public class PlayerSettingsCommand { private Date lastSeen; private boolean isDynamicIp; private boolean isAutoControlEnabled; + private boolean isM3uBomEnabled; private String technologyName; private String transcodeSchemeName; private boolean transcodingSupported; @@ -109,6 +110,14 @@ public class PlayerSettingsCommand { isAutoControlEnabled = autoControlEnabled; } + public boolean isM3uBomEnabled() { + return isM3uBomEnabled; + } + + public void setM3uBomEnabled(boolean m3uBomEnabled) { + isM3uBomEnabled = m3uBomEnabled; + } + public String getTranscodeSchemeName() { return transcodeSchemeName; } diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/HomeController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/HomeController.java index 8f943a54..c6b0ef68 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/HomeController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/HomeController.java @@ -76,8 +76,8 @@ public class HomeController extends ParameterizableViewController { } int listOffset = getIntParameter(request, "listOffset", 0); AlbumListType listType = AlbumListType.fromId(getStringParameter(request, "listType")); + UserSettings userSettings = settingsService.getUserSettings(user.getUsername()); if (listType == null) { - UserSettings userSettings = settingsService.getUserSettings(user.getUsername()); listType = userSettings.getDefaultAlbumList(); } @@ -140,6 +140,7 @@ public class HomeController extends ParameterizableViewController { map.put("coverArtSize", CoverArtScheme.MEDIUM.getSize()); map.put("listOffset", listOffset); map.put("musicFolder", selectedMusicFolder); + map.put("listReloadDelay", userSettings.getListReloadDelay()); ModelAndView result = super.handleRequestInternal(request, response); result.addObject("model", map); diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/M3UController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/M3UController.java index d41df2ec..e04cd4ad 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/M3UController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/M3UController.java @@ -74,6 +74,9 @@ public class M3UController implements Controller { } private void createClientSidePlaylist(PrintWriter out, Player player, String url) throws Exception { + if (player.isM3uBomEnabled()) { + out.print("\ufeff"); + } out.println("#EXTM3U"); List result; synchronized (player.getPlayQueue()) { @@ -99,6 +102,9 @@ public class M3UController implements Controller { url += "&suffix=." + suffix; } + if (player.isM3uBomEnabled()) { + out.print("\ufeff"); + } out.println("#EXTM3U"); out.println("#EXTINF:-1,Libresonic"); out.println(url); diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java index 00e318aa..e37b736e 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/MultiController.java @@ -237,6 +237,7 @@ public class MultiController extends MultiActionController { Map map = new HashMap(); map.put("showRight", userSettings.isShowNowPlayingEnabled() || userSettings.isShowChatEnabled()); map.put("autoHidePlayQueue", userSettings.isAutoHidePlayQueue()); + map.put("listReloadDelay", userSettings.getListReloadDelay()); map.put("showSideBar", userSettings.isShowSideBar()); map.put("brand", settingsService.getBrand()); return new ModelAndView("index", "model", map); diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/PersonalSettingsController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/PersonalSettingsController.java index 64808a2c..e772c224 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/PersonalSettingsController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/PersonalSettingsController.java @@ -73,6 +73,7 @@ public class PersonalSettingsController extends SimpleFormController { command.setBetaVersionNotificationEnabled(userSettings.isBetaVersionNotificationEnabled()); command.setSongNotificationEnabled(userSettings.isSongNotificationEnabled()); command.setAutoHidePlayQueue(userSettings.isAutoHidePlayQueue()); + command.setListReloadDelay(userSettings.getListReloadDelay()); command.setLastFmEnabled(userSettings.isLastFmEnabled()); command.setLastFmUsername(userSettings.getLastFmUsername()); command.setLastFmPassword(userSettings.getLastFmPassword()); @@ -135,6 +136,7 @@ public class PersonalSettingsController extends SimpleFormController { settings.setBetaVersionNotificationEnabled(command.isBetaVersionNotificationEnabled()); settings.setSongNotificationEnabled(command.isSongNotificationEnabled()); settings.setAutoHidePlayQueue(command.isAutoHidePlayQueue()); + settings.setListReloadDelay(command.getListReloadDelay()); settings.setLastFmEnabled(command.isLastFmEnabled()); settings.setLastFmUsername(command.getLastFmUsername()); settings.setSystemAvatarId(getSystemAvatarId(command)); diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/PlayerSettingsController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/PlayerSettingsController.java index 712aa6f0..2a6d5d28 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/controller/PlayerSettingsController.java +++ b/libresonic-main/src/main/java/org/libresonic/player/controller/PlayerSettingsController.java @@ -72,6 +72,7 @@ public class PlayerSettingsController extends SimpleFormController { command.setLastSeen(player.getLastSeen()); command.setDynamicIp(player.isDynamicIp()); command.setAutoControlEnabled(player.isAutoControlEnabled()); + command.setM3uBomEnabled(player.isM3uBomEnabled()); command.setTranscodeSchemeName(player.getTranscodeScheme().name()); command.setTechnologyName(player.getTechnology().name()); command.setAllTranscodings(transcodingService.getAllTranscodings()); @@ -99,6 +100,7 @@ public class PlayerSettingsController extends SimpleFormController { Player player = playerService.getPlayerById(command.getPlayerId()); player.setAutoControlEnabled(command.isAutoControlEnabled()); + player.setM3uBomEnabled(command.isM3uBomEnabled()); player.setDynamicIp(command.isDynamicIp()); player.setName(StringUtils.trimToNull(command.getName())); player.setTranscodeScheme(TranscodeScheme.valueOf(command.getTranscodeSchemeName())); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/HsqlDaoHelper.java b/libresonic-main/src/main/java/org/libresonic/player/dao/HsqlDaoHelper.java index 98137858..43880551 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/HsqlDaoHelper.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/HsqlDaoHelper.java @@ -52,6 +52,8 @@ import org.libresonic.player.dao.schema.hsql.Schema50; import org.libresonic.player.dao.schema.hsql.Schema51; import org.libresonic.player.dao.schema.hsql.Schema52; import org.libresonic.player.dao.schema.hsql.Schema53; +import org.libresonic.player.dao.schema.hsql.Schema61; +import org.libresonic.player.dao.schema.hsql.Schema62; import org.libresonic.player.service.SettingsService; /** @@ -67,7 +69,8 @@ public class HsqlDaoHelper implements DaoHelper { new Schema30(), new Schema31(), new Schema32(), new Schema33(), new Schema34(), new Schema35(), new Schema36(), new Schema37(), new Schema38(), new Schema40(), new Schema43(), new Schema45(), new Schema46(), new Schema47(), new Schema49(), - new Schema50(), new Schema51(), new Schema52(), new Schema53()}; + new Schema50(), new Schema51(), new Schema52(), new Schema53(), new Schema61(), + new Schema62()}; private DataSource dataSource; private static boolean shutdownHookAdded; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java index d470452d..37d9f6a4 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java @@ -35,7 +35,7 @@ import java.util.*; public class PlayerDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(PlayerDao.class); - private static final String COLUMNS = "id, name, type, username, ip_address, auto_control_enabled, " + + private static final String COLUMNS = "id, name, type, username, ip_address, auto_control_enabled, m3u_bom_enabled, " + "last_seen, cover_art_scheme, transcode_scheme, dynamic_ip, technology, client_id"; private PlayerRowMapper rowMapper = new PlayerRowMapper(); @@ -94,7 +94,7 @@ public class PlayerDao extends AbstractDao { player.setId(String.valueOf(id)); String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")"; update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(), - player.getIpAddress(), player.isAutoControlEnabled(), + player.getIpAddress(), player.isAutoControlEnabled(), player.isM3uBomEnabled(), player.getLastSeen(), CoverArtScheme.MEDIUM.name(), player.getTranscodeScheme().name(), player.isDynamicIp(), player.getTechnology().name(), player.getClientId()); @@ -143,6 +143,7 @@ public class PlayerDao extends AbstractDao { "username = ?," + "ip_address = ?," + "auto_control_enabled = ?," + + "m3u_bom_enabled = ?," + "last_seen = ?," + "transcode_scheme = ?, " + "dynamic_ip = ?, " + @@ -150,7 +151,7 @@ public class PlayerDao extends AbstractDao { "client_id = ? " + "where id = ?"; update(sql, player.getName(), player.getType(), player.getUsername(), - player.getIpAddress(), player.isAutoControlEnabled(), + player.getIpAddress(), player.isAutoControlEnabled(), player.isM3uBomEnabled(), player.getLastSeen(), player.getTranscodeScheme().name(), player.isDynamicIp(), player.getTechnology(), player.getClientId(), player.getId()); } @@ -174,6 +175,7 @@ public class PlayerDao extends AbstractDao { player.setUsername(rs.getString(col++)); player.setIpAddress(rs.getString(col++)); player.setAutoControlEnabled(rs.getBoolean(col++)); + player.setM3uBomEnabled(rs.getBoolean(col++)); player.setLastSeen(rs.getTimestamp(col++)); col++; // Ignore cover art scheme. player.setTranscodeScheme(TranscodeScheme.valueOf(rs.getString(col++))); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java index abd1ac2e..87c3d81a 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java @@ -44,7 +44,7 @@ public class UserDao extends AbstractDao { "playlist_year, playlist_bit_rate, playlist_duration, playlist_format, playlist_file_size, " + "last_fm_enabled, last_fm_username, last_fm_password, transcode_scheme, show_now_playing, selected_music_folder_id, " + "party_mode_enabled, now_playing_allowed, avatar_scheme, system_avatar_id, changed, show_chat, show_artist_info, auto_hide_play_queue, " + - "view_as_list, default_album_list, queue_following_songs, show_side_bar"; + "view_as_list, default_album_list, queue_following_songs, show_side_bar, list_reload_delay"; private static final Integer ROLE_ID_ADMIN = 1; private static final Integer ROLE_ID_DOWNLOAD = 2; @@ -188,7 +188,7 @@ public class UserDao extends AbstractDao { settings.getAvatarScheme().name(), settings.getSystemAvatarId(), settings.getChanged(), settings.isShowChatEnabled(), settings.isShowArtistInfoEnabled(), settings.isAutoHidePlayQueue(), settings.isViewAsList(), settings.getDefaultAlbumList().getId(), settings.isQueueFollowingSongs(), - settings.isShowSideBar()}); + settings.isShowSideBar(), settings.getListReloadDelay()}); } private static String encrypt(String s) { @@ -349,6 +349,7 @@ public class UserDao extends AbstractDao { settings.setDefaultAlbumList(AlbumListType.fromId(rs.getString(col++))); settings.setQueueFollowingSongs(rs.getBoolean(col++)); settings.setShowSideBar(rs.getBoolean(col++)); + settings.setListReloadDelay((Integer) rs.getObject(col++)); return settings; } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema61.java b/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema61.java new file mode 100644 index 00000000..d2634efa --- /dev/null +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema61.java @@ -0,0 +1,48 @@ +/* + * This file is part of Libresonic. + * + * Libresonic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libresonic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Libresonic. If not, see . + */ +package org.libresonic.player.dao.schema.hsql; + +import org.springframework.jdbc.core.JdbcTemplate; + +import org.libresonic.player.Logger; +import org.libresonic.player.dao.schema.Schema; + +/** + * Used for creating and evolving the database schema. + * This class implements the database schema for Libresonic version 6.1. + * + * @author François-Xavier Thomas + */ +public class Schema61 extends Schema { + + private static final Logger LOG = Logger.getLogger(Schema61.class); + + @Override + public void execute(JdbcTemplate template) { + + if (template.queryForInt("select count(*) from version where version = 26") == 0) { + LOG.info("Updating database schema to version 26."); + template.execute("insert into version values (26)"); + } + + if (!columnExists(template, "list_reload_delay", "user_settings")) { + LOG.info("Database column 'user_settings.list_reload_delay' not found. Creating it."); + template.execute("alter table user_settings add list_reload_delay int default 60 not null"); + LOG.info("Database column 'user_settings.list_reload_delay' was added successfully."); + } + } +} diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema62.java b/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema62.java new file mode 100644 index 00000000..0e945944 --- /dev/null +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/schema/hsql/Schema62.java @@ -0,0 +1,48 @@ +/* + * This file is part of Libresonic. + * + * Libresonic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libresonic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Libresonic. If not, see . + */ +package org.libresonic.player.dao.schema.hsql; + +import org.springframework.jdbc.core.JdbcTemplate; + +import org.libresonic.player.Logger; +import org.libresonic.player.dao.schema.Schema; + +/** + * Used for creating and evolving the database schema. + * This class implements the database schema for Libresonic version 6.1. + * + * @author Shen-Ta Hsieh + */ +public class Schema62 extends Schema { + + private static final Logger LOG = Logger.getLogger(Schema62.class); + + @Override + public void execute(JdbcTemplate template) { + + if (template.queryForInt("select count(*) from version where version = 27") == 0) { + LOG.info("Updating database schema to version 27."); + template.execute("insert into version values (27)"); + } + + if (!columnExists(template, "player", "m3u_bom_enabled")) { + LOG.info("Database column 'player.m3u_bom_enabled' not found. Creating it."); + template.execute("alter table player add m3u_bom_enabled boolean default false not null"); + LOG.info("Database column 'player.m3u_bom_enabled' was added successfully."); + } + } +} diff --git a/libresonic-main/src/main/java/org/libresonic/player/domain/PlayQueue.java b/libresonic-main/src/main/java/org/libresonic/player/domain/PlayQueue.java index 16401e34..2cc2ae42 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/domain/PlayQueue.java +++ b/libresonic-main/src/main/java/org/libresonic/player/domain/PlayQueue.java @@ -241,7 +241,8 @@ public class PlayQueue { MediaFile currentFile = getCurrentFile(); Collections.shuffle(files); if (currentFile != null) { - index = files.indexOf(currentFile); + Collections.swap(files, files.indexOf(currentFile), 0); + index = 0; } } diff --git a/libresonic-main/src/main/java/org/libresonic/player/domain/Player.java b/libresonic-main/src/main/java/org/libresonic/player/domain/Player.java index 8a14ecdd..9ef3fa38 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/domain/Player.java +++ b/libresonic-main/src/main/java/org/libresonic/player/domain/Player.java @@ -40,6 +40,7 @@ public class Player { private String ipAddress; private boolean isDynamicIp = true; private boolean isAutoControlEnabled = true; + private boolean isM3uBomEnabled = true; private Date lastSeen; private TranscodeScheme transcodeScheme = TranscodeScheme.OFF; private PlayQueue playQueue; @@ -188,6 +189,24 @@ public class Player { this.isAutoControlEnabled = isAutoControlEnabled; } + /** + * Returns whether apply BOM mark when generating a M3U file. + * + * @return Whether apply BOM mark when generating a M3U file. + */ + public boolean isM3uBomEnabled() { + return isM3uBomEnabled; + } + + /** + * Sets whether apply BOM mark when generating a M3U file. + * + * @param isM3uBomEnabled Whether apply BOM mark when generating a M3U file. + */ + public void setM3uBomEnabled(boolean isM3uBomEnabled) { + this.isM3uBomEnabled = isM3uBomEnabled; + } + /** * Returns the time when the player was last seen. * diff --git a/libresonic-main/src/main/java/org/libresonic/player/domain/UserSettings.java b/libresonic-main/src/main/java/org/libresonic/player/domain/UserSettings.java index 6b587fd1..05a9139c 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/domain/UserSettings.java +++ b/libresonic-main/src/main/java/org/libresonic/player/domain/UserSettings.java @@ -46,6 +46,7 @@ public class UserSettings { private Visibility mainVisibility = new Visibility(); private Visibility playlistVisibility = new Visibility(); private boolean lastFmEnabled; + private int listReloadDelay; private String lastFmUsername; private String lastFmPassword; private TranscodeScheme transcodeScheme = TranscodeScheme.OFF; @@ -156,6 +157,14 @@ public class UserSettings { this.lastFmEnabled = lastFmEnabled; } + public int getListReloadDelay() { + return listReloadDelay; + } + + public void setListReloadDelay(int listReloadDelay) { + this.listReloadDelay = listReloadDelay; + } + public String getLastFmUsername() { return lastFmUsername; } diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java b/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java index 63b454a0..2c579baf 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java +++ b/libresonic-main/src/main/java/org/libresonic/player/service/SettingsService.java @@ -1270,6 +1270,7 @@ public class SettingsService { settings.setQueueFollowingSongs(true); settings.setDefaultAlbumList(AlbumListType.RANDOM); settings.setLastFmEnabled(false); + settings.setListReloadDelay(60); settings.setLastFmUsername(null); settings.setLastFmPassword(null); settings.setChanged(new Date()); diff --git a/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_en.properties b/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_en.properties index 8f240eb2..a71e11bb 100644 --- a/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_en.properties +++ b/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_en.properties @@ -378,6 +378,7 @@ personalsettings.autohideplayqueue = Auto-hide play queue personalsettings.finalversionnotification = Notify me about new versions personalsettings.betaversionnotification = Notify me about new beta versions personalsettings.songnotification = Notify me when new songs are played (not supported by all browsers) +personalsettings.listreloaddelay = Album list reload delay (in seconds, 0 disables) personalsettings.lastfmenabled = Register what I'm playing at Last.fm personalsettings.lastfmusername = Last.fm username personalsettings.lastfmpassword = Last.fm password @@ -511,6 +512,7 @@ playersettings.name = Player name playersettings.maxbitrate = Max bitrate playersettings.notranscoder = Notice: Transcoders does not appear to be installed.
Click Help button for more information. playersettings.autocontrol = Control player automatically +playersettings.m3ubom = Apply BOM signature in the generated M3U file playersettings.dynamicip = Player has dynamic IP address playersettings.transcodings = Active transcodings playersettings.ok = Save @@ -817,6 +819,8 @@ helppopup.playername.text =

Allows you to specify an easy-to-remember name fo helppopup.autocontrol.title = Control player automatically helppopup.autocontrol.text =

With this option selected, {0} will automatically start the player when you click "Play" \ in the playlist. Otherwise, you must start and connect the player yourself.

+helppopup.m3ubom.title = Apply BOM in M3U file +helppopup.m3ubom.text =

Apply a BOM mark in generated M3U playlists for Unicode compatibility.

helppopup.dynamicip.title = Dynamic IP address helppopup.dynamicip.text =

Turn off this option if the player uses a static IP address.

helppopup.smtpServer.title = SMTP Server diff --git a/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_zh_TW.properties b/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_zh_TW.properties index 272cf257..e3ff6b3a 100644 --- a/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_zh_TW.properties +++ b/libresonic-main/src/main/resources/org/libresonic/player/i18n/ResourceBundle_zh_TW.properties @@ -1,44 +1,71 @@ # -# Taiwan localization. +# Traditional Chinese (Taiwan) localization. # Author: Cheng Jen Li # chengjen.li@gmail.com +# Author: Shen-Ta Hsieh +# ibmibmibm.tw@gmail.com # common.home = \u9996\u9801 -common.back = \u56DE\u5FA9 -common.help = \u5354\u52A9 +common.back = \u4E0A\u4E00\u9801 +common.help = \u8AAA\u660E common.play = \u64AD\u653E common.add = \u65B0\u589E common.download = \u4E0B\u8F09 common.close = \u95DC\u9589 -common.refresh = \u5237\u65B0 -common.next = \u4E0B\u9801 -common.previous = \u4E0A\u9801 +common.refresh = \u91CD\u65B0\u6574\u7406 +common.next = \u4E0B\u4E00\u9801 +common.previous = \u4E0A\u4E00\u9801 common.more = \u66F4\u591A common.ok = \u78BA\u5B9A common.cancel = \u53D6\u6D88 common.save = \u5132\u5B58 common.create = \u5EFA\u7ACB common.delete = \u522A\u9664 +common.edit = \u7DE8\u8F2F +common.confirm = \u8ACB\u78BA\u8A8D common.unknown = (\u672A\u77E5) common.default = (\u9810\u8A2D\u503C) +common.settingssaved = \u8A2D\u5B9A\u5DF2\u5132\u5B58\u3002 +common.trialexpired = \u8A66\u7528\u7248\u5C07\u65BC {0} \u5230\u671F\u3002\u53D6\u5F97Subsonic Premium\u4F86\u4F7F\u7528\u9019\u500B\u529F\u80FD\u3002 +common.trialnotexpired = \u9019\u500B\u529F\u80FD\u5728 {0} \u4E4B\u524D\u90FD\u53EF\u4F7F\u7528\u3002\u4E4B\u5F8C\u60A8\u5FC5\u9808\u53D6\u5F97Subsonic Premium\u624D\u80FD\u4F7F\u7528\u3002 # login.jsp login.username = \u5E33\u865F login.password = \u5BC6\u78BC login.login = \u767B\u5165 login.remember = \u8A18\u5F97\u6211 -login.logout = \u60A8\u5DF2\u7D93\u767B\u51FA. -login.error = \u5E33\u865F\u6216\u662F\u5BC6\u78BC\u932F\u8AA4. -login.insecure = {0} \u672A\u53D7\u4FDD\u8B77. \u8ACB\u5148\u4EE5\u4F7F\u7528\u8005\u53CA\u5BC6\u78BC "admin"\u767B\u5165, \u6216\u9EDE\u64CA \u9019\u88E1. \u4E26\u4E14\u7ACB\u523B\u8B8A\u66F4\u60A8\u7684\u5BC6\u78BC. +login.logout = \u60A8\u5DF2\u7D93\u767B\u51FA\u3002 +login.error = \u5E33\u865F\u6216\u662F\u5BC6\u78BC\u932F\u8AA4\u3002 +login.insecure = {0} \u672A\u53D7\u4FDD\u8B77\u3002\u8ACB\u5148\u4EE5\u4F7F\u7528\u8005\u53CA\u5BC6\u78BC "admin"\u767B\u5165\uFF0C\u6216\u9EDE\u9078 \u9019\u88E1\uFF0C\u4E26\u4E14\u7ACB\u523B\u8B8A\u66F4\u60A8\u7684\u5BC6\u78BC\u3002 +login.recover = \u5FD8\u8A18\u5BC6\u78BC\uFF1F + +# recover.jsp +recover.title = \u5FD8\u8A18\u5BC6\u78BC\uFF1F +recover.text = \u8981\u91CD\u8A2D\u5BC6\u78BC\uFF0C\u8ACB\u5728\u4E0B\u65B9\u8F38\u5165\u60A8\u7684\u5E33\u865F\u6216\u662FEmail\u4F4D\u5740\u3002 +recover.username = \u5E33\u865F\u6216Email\u4F4D\u5740 +recover.send = \u91CD\u8A2D\u5BC6\u78BC\u4E26\u5BC4\u7D66\u6211 +recover.success = \u60A8\u7684\u5BC6\u78BC\u5DF2\u91CD\u8A2D\u4E26\u5BC4\u5230\u4E86 {0} \u3002 +recover.error.usernotfound = \u62B1\u6B49\uFF0C\u672A\u627E\u5230\u4F7F\u7528\u8005\u3002 +recover.error.noemail = \u62B1\u6B49\uFF0C\u8A72\u4F7F\u7528\u8005\u672A\u8A3B\u518A\u4FE1\u7BB1\u3002 +recover.error.sendfailed = Email\u5BC4\u9001\u5931\u6557\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66\u3002 +recover.error.invalidcaptcha = \u62B1\u6B49\uFF0C\u8F38\u5165\u7684CAPTCHA\u6587\u5B57\u6709\u8AA4\uFF0C\u8ACB\u518D\u8A66\u4E00\u6B21\u3002 # accessDenied.jsp accessDenied.title = \u62D2\u7D55\u5B58\u53D6 -accessDenied.text = \u62B1\u6B49\uFF0C\u60A8\u7121\u6B0A\u57F7\u884C\u6240\u8ACB\u6C42\u7684\u64CD\u4F5C. +accessDenied.text = \u62B1\u6B49\uFF0C\u60A8\u7121\u6B0A\u57F7\u884C\u6240\u8ACB\u6C42\u7684\u64CD\u4F5C\u3002 + +# notFound.jsp +notFound.title = \u627E\u4E0D\u5230 +notFound.text =

Sorry, we could not find what you were looking for.

Try reloading the web page. If that doesn't help, \ + try scanning the media folders again.

+notFound.reload = \u91CD\u65B0\u6574\u7406\u9801\u9762 +notFound.scan = Media folders settings # top.jsp top.home = \u9996\u9801 top.now_playing = \u64AD\u653E +top.starred = Starred top.settings = \u8A2D\u5B9A top.status = \u72C0\u614B top.podcast = \u64AD\u5BA2 @@ -46,32 +73,40 @@ top.more = \u5176\u4ED6 top.help = \u95DC\u65BC top.search = \u641C\u5C0B top.upgrade = \u6709\u65B0\u7248\u672C\u63D0\u4F9B. \u4E0B\u8F09 {0} {1} \ - \u9019\u88E1. -top.missing = \u627E\u4E0D\u5230\u97F3\u6A02\u593E\uFF0C\u8ACB\u91CD\u65B0\u8A2D\u5B9A. + \u9019\u88E1\u3002 +top.missing = \u627E\u4E0D\u5230\u97F3\u6A02\u8CC7\u6599\u593E\uFF0C\u8ACB\u91CD\u65B0\u8A2D\u5B9A\u3002 top.logout =\u767B\u51FA{0} +top.getpremium = \u53D6\u5F97 Subsonic Premium +top.gotpremium = Subsonic Premium +top.trialdaysleft = \u5269\u4E0B {0} \u5929\u9AD4\u9A57\u6642\u9593 # left.jsp -left.statistics = \u97F3\u6A02\u76D2\u6709 \ - {0} \u4F4D\u6B4C\u624B
\ +left.scanning = \u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E\u4E2D\u2026 +left.statistics = {0} \u4F4D\u6B4C\u624B
\ {1} \u5F35\u5C08\u8F2F
\ {2} \u9996\u6B4C\u66F2
\ - {3} (\u7D04 {4} \u5C0F\u6642) + {3}
\ + {4} \u5C0F\u6642 left.shortcut = \u6377\u5F91 +left.playlists = \u64AD\u653E\u6E05\u55AE left.radio = \u7DDA\u4E0A\u96FB\u8996/\u6536\u97F3\u6A5F left.allfolders = \u5168\u90E8 +left.showallplaylists = \u986F\u793A\u5168\u90E8 +left.createplaylist = \u5EFA\u7ACB\u65B0\u7684\u64AD\u653E\u6E05\u55AE +left.importplaylist = \u532F\u5165\u64AD\u653E\u6E05\u55AE -# playlist.jsp +# playQueue.jsp playlist.stop = \u505C\u6B62 playlist.start = \u64AD\u653E -playlist.confirmclear = \u78BA\u5B9A\u522A\u9664\u9EDE\u64AD\u6E05\u55AE? +playlist.confirmclear = \u78BA\u5B9A\u522A\u9664\u64AD\u653E\u6E05\u55AE? playlist.clear = \u6E05\u9664 playlist.shuffle = \u96A8\u8208\u64AD\u653E playlist.repeat_on = \u91CD\u64AD playlist.repeat_off = \u4E0D\u91CD\u64AD playlist.undo = \u53D6\u6D88 playlist.settings = \u8A2D\u5B9A -playlist.more = \u5176\u4ED6... -playlist.more.playlist = \u9EDE\u64AD\u6E05\u55AE +playlist.more = \u5176\u4ED6\u2026 +playlist.more.playlist = \u64AD\u653E\u6E05\u55AE playlist.more.sortbytrack = \u97F3\u8ECC\u6392\u5E8F playlist.more.sortbyartist = \u6B4C\u624B\u6392\u5E8F playlist.more.sortbyalbum = \u5C08\u8F2F\u6392\u5E8F @@ -79,12 +114,41 @@ playlist.more.selection = \u9078\u6B4C playlist.more.selectall = \u5168\u9078 playlist.more.selectnone = \u5168\u4E0D\u9078 playlist.getflash = \u53D6\u5F97Flash\u64A5\u653E\u5668 +playlist.saveplayqueue = \u5132\u5B58\u64AD\u653E\u4F47\u5217 +playlist.loadplayqueue = \u8F09\u5165\u64AD\u653E\u4F47\u5217 playlist.save = \u5132\u5B58 playlist.append = \u52A0\u5165\u6E05\u55AE playlist.remove = \u79FB\u9664 playlist.up = \u4E0A playlist.down = \u4E0B -playlist.empty = \u7A7A\u7684\u9EDE\u64AD\u6E05\u55AE +playlist.empty = \u7A7A\u7684\u64AD\u653E\u6E05\u55AE +playlist.toast.appendtoplaylist = \u64AD\u653E\u6E05\u55AE\u5DF2\u66F4\u65B0\u3002 +playlist.toast.saveasplaylist = \u64AD\u653E\u6E05\u55AE\u5DF2\u5132\u5B58\u3002 +playlist.toast.saveplayqueue = \u64AD\u653E\u4F47\u5217\u5DF2\u5132\u5B58\u3002 +playlist.missing = \u907A\u5931 + +# playlist.jsp +playlist2.noplaylists = \u60A8\u9084\u672A\u5EFA\u7ACB\u4EFB\u4F55\u6E05\u55AE\u3002 +playlist2.created = \u7531 {0} \u5EFA\u7ACB\u7684 {1} +playlist2.songs = \u6B4C\u66F2 +playlist2.shared = \u5176\u4ED6\u4EBA\u4E5F\u53EF\u770B\u898B +playlist2.notshared = \u5176\u4ED6\u4EBA\u7121\u6CD5\u770B\u898B +playlist2.name = \u64AD\u653E\u6E05\u55AE\u540D\u7A31 +playlist2.comment = \u64AD\u653E\u6E05\u55AE\u8A3B\u89E3 +playlist2.public = \u4F7F\u6B64\u64AD\u653E\u6E05\u55AE\u53EF\u88AB\u5176\u4ED6\u4EBA\u4F7F\u7528\u3002 +playlist2.confirmdelete = \u60A8\u78BA\u5B9A\u8981\u522A\u9664\u6B64\u64AD\u653E\u6E05\u55AE\u55CE\uFF1F +playlist2.empty = \u64AD\u653E\u6E05\u55AE\u70BA\u7A7A +playlist2.export = \u532F\u51FA + +# importPlaylist.jsp +importPlaylist.title = Import playlist +importPlaylist.text = Select playlist to import (m3u, pls, xspf) +importPlaylist.success = Successfully imported playlist "{0}". +importPlaylist.error = Failed to import playlist. {0} + +# videoPlayer.jsp +videoPlayer.getflash = Please install Flash Player +videoPlayer.getpremium = Get Subsonic Premium to play on Chromecast. # status.jsp status.title = \u72C0\u614B @@ -98,46 +162,67 @@ status.current = \u76EE\u524D\u64AD\u653E status.transmitted = \u50B3\u8F38 status.bitrate = Bitrate (Kbps) +# starred.jsp +starred.title = My starred items +starred.empty = Click the star icons to mark your favorite artist, albums and songs. + # search.jsp search.title = \u641C\u5C0B +search.query = \u6B4C\u624B\u3001\u5C08\u8F2F\u6216\u6B4C\u66F2\u6A19\u984C\u3002 search.search = \u641C\u5C0B -search.index = \u6B63\u5728\u5EFA\u7ACB\u7D22\u5F15\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66! -search.hits.none = \u627E\u4E0D\u5230. +search.index = \u6B63\u5728\u5EFA\u7ACB\u7D22\u5F15\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66\uFF01 +search.hits.none = \u627E\u4E0D\u5230\u3002 +search.hits.more = \u66F4\u591A +search.hits.artists = \u6B4C\u624B +search.hits.albums = \u5C08\u8F2F +search.hits.songs = \u6B4C\u66F2 +search.hits.videos = \u5F71\u50CF # gettingStarted.jsp gettingStarted.title = \u521D\u6B21\u4F7F\u7528 -gettingStarted.text =

\u6B61\u8FCE\u4F7F\u7528Libresonic!
\u8ACB\u4F9D\u7167\u4E0B\u9762\u7684\u6B65\u9A5F\u8A2D\u5B9A.
\ - \u9EDE\u64CA\u5DE5\u5177\u5217\u4E0A\u7684"\u9996\u9801"\uFF0C\u5C31\u80FD\u96A8\u6642\u56DE\u4F86\u9019\u88E1\uFF01.

\ +gettingStarted.text =

\u6B61\u8FCE\u4F7F\u7528Libresonic\uFF01
\u8ACB\u4F9D\u7167\u4E0B\u9762\u7684\u6B65\u9A5F\u8A2D\u5B9A\u3002
\ + \u9EDE\u64CA\u5DE5\u5177\u5217\u4E0A\u7684"\u9996\u9801"\uFF0C\u5C31\u80FD\u96A8\u6642\u56DE\u4F86\u9019\u88E1\u3002

\

\u9700\u8981\u66F4\u591A\u8A0A\u606F\u8ACB\u53C3\u8003\u5165\u9580\u6307\u5357

-gettingStarted.step1.title = \u8B8A\u66F4\u7BA1\u7406\u54E1\u7684\u5BC6\u78BC. +gettingStarted.root = \u8B66\u544A\uFF01Libresonic\u7A0B\u5F0F\u6B63\u4EE5 root \u4F7F\u7528\u8005\u57F7\u884C\u3002\u8ACB\u8003\u616E \ + \u5225\u7684\u65B9\u5F0F\u3002 +gettingStarted.step1.title = \u8B8A\u66F4\u7BA1\u7406\u54E1\u7684\u5BC6\u78BC\u3002 gettingStarted.step1.text = \u8ACB\u4FEE\u6539\u9810\u8A2D\u7684\u7BA1\u7406\u54E1\u5BC6\u78BC\uFF0C\u4EE5\u78BA\u4FDD\u4F3A\u670D\u5668\u7684\u5B89\u5168\u3002\ - \u4E5F\u53EF\u4EE5\u5EFA\u7ACB\u65B0\u7684\u4F7F\u7528\u8005\u4E26\u7D66\u4E88\u4E0D\u540C\u7684\u6B0A\u9650 -gettingStarted.step2.title = \u8A2D\u5B9A\u97F3\u6A02\u593E. + \u4E5F\u53EF\u4EE5\u5EFA\u7ACB\u65B0\u7684\u4F7F\u7528\u8005\u4E26\u7D66\u4E88\u4E0D\u540C\u7684\u6B0A\u9650\u3002 +gettingStarted.step2.title = \u8A2D\u5B9A\u97F3\u6A02\u8CC7\u6599\u593E\u3002 gettingStarted.step2.text = \u8A2D\u5B9A\u60A8\u97F3\u6A02\u6240\u653E\u7F6E\u7684\u8CC7\u6599\u593E\u3002 -gettingStarted.step3.title = \u914D\u7F6E\u7DB2\u8DEF\u8A2D\u5B9A. +gettingStarted.step3.title = \u914D\u7F6E\u7DB2\u8DEF\u8A2D\u5B9A\u3002 gettingStarted.step3.text = \u5982\u679C\u60A8\u8981\u900F\u904E\u7DB2\u969B\u7DB2\u8DEF\u6216\u662F\u8207\u60A8\u7684\u670B\u53CB\u3001\u5BB6\u4EBA\u5206\u4EAB\u3002\ - \u4E26\u53D6\u5F97\u60A8\u7684\u5C08\u5C6C\u7DB2\u5740\u50CF\u662Fyourname.libresonic.org. + \u4E26\u53D6\u5F97\u60A8\u7684\u5C08\u5C6C\u7DB2\u5740\u50CF\u662Fyourname.libresonic.org\u3002 gettingStarted.hide = \u4E0B\u6B21\u4E0D\u986F\u793A\u672C\u9801\uFF01 -gettingStarted.hidealert = \u5982\u679C\u4E0B\u6B21\u9084\u9700\u8981\u986F\u793A\u63D0\u793A,\u8ACB\u5F9E \u8A2D\u5B9A->\u4E00\u822C \u4E2D\u52FE\u9078. +gettingStarted.hidealert = \u5982\u679C\u4E0B\u6B21\u9084\u9700\u8981\u986F\u793A\u63D0\u793A\uFF0C\u8ACB\u5F9E \u8A2D\u5B9A\u2192\u4E00\u822C \u4E2D\u52FE\u9078\u3002 # home.jsp home.random.title = \u96A8\u8208\u64AD\u653E +home.alphabetical.title = \u5168\u90E8 home.newest.title = \u6700\u65B0\u97F3\u6A02 +home.starred.title = \u661F\u865F\u6A19\u8A18 home.highest.title = \u559C\u597D\u7A0B\u5EA6 home.frequent.title = \u9EDE\u64AD\u7387 home.recent.title = \u6700\u8FD1\u64AD\u653E +home.decade.title = \u7531\u5E74\u4EFD +home.genre.title = \u7531\u66F2\u98A8 home.users.title = \u4F7F\u7528\u8005 home.random.text = \u96A8\u8208\u9078\u64AD\u5C08\u8F2F +home.alphabetical.text = \u6240\u6709\u5C08\u8F2F home.newest.text = \u6700\u65B0\u5C08\u8F2F +home.starred.text = \u60A8\u6A19\u8A18\u661F\u865F\u7684\u5C08\u8F2F home.highest.text = \u8A55\u50F9\u9AD8\u7684\u5C08\u8F2F home.frequent.text = \u6700\u591A\u9EDE\u64AD\u5C08\u8F2F home.recent.text =\u6700\u8FD1\u64AD\u653E\u5C08\u8F2F +home.decade.text = \u5E74\u4EFD +home.genre.text = \u66F2\u98A8 home.users.text = \u4F7F\u7528\u8005\u7D71\u8A08 -home.scan = \u97F3\u6A02\u593E\u5DF2\u7D93\u6383\u63CF. \u6240\u6709\u529F\u80FD\u5C1A\u672A\u958B\u653E. +home.scan = \u6B63\u5728\u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E\u3002\u90E8\u4EFD\u529F\u80FD\u5C07\u7121\u6CD5\u4F7F\u7528\u3002 home.albums = \u5C08\u8F2F {0} - {1} home.playcount = \u64AD\u653E\u4E86 {0} \u9996\u6B4C home.lastplayed = \u64AD\u653E {0} home.created = \u5EFA\u7ACB {0} +home.shuffle = \u96A8\u6A5F\u64AD\u653E home.chart.total = \u7E3D\u8A08 (MB) home.chart.stream = \u4E32\u6D41 (MB) home.chart.download = \u5DF2\u4E0B\u8F09(MB) @@ -148,70 +233,79 @@ more.title = \u5176\u4ED6 more.random.title = \u96A8\u8208\u64AD\u653E more.random.text = \u5EFA\u7ACB\u96A8\u8208\u6E05\u55AE more.random.songs = {0} \u9996 -more.random.auto = \u7576\u9EDE\u64AD\u6E05\u55AE\u64AD\u653E\u5B8C\u7562\u6642\u7E7C\u7E8C\u64AD\u653E\u66F4\u591A\u7684\u96A8\u8208\u6B4C\u66F2 . +more.random.auto = \u7576\u64AD\u653E\u6E05\u55AE\u64AD\u653E\u5B8C\u7562\u6642\u7E7C\u7E8C\u96A8\u6A5F\u64AD\u653E\u6B4C\u66F2\u3002 more.random.ok = \u78BA\u5B9A more.random.genre = \u66F2\u98A8 more.random.anygenre = \u4EFB\u610F more.random.year = \u5E74\u4EFD more.random.anyyear = \u4EFB\u610F -more.random.folder = \u97F3\u6A02\u593E +more.random.folder = \u97F3\u6A02\u8CC7\u6599\u593E more.random.anyfolder = \u4EFB\u610F more.apps.title = Libresonic Apps more.apps.text =

\u652F\u63F4 iPhone, \ - Android \u548C AIR\u7684Libresonic apps.

+ Android \u548C AIR\u7684Libresonic apps\u3002

+more.jamstash.title = JamStash +more.jamstash.text =

Jamstash \u662F Libresonic \u7684 HTML5 \u64AD\u653E\u5668\u3002\u9EDE\u9078\u9019\u88E1 \u4F86\u555F\u52D5\u3002 \ + \u4E5F\u53EF\u4EE5\u5728 Chrome App \u5167\u53D6\u5F97\u3002

+more.status.title = \u7DB2\u8DEF\u72C0\u614B +more.status.text = \u76E3\u63A7\u6240\u6709\u7DB2\u8DEF\u4E32\u6D41\u7684\u5373\u6642\u72C0\u614B\u3002 more.mobile.title = \u79FB\u52D5\u8A2D\u5099 -more.mobile.text =

\u53EF\u4EE5\u7531WAP\u96FB\u8A71\u6216PDA\u4F7F\u7528 {0} .
\ +more.mobile.text =

\u53EF\u4EE5\u7531 WAP \u96FB\u8A71\u6216 PDA \u4F7F\u7528 {0} \u3002
\ \u7D93\u7531\u624B\u6A5F\u8F38\u5165\u9019\u6A23\u7684\u7DB2\u5740 http://yourhostname/wap

\ -

\u7576\u7136\u60A8\u624B\u6A5F\u5FC5\u9808\u8981\u6709\u4E0A\u7DB2\u529F\u80FD!.

+

\u9019\u9700\u8981\u60A8\u7684\u4F3A\u670D\u5668\u53EF\u4EE5\u900F\u904E\u7DB2\u969B\u7DB2\u8DEF\u5B58\u53D6\u3002

more.podcast.title = \u64AD\u5BA2 -more.podcast.text =

\u5132\u5B58\u9EDE\u64AD\u6E05\u55AE\u7576\u6210\u64AD\u5BA2.
\ - \u7D93\u7531\u9019\u500B\u7DB2\u5740\u53EF\u4EE5\u6536\u807D: http://yourhostname/podcast, \ - \u6216\u662F \u9EDE\u6211.

+more.podcast.text =

\u5132\u5B58\u64AD\u653E\u6E05\u55AE\u7576\u6210\u64AD\u5BA2\u3002
\ + \u7D93\u7531\u9019\u500B\u7DB2\u5740\u53EF\u4EE5\u6536\u807D\uFF1A http://yourhostname/podcast\uFF0C\ + \u6216\u662F \u9EDE\u6211\u3002

more.upload.title = \u4E0A\u50B3\u6A94\u6848 more.upload.source = \u9078\u64C7\u6A94\u6848 more.upload.target = \u4E0A\u50B3\u5230 more.upload.browse = \u9078\u64C7 more.upload.ok = \u4E0A\u50B3 -more.upload.unzip = \u81EA\u52D5\u89E3\u58D3\u7E2Ezip\u6A94. -more.upload.progress = % \u5B8C\u6210. \u8ACB\u7A0D\u5019... +more.upload.unzip = \u81EA\u52D5\u89E3\u58D3\u7E2Ezip\u6A94\u3002 +more.upload.progress = % \u5B8C\u6210\u3002\u8ACB\u7A0D\u5019\u2026 # upload.jsp -upload.title = \u6A94\u6848\u4E0A\u50B3\u4E2D...... +upload.title = \u6A94\u6848\u4E0A\u50B3\u4E2D upload.success = \u4E0A\u50B3\u6210\u529F {0} -upload.empty = \u6C92\u6709\u4E0A\u50B3\u7684\u6A94\u6848\u5594. -upload.failed = \u6A94\u6848\u4E0A\u50B3\u5931\u6557\u56E0\u70BA:
"{0}" +upload.empty = \u6C92\u6709\u53EF\u4E0A\u50B3\u7684\u6A94\u6848\u3002 +upload.failed = \u6A94\u6848\u4E0A\u50B3\u6642\u767C\u751F\u932F\u8AA4\uFF1A
"{0}" upload.unzipped = \u89E3\u58D3\u7E2E {0} # help.jsp help.title = \u95DC\u65BC {0} -help.upgrade = \u6CE8\u610F! \u5DF2\u7D93\u6709\u65B0\u7684\u7248\u672C\u4E86\uFF0C\u4E0B\u8F09\u65B0\u7248 {0} {1} \ - \u5728\u9019. +help.upgrade = \u6CE8\u610F\uFF01 \u6709\u65B0\u7248\u672C\u53EF\u7528\u3002\u4E0B\u8F09 {0} {1} \ + \u8ACB\u9EDE\u9078\u9019\u88E1\u3002 +help.premium.title = \u6388\u6B0A +help.premium.expires = (\u904E\u671F {0}) +help.premium.upgrade = \u5347\u7D1A\u5230 Subsonic Premium \u4F86\u4F7F\u7528 \u66F4\u591A\u529F\u80FD\uFF01 +help.premium.expired = (\u6388\u6B0A\u904E\u671F\u65BC {0}) help.version.title = \u7248\u672C help.builddate.title = \u65E5\u671F help.server.title = \u4F3A\u670D\u5668 help.license.title = \u6388\u6B0A -help.license.text = {0} \u662F\u4EE5 GPL \u578B\u5F0F\u767C\u4F48\u6388\u6B0A\u7684\u81EA\u7531\u8EDF\u9AD4.
\ - {0} \u4F7F\u7528 \u7B2C\u4E09\u65B9\u6388\u6B0A. +help.license.text = {0} \u662F\u4EE5 GPL \u578B\u5F0F\u767C\u4F48\u6388\u6B0A\u7684\u81EA\u7531\u8EDF\u9AD4\u3002
{0} \u4F7F\u7528 \u7B2C\u4E09\u65B9\u6388\u6B0A\u3002 help.homepage.title = \u9996\u9801 help.forum.title = \u8AD6\u58C7 help.shop.title = \u5546\u54C1 help.contact.title = \u806F\u7E6B -help.contact.text = {0} \u7531 Sindre Mehus \u958B\u767C\u53CA\u7DAD\u8B77 \ - (sindre@activeobjects.no). \ - \u5982\u679C\u60A8\u6709\u4EFB\u4F55\u7591\u554F\uFF0C\u610F\u898B\u6216\u5EFA\u8B70\u6539\u5584\uFF0C\u8ACB\u5230 \ - Libresonic\u8AD6\u58C7. +help.contact.text = {0} \u7531 Sindre Mehus \u958B\u767C\u53CA\u7DAD\u8B77(sindre@activeobjects.no)\u3002\u5982\u679C\u60A8\u6709\u4EFB\u4F55\u7591\u554F\uFF0C\u610F\u898B\u6216\u5EFA\u8B70\u6539\u5584\uFF0C\u8ACB\u5230Libresonic\u8AD6\u58C7\u3002 help.log = \u8A18\u9304 -help.logfile = \u5B8C\u6574\u7684\u7D00\u9304\u5B58\u653E\u5728 {0}. +help.logfile = \u5B8C\u6574\u7684\u7D00\u9304\u5B58\u653E\u5728 {0}\u3002 # settingsHeader.jsp settingsheader.title = \u8A2D\u5B9A settingsheader.general = \u4E00\u822C settingsheader.advanced = \u9032\u968E settingsheader.personal = \u500B\u4EBA\u5316 -settingsheader.musicFolder = \u97F3\u6A02\u593E +settingsheader.musicFolder = \u97F3\u6A02\u8CC7\u6599\u593E settingsheader.internetRadio = \u7DDA\u4E0A\u96FB\u8996/\u6536\u97F3\u6A5F settingsheader.podcast = \u64AD\u5BA2 settingsheader.player = \u64AD\u653E\u5668 +settingsheader.dlna = DLNA/UPnP +settingsheader.sonos = Sonos +settingsheader.premium = Subsonic Premium +settingsheader.share = \u5206\u4EAB\u5A92\u9AD4 settingsheader.network = \u7DB2\u8DEF settingsheader.transcoding = \u8F49\u6A94 settingsheader.user = \u4F7F\u7528\u8005 @@ -220,57 +314,71 @@ settingsheader.coverArt = \u5C08\u8F2F\u5C01\u9762 settingsheader.password = \u5BC6\u78BC # generalSettings.jsp -generalsettings.playlistfolder = \u9EDE\u64AD\u6E05\u55AE\u8CC7\u6599\u593E +generalsettings.playlistfolder = \u64AD\u653E\u6E05\u55AE\u8CC7\u6599\u593E generalsettings.musicmask = \u97F3\u6A02\u7684\u9644\u5C6C\u6A94\u540D: generalsettings.videomask = \u8996\u8A0A\u7684\u9644\u5C6C\u6A94\u540D: generalsettings.coverartmask = \u5C08\u8F2F\u5C01\u9762\u9644\u5C6C\u6A94\u540D generalsettings.index = \u7D22\u5F15 generalsettings.ignoredarticles = \u5FFD\u7565\u7684\u6B4C\u624B\u540D\u7A31 generalsettings.shortcuts = \u6377\u5F91 +generalsettings.sortalbumsbyyear = \u7531\u5E74\u4EFD\u6392\u5E8F\u5C08\u8F2F generalsettings.showgettingstarted = \u5728\u9996\u9801\u986F\u793A "\u521D\u6B21\u4F7F\u7528" generalsettings.welcometitle = \u6B61\u8FCE\u6A19\u984C generalsettings.welcomesubtitle = \u6B61\u8FCE\u6B21\u6A19\u984C generalsettings.welcomemessage = \u6B61\u8FCE\u8A0A\u606F generalsettings.loginmessage = \u767B\u5165\u8A0A\u606F -generalsettings.language = Default language +generalsettings.language = \u9810\u8A2D\u8A9E\u8A00 generalsettings.theme = \u9810\u8A2D\u4F48\u666F\u4E3B\u984C # advancedSettings.jsp advancedsettings.downsamplecommand = \u964D\u983B\u6307\u4EE4 -advancedsettings.coverartlimit = \u5C01\u9762\u9650\u5236
(0 = \u4E0D\u9650)
+advancedsettings.hlscommand = HTTP \u7DDA\u4E0A\u4E32\u6D41\u6307\u4EE4 advancedsettings.downloadlimit = \u4E0B\u8F09\u9650\u5236 (Kbps)
(0 = \u4E0D\u9650)
advancedsettings.uploadlimit = \u4E0A\u50B3\u9650\u5236 (Kbps)
(0 = \u4E0D\u9650)
-advancedsettings.streamport = \u975ESSL \u4E32\u6D41Port
(0 = \u53D6\u6D88)
-advancedsettings.ldapenabled = \u555F\u52D5LDAP\u9A57\u8B49 -advancedsettings.ldapurl = LDAP\u7DB2\u5740 -advancedsettings.ldapsearchfilter = LDAP\u641C\u5C0B\u904E\u6FFE -advancedsettings.ldapmanagerdn = LDAP \u7BA1\u7406\u8005DN
(\u53EF\u9078\u64C7)
+advancedsettings.streamport = \u975E SSL \u4E32\u6D41 Port
(0 = \u53D6\u6D88)
+advancedsettings.ldapenabled = \u555F\u52D5 LDAP \u9A57\u8B49 +advancedsettings.ldapurl = LDAP \u7DB2\u5740 +advancedsettings.ldapsearchfilter = LDAP \u641C\u5C0B\u904E\u6FFE +advancedsettings.ldapmanagerdn = LDAP \u7BA1\u7406\u8005 DN
(\u53EF\u9078\u64C7)
advancedsettings.ldapmanagerpassword = \u5BC6\u78BC advancedsettings.ldapautoshadowing = \u81EA\u52D5\u5728{0}\u5EFA\u7ACB\u4F7F\u7528\u8005 +advancedsettings.smtpPort = SMTP \u9023\u63A5\u57E0 +advancedsettings.smtpServer = SMTP \u4F3A\u670D\u5668 +advancedsettings.smtpEncryption = SMTP \u52A0\u5BC6 +advancedsettings.smtpUser = SMTP \u5E33\u865F +advancedsettings.smtpPassword = \u5BC6\u78BC +advancedsettings.smtpEncryption.none = \u7121 +advancedsettings.smtpEncryption.starttls = STARTTLS +advancedsettings.smtpEncryption.ssl = SSL/TLS +advancedsettings.smtpFrom = \u5BC4\u4EF6\u8005 # personalSettings.jsp personalsettings.title = {0}\u7684\u500B\u4EBA\u5316\u8A2D\u5B9A -personalsettings.language = Language +personalsettings.language = \u8A9E\u8A00 personalsettings.theme = \u4F48\u666F\u4E3B\u984C +personalsettings.albumlist = \u9810\u8A2D\u5C08\u8F2F\u6392\u5E8F\u65B9\u5F0F personalsettings.display = \u986F\u793A personalsettings.browse = \u700F\u89BD -personalsettings.playlist = \u9EDE\u64AD\u6E05\u55AE +personalsettings.playlist = \u64AD\u653E\u6E05\u55AE personalsettings.tracknumber = \u97F3\u8ECC # personalsettings.artist = \u6B4C\u624B personalsettings.album = \u5C08\u8F2F -personalsettings.genre = \u66F2\u98A8\u578B\u614B +personalsettings.genre = \u66F2\u98A8 personalsettings.year = \u767C\u884C personalsettings.bitrate = Bit rate personalsettings.duration = \u6642\u6548 personalsettings.format = \u683C\u5F0F personalsettings.filesize = \u6587\u4EF6\u5927\u5C0F -personalsettings.captioncutoff = Caption cutoff personalsettings.partymode = \u5BB4\u6703\u6A21\u5F0F +personalsettings.queuefollowingsongs = Queue following songs on play personalsettings.shownowplaying = \u5176\u4ED6\u4EBA\u5728\u807D\u4EC0\u9EBC personalsettings.nowplayingallowed = \u8B93\u5225\u4EBA\u770B\u6211\u5728\u807D\u4EC0\u9EBC personalsettings.showchat = \u986F\u793A\u4EA4\u8AC7\u8A0A\u606F +personalsettings.showartistinfo = \u986F\u793A\u6B4C\u624B\u8CC7\u8A0A +personalsettings.autohideplayqueue = \u81EA\u52D5\u96B1\u85CF\u64AD\u653E\u4F47\u5217 personalsettings.finalversionnotification = \u63D0\u793A\u65B0\u7248\u672C personalsettings.betaversionnotification = \u63D0\u793A\u65B0\u7684\u6E2C\u8A66\u7248 +personalsettings.songnotification = \u958B\u59CB\u64AD\u653E\u65B0\u6B4C\u6642\u63D0\u9192\u6211 (\u4E0D\u662F\u6240\u6709\u700F\u89BD\u5668\u90FD\u652F\u63F4) personalsettings.lastfmenabled = \u767B\u9304\u6211\u5728 Last.fm\u7684\u5E33\u865F personalsettings.lastfmusername = Last.fm \u5E33\u865F personalsettings.lastfmpassword = Last.fm \u5BC6\u78BC @@ -286,28 +394,51 @@ personalsettings.avatar.courtesy = Icons courtesy of \u8A18\u9304. +avataruploadresult.success = \u6210\u529F\u4E0A\u50B3\u500B\u4EBA\u5716\u793A "{0}"\u3002 +avataruploadresult.failure = \u7121\u6CD5\u4E0A\u50B3\u500B\u4EBA\u5716\u793A. \u8ACB\u53C3\u95B1 \u8A18\u9304\u3002 # passwordSettings.jsp passwordsettings.title = \u8B8A\u66F4\u5BC6\u78BC {0} # musicFolderSettings.jsp -musicfoldersettings.path = \u97F3\u6A02\u593E +musicfoldersettings.path = \u97F3\u6A02\u8CC7\u6599\u593E musicfoldersettings.name = \u540D\u7A31 musicfoldersettings.enabled = \u4F7F\u7528 -musicfoldersettings.add = \u65B0\u589E\u97F3\u6A02\u593E -musicfoldersettings.nopath = \u5E6B\u97F3\u6A02\u593E\u547D\u540D\u5427. +musicfoldersettings.add = \u65B0\u589E\u97F3\u6A02\u8CC7\u6599\u593E +musicfoldersettings.nopath = \u8ACB\u6307\u5B9A\u8CC7\u6599\u593E\u3002 +musicfoldersettings.notfound = \u627E\u4E0D\u5230\u8CC7\u6599\u593E +musicfoldersettings.scan = \u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E +musicfoldersettings.interval.never = \u5F9E\u4E0D +musicfoldersettings.interval.one = \u6BCF\u5929 +musicfoldersettings.interval.many = \u6BCF\u9694 {0} \u5929 +musicfoldersettings.hour = \u5728 {0}:00 +musicfoldersettings.nowscanning = \u6B63\u5728\u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E\u3002 \ + \u9019\u500B\u52D5\u4F5C\u5C07\u9700\u8981\u5E7E\u5206\u9418\uFF0C\u53D6\u6C7A\u65BC\u60A8\u7684\u5A92\u9AD4\u8CC7\u6599\u5EAB\u7684\u5927\u5C0F\u3002 +musicfoldersettings.scannow = \u7ACB\u5373\u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E +musicfoldersettings.access = \u7BA1\u7406\u4F7F\u7528\u8005\u5B58\u53D6\u6B0A\u9650 +musicfoldersettings.access.description = \u8A2D\u5B9A\u54EA\u4E9B\u8CC7\u6599\u593E\u53EF\u4EE5\u88AB\u54EA\u4E9B\u4F7F\u7528\u8005\u5B58\u53D6\u3002 +musicfoldersettings.fastcache = \u5FEB\u901F\u8B80\u53D6\u6A21\u5F0F +musicfoldersettings.fastcache.description = \u5982\u679C\u4F60\u7684\u5A92\u9AD4\u6A94\u6848\u5728\u7DB2\u8DEF\u4E0A\u7684\u78C1\u789F\uFF0C\u4F7F\u7528\u9019\u500B\u9078\u9805\u4F86\u6E1B\u5C11\u78C1\u789F\u5B58\u53D6\u3002 \ + \u6CE8\u610F\uFF1A\u65B0\u589E\u6216\u66F4\u6539\u5BE6\u969B\u6A94\u6848\u5C07\u6703\u53EA\u6709\u5728\u6383\u63CF\u97F3\u6A02\u8CC7\u6599\u593E\u5F8C\u624D\u6703\u751F\u6548\u3002 +musicfoldersettings.expunge = \u6E05\u7406\u8CC7\u6599\u5EAB +musicfoldersettings.expunge.description = Libresonic \u5132\u5B58\u4E86\u6240\u6709\u5A92\u9AD4\u6A94\u6848\u7684\u8CC7\u8A0A\u3002 \ + \u6E05\u7406\u8CC7\u6599\u5EAB\u5F8C\uFF0C\u4E0D\u5728\u60A8\u7684\u5A92\u9AD4\u8CC7\u6599\u5EAB\u5167\u7684\u6A94\u6848\uFF0C\u5176\u8CC7\u8A0A\u5C07\u6C38\u4E45\u522A\u9664\u3002 +musicfoldersettings.organizebyfolderstructure = \u4EE5\u8CC7\u6599\u593E\u7D50\u69CB\u6574\u7406 +musicfoldersettings.organizebyfolderstructure.description = \u958B\u555F\u9019\u500B\u9078\u9805\u4F7F\u60A8\u700F\u89BD\u5A92\u9AD4\u8CC7\u6599\u5EAB\u6642\u4F7F\u7528\u539F\u4F86\u7684\u8CC7\u6599\u593E\u7D50\u69CB\uFF0C\u800C\u4E0D\u662F\u4F9D\u7167 ID3 \u6A19\u7C64\u5167\u7684\u6B4C\u624B\u8207\u5C08\u8F2F\u8CC7\u8A0A\u3002 # networkSettings.jsp -networksettings.text = \u4EE5\u4E0B\u8A2D\u5B9A\u8B93\u60A8\u900F\u904E\u7DB2\u969B\u7DB2\u8DEF\u5B58\u53D6Libresonic\u4F3A\u670D\u5668.
\ - \u6709\u4EFB\u4F55\u554F\u984C, \u8ACB\u53C3\u8003 \u521D\u6B21\u4F7F\u7528\u624B\u518A. -networksettings.portforwardingenabled = \u81EA\u52D5\u914D\u7F6E\u8DEF\u7531\u5668\u5B58\u53D6Libresonic\u4F3A\u670D\u5668 (UPnP port \u8F49\u767C). -networksettings.portforwardinghelp = \u5982\u679C\u8DEF\u7531\u7121\u6CD5\u81EA\u52D5\u914D\u7F6E\uFF0C\u8ACB\u4F7F\u7528\u624B\u52D5\u914D\u7F6E.
\ +networksettings.text = \u4EE5\u4E0B\u8A2D\u5B9A\u8B93\u60A8\u900F\u904E\u7DB2\u969B\u7DB2\u8DEF\u5B58\u53D6Libresonic\u4F3A\u670D\u5668\u3002
\ + \u6709\u4EFB\u4F55\u554F\u984C\uFF0C\u8ACB\u53C3\u8003 \u521D\u6B21\u4F7F\u7528\u624B\u518A\u3002 +networksettings.portforwardingenabled = \u81EA\u52D5\u914D\u7F6E\u8DEF\u7531\u5668\u5B58\u53D6 Libresonic \u4F3A\u670D\u5668 (UPnP port \u8F49\u767C)\u3002 +networksettings.portforwardinghelp = \u5982\u679C\u8DEF\u7531\u7121\u6CD5\u81EA\u52D5\u914D\u7F6E\uFF0C\u8ACB\u4F7F\u7528\u624B\u52D5\u914D\u7F6E\u3002
\ \u4F9D\u7167 portforward.com \u7684\u8AAA\u660E
\ - \u4F60\u5FC5\u9808\u8F49\u767CPort:{0}\u5230\u96FB\u8166\u4E0A\u904B\u884C\u7684Libresonic\u4F3A\u670D\u5668. -networksettings.urlredirectionenabled = \u7528\u7C21\u55AE\u597D\u8A18\u7684\u7DB2\u5740\u9023\u7DDA\u5230\u60A8\u7684\u4F3A\u670D\u5668. -networksettings.status = \u72C0\u614B: + \u60A8\u5FC5\u9808\u8F49\u767CPort {0}\u5230\u96FB\u8166\u4E0A\u904B\u884C\u7684Libresonic\u4F3A\u670D\u5668\u3002 +networksettings.urlredirectionenabled = \u7528\u7C21\u55AE\u597D\u8A18\u7684\u7DB2\u5740\u9023\u7DDA\u5230\u60A8\u7684\u4F3A\u670D\u5668\u3002 +networksettings.status = \u72C0\u614B\uFF1A +networksettings.normalurl = Use +networksettings.customurl = Use custom URL (advanced) +networksettings.urlRedirectDisabled = Feature not currently available + # transcodingSettings.jsp transcodingsettings.name = \u8F49\u6A94\u540D\u7A31 @@ -316,22 +447,23 @@ transcodingsettings.targetformat = \u8F49\u63DB\u6210 transcodingsettings.step1 = \u6B65\u9A5F\u4E00 transcodingsettings.step2 = \u6B65\u9A5F\u4E8C transcodingsettings.step3 = \u6B65\u9A5F\u4E09 -transcodingsettings.defaultactive = \u9810\u8A2D transcodingsettings.add = \u65B0\u589E\u8F49\u78BC\u5668 -transcodingsettings.noname = \u8ACB\u6307\u5B9A\u4E00\u500B\u540D\u7A31. -transcodingsettings.nosourceformat = \u8ACB\u6307\u5B9A\u8F49\u63DB\u683C\u5F0F. -transcodingsettings.notargetformat = \u8ACB\u6307\u5B9A\u8F49\u63DB\u683C\u5F0F. -transcodingsettings.nostep1 = \u8ACB\u81F3\u5C11\u6307\u5B9A\u4E00\u500B\u8F49\u63DB\u6B65\u9A5F. -transcodingsettings.info =

(%s = \u6A94\u6848\u5C07\u88AB\u8F49\u63DB, %b = \u64A5\u653E\u5668\u7684\u6700\u5927\u50B3\u8F38\u7387)

\ -

\u8F49\u6A94\u904E\u7A0B\u662F\u7531\u4E00\u500B\u97F3\u6A02\u683C\u5F0F\u7BA1\u63DB\u6210\u53E6\u4E00\u7A2E\u683C\u5F0F. {1}\u7684\u8F49\u6A94 \ - \u5F15\u64CE\u5C07\u975E\u4E32\u6D41\u683C\u5F0F\u8F49\u63DB\u6210\u4E32\u6D41. \u76F4\u63A5\u8F49\u6A94\u4E26\u4E14\u4E0D\u9700\u8981\u78C1\u789F\u904B\u4F5C

\ -

\u5BE6\u969B\u7684\u5C08\u63DB\u6771\u505A\u901A\u5E38\u662F\u900F\u904E\u7B2C\u4E09\u65B9\u8EDF\u9AD4\u4EE5\u547D\u4EE4\u5217\u65B9\u5F0F\u8F49\u63DB\uFF0C\u7A0B\u5F0F\u5B89\u88DD\u5728 {0}.

\ -

\u800CWindows\u7CFB\u7D71\u7684\u8F49\u63DB\u7A0B\u5F0F\u53EF\u4EE5\u5728\u9019\u88E1\u627E\u5230. \ +transcodingsettings.defaultactive = \u9810\u8A2D +transcodingsettings.recommended = Recommended configuration +transcodingsettings.noname = \u8ACB\u6307\u5B9A\u4E00\u500B\u540D\u7A31\u3002 +transcodingsettings.nosourceformat = \u8ACB\u6307\u5B9A\u8F49\u63DB\u7684\u4F86\u6E90\u683C\u5F0F\u3002 +transcodingsettings.notargetformat = \u8ACB\u6307\u5B9A\u8F49\u63DB\u7684\u76EE\u7684\u683C\u5F0F\u3002 +transcodingsettings.nostep1 = \u8ACB\u81F3\u5C11\u6307\u5B9A\u4E00\u500B\u8F49\u63DB\u6B65\u9A5F\u3002 +transcodingsettings.info =

(%s = \u6A94\u6848\u5C07\u88AB\u8F49\u63DB\uFF0C%b = \u64A5\u653E\u5668\u7684\u6700\u5927\u50B3\u8F38\u7387\uFF0C%t = \u6A19\u984C\uFF0C%a = \u6B4C\u624B\uFF0C%l = \u5C08\u8F2F)

\ +

\u8F49\u6A94\u904E\u7A0B\u662F\u7531\u4E00\u500B\u97F3\u6A02\u683C\u5F0F\u8F49\u63DB\u6210\u53E6\u4E00\u7A2E\u683C\u5F0F\u3002{1}\u7684\u8F49\u6A94 \ + \u5F15\u64CE\u5C07\u975E\u4E32\u6D41\u683C\u5F0F\u8F49\u63DB\u6210\u4E32\u6D41\u3002\u76F4\u63A5\u8F49\u6A94\u4E26\u4E14\u4E0D\u9700\u8981\u78C1\u789F\u904B\u4F5C

\ +

\u5BE6\u969B\u7684\u8F49\u63DB\u52D5\u4F5C\u901A\u5E38\u662F\u900F\u904E\u7B2C\u4E09\u65B9\u8EDF\u9AD4\u4EE5\u547D\u4EE4\u5217\u65B9\u5F0F\u8F49\u63DB\uFF0C\u7A0B\u5F0F\u5B89\u88DD\u5728 {0}\u3002

\ +

\u800CWindows\u7CFB\u7D71\u7684\u8F49\u63DB\u7A0B\u5F0F\u53EF\u4EE5\u5728\u9019\u88E1\u627E\u5230\u3002 \ \u60A8\u4E5F\u80FD\u4EE5\u81EA\u5B9A\u7684\u8F49\u63DB\uFF0C\u53EA\u8981\u6EFF\u8DB3\u4E0B\u9762\u8981\u6C42\uFF1A\

    \ -
  • \u5FC5\u9808\u4EE5\u4E00\u500B\u547D\u4EE4\u884C\u6307\u4EE4\u754C\u9762.
  • \ -
  • \u5FC5\u9808\u80FD\u5920\u5C07\u8F38\u51FA\u767C\u9001\u5230\u6A19\u6E96\u8F38\u51FA(Stdout).
  • \ -
  • \u5982\u679C\u4F7F\u7528\u6B65\u9A5F2\u62163\uFF0C\u5B83\u5FC5\u9808\u80FD\u5920\u5F9E\u6A19\u6E96\u8F38\u5165(Stdin)\u8B80\u53D6.
  • \ +
  • \u5FC5\u9808\u6709\u547D\u4EE4\u5217\u754C\u9762\u3002
  • \ +
  • \u5FC5\u9808\u80FD\u5920\u5C07\u7D50\u679C\u9001\u5230\u6A19\u6E96\u8F38\u51FA(Stdout)\u3002
  • \ +
  • \u5982\u679C\u5728\u6B65\u9A5F2\u4F7F\u7528\uFF0C\u5B83\u5FC5\u9808\u80FD\u5920\u5F9E\u6A19\u6E96\u8F38\u5165(Stdin)\u8B80\u53D6\u3002
  • \
\

\

\u8ACB\u6CE8\u610F\uFF0C\u8F49\u63DB\u7684\u7A0B\u5E8F\u7684\u7531\u64A5\u653E\u5668\u8A2D\u5B9A\u4E2D\u52FE\u9078\u3002\u5982\u679C"\u9810\u8A2D"\u662F\u5DF2\u52FE\u9078\u7684\uFF0C\u90A3\u9EBC\u8F49\u63DB\u6703\u81EA\u52D5\u5728\u65B0\u64AD\u653E\u5668\u4E2D\u4F7F\u7528\u3002

@@ -363,35 +495,60 @@ podcastsettings.interval.weekly = \u6BCF\u9031 podcastsettings.folder = \u5132\u5B58\u64AD\u5BA2\u5728 # playerSettings.jsp -playersettings.noplayers = \u6C92\u6709\u64A5\u653E\u5668. +playersettings.noplayers = \u6C92\u6709\u64A5\u653E\u5668\u3002 playersettings.type = \u5F62\u614B playersettings.lastseen = \u4E0A\u6B21\u767B\u5165 playersettings.title = \u9078\u64C7\u64A5\u653E\u5668 - playersettings.technology.web.title = \u7DB2\u9801\u64AD\u653E playersettings.technology.external.title = \u76F4\u63A5\u7528\u5916\u90E8\u64AD\u653E\u5668\u64AD\u653E -playersettings.technology.external_with_playlist.title = \u4EE5\u9EDE\u64AD\u6E05\u55AE\u5728\u5916\u90E8\u64A5\u653E\u5668\u64AD\u653E +playersettings.technology.external_with_playlist.title = \u4EE5\u64AD\u653E\u6E05\u55AE\u5728\u5916\u90E8\u64A5\u653E\u5668\u64AD\u653E playersettings.technology.jukebox.title = \u9EDE\u64AD\u6A5F\u6A21\u5F0F playersettings.technology.web.text = \u76F4\u63A5\u5728\u7DB2\u9801\u4E2D\u7684Flash\u64AD\u653E\u5668\u64AD\u653E. playersettings.technology.external.text = \u5728\u60A8\u5E38\u7528\u7684\u64A5\u653E\u5668\u4E2D\u64AD\u653E\uFF0C\u4F8B\u5982:WinAmp\u3001Windows Media Player\u3001iTunes. -playersettings.technology.external_with_playlist.text = \u5982\u540C\u4E0A\u9762\u7684\u9078\u9805\uFF0C\u4F46\u662F\u9EDE\u64AD\u6E05\u55AE\u7531\u5BA2\u6236\u7AEF\u7BA1\u7406\uFF0C\u800C\u4E0D\u662F\u4F3A\u670D\u5668
\ - \u56E0\u6B64\u53EF\u80FD\u7684\u60C5\u6CC1\u4E0B\u53EF\u4EE5\u76F4\u63A5\u8DF3\u807D\u4E0B\u4E00\u9996\u6B4C\u66F2\u3002 -playersettings.technology.jukebox.text = \u76F4\u63A5\u5728Libresonic\u4F3A\u670D\u5668\u4E2D\u64AD\u653E. (\u9650\u5DF2\u6388\u6B0A\u7684\u7528\u6236). +playersettings.technology.external_with_playlist.text = \u5982\u540C\u4E0A\u9762\u7684\u9078\u9805\uFF0C\u4F46\u662F\u64AD\u653E\u6E05\u55AE\u7531\u5BA2\u6236\u7AEF\u7BA1\u7406\uFF0C\u800C\u4E0D\u662F\u4F3A\u670D\u5668\u3002 \ + \u5728\u9019\u500B\u6A21\u5F0F\u4E2D\u53EF\u4EE5\u8DF3\u8457\u64AD\u653E\u3002 +playersettings.technology.jukebox.text = \u76F4\u63A5\u5728Libresonic\u4F3A\u670D\u5668\u4E2D\u64AD\u653E\u3002(\u9650\u5DF2\u6388\u6B0A\u7684\u7528\u6236\u3002) playersettings.name = \u64A5\u653E\u5668\u540D\u7A31 -playersettings.coverartsize = \u5C08\u8F2F\u5C01\u9762\u5927\u5C0F playersettings.maxbitrate = \u6700\u5927\u50B3\u8F38\u7387 -playersettings.coverart.off = \u4E0D\u986F\u793A -playersettings.coverart.small = \u5C0F -playersettings.coverart.medium = \u4E2D -playersettings.coverart.large = \u5927 -playersettings.notranscoder = \u6CE8\u610F: ffmpeg \u5C1A\u672A\u5B89\u88DD.
\u9EDE\u64CA\u3010\u5354\u52A9\u3011. +playersettings.notranscoder = \u6CE8\u610F: \u8F49\u78BC\u5F15\u64CE\u5C1A\u672A\u5B89\u88DD\u3002
\u9EDE\u9078\u3010\u8AAA\u660E\u3011\u7372\u5F97\u66F4\u591A\u8CC7\u8A0A\u3002 playersettings.autocontrol = \u81EA\u52D5\u64AD\u653E +playersettings.m3ubom = \u70ba\u7522\u751f\u7684M3U\u6a94\u6848\u589e\u52a0BOM\u6a19\u8a18 playersettings.dynamicip = \u64A5\u653E\u5668\u4F7F\u7528\u52D5\u614BIP\u4F4D\u5740 playersettings.transcodings = \u555F\u52D5\u7684\u8F49\u78BC\u7A0B\u5F0F playersettings.ok = \u5132\u5B58 playersettings.forget = \u522A\u9664\u64A5\u653E\u5668 playersettings.clone = \u8907\u88FD\u64A5\u653E\u5668 +dlnasettings.enabled = Enable DLNA server +dlnasettings.description = Use this option to turn on the DLNA/UPnP Media Server in Libresonic, \ + and stream your media to compatible DLNA players. +dlnasettings.servername = Media Server name +dlnasettings.servername.description = The name of the Media Server as it will appear in DLNA players. + +sonossettings.enabled = Enable Sonos music service +sonossettings.description = Use this option to turn on the Sonos music service in Libresonic, \ + and stream your media to Sonos devices on your local network. Remember to add Libresonic \ + as a music service from your Sonos controller. Visit \ + sonos.libresonic.org for more info. \ + For trouble-shooting, please see the log. +sonossettings.servicename = Music service name +sonossettings.servicename.description = The name of the music service as it will appear in the Sonos controller. + +# shareSettings.jsp +sharesettings.name = Name +sharesettings.owner = Shared by +sharesettings.description = Description +sharesettings.visits = Visits +sharesettings.lastvisited = Last visited +sharesettings.expires = Expires +sharesettings.files = Shared files +sharesettings.expirein = Expire in +sharesettings.expirein.week = 1w +sharesettings.expirein.month = 1m +sharesettings.expirein.year = 1y +sharesettings.expirein.never = never +sharesettings.deleteexpired = Delete all expired + # userSettings.jsp usersettings.title = \u9078\u64C7\u4F7F\u7528\u8005 usersettings.newuser = \u65B0\u4F7F\u7528\u8005 @@ -401,52 +558,67 @@ usersettings.stream = \u53EF\u4EE5\u64AD\u653E\u6A94\u6848 usersettings.jukebox = \u53EF\u4EE5\u7528\u9EDE\u64A5\u6A5F\u6A21\u5F0F usersettings.download = \u53EF\u4EE5\u4E0B\u8F09\u6A94\u6848 usersettings.upload = \u53EF\u4EE5\u4E0A\u50B3\u6A94\u6848 +usersettings.share = \u53EF\u4EE5\u8207\u4EFB\u4F55\u4EBA\u5206\u4EAB\u6A94\u6848 usersettings.coverart = \u53EF\u4EE5\u66F4\u63DB\u5C08\u8F2F\u5C01\u9762\u53CA\u6A19\u7C64 usersettings.comment= \u53EF\u4EE5\u5EFA\u7ACB\u6216\u7DE8\u8F2F\u8A55\u8AD6\u53CA\u8A55\u5206 usersettings.podcast= \u53EF\u4EE5\u7BA1\u7406\u64AD\u5BA2 +usersettings.folderaccess = \u53EF\u4EE5\u5B58\u53D6\u9019\u4E9B\u5A92\u9AD4\u8CC7\u6599\u593E usersettings.username = \u4F7F\u7528\u8005 +usersettings.email = Email usersettings.changepassword = \u8B8A\u66F4\u5BC6\u78BC usersettings.password = \u5BC6\u78BC usersettings.newpassword = \u65B0\u5BC6\u78BC usersettings.confirmpassword = \u518D\u6B21\u78BA\u8A8D\u5BC6\u78BC usersettings.delete = \u522A\u9664\u4F7F\u7528\u8005 usersettings.ldap = \u5728LDAP\u9A57\u8B49\u7528\u6236 -usersettings.nousername = \u7F3A\u5C11\u4F7F\u7528\u8005\u540D\u7A31. -usersettings.useralreadyexists = \u4F7F\u7528\u8005\u540D\u7A31\u5DF2\u7D93\u88AB\u4F7F\u7528\u4E86\uFF01. -usersettings.nopassword = \u5FC5\u9808\u8A2D\u5B9A\u5BC6\u78BC. -usersettings.wrongpassword = \u5169\u6B21\u8F38\u5165\u5BC6\u78BC\u4E0D\u540C. -usersettings.ldapdisabled = LDAP\u9A57\u8B49\u6C92\u6709\u555F\u52D5. \u8ACB\u5148\u5230\u9032\u968E\u8A2D\u5B9A. -usersettings.passwordnotsupportedforldap = \u7121\u6CD5\u8A2D\u5B9A\u6216\u8B8A\u66F4LDAP\u9A57\u8B49\u7528\u6236\u7684\u5BC6\u78BC. -usersettings.ok = \u4F7F\u7528\u8005 {0}\u7684\u5BC6\u78BC\u5DF2\u7D93\u8B8A\u66F4. - -# musicFolderSettings.jsp -musicfoldersettings.interval.never = \u5F9E\u4E0D -musicfoldersettings.interval.one = \u6BCF\u5929 -musicfoldersettings.interval.many = \u6BCF\u9694 {0} \u5929 -musicfoldersettings.hour = \u5728 {0}:00 +usersettings.nousername = \u7F3A\u5C11\u4F7F\u7528\u8005\u540D\u7A31\u3002 +usersettings.noemail= \u4E0D\u5408\u6CD5\u7684 email \u4F4D\u5740\u3002 +usersettings.useralreadyexists = \u5E33\u865F\u540D\u7A31\u5DF2\u7D93\u88AB\u4F7F\u7528\u4E86\u3002 +usersettings.nopassword = \u5FC5\u9808\u8A2D\u5B9A\u5BC6\u78BC\u3002 +usersettings.wrongpassword = \u5169\u6B21\u8F38\u5165\u5BC6\u78BC\u4E0D\u540C\u3002 +usersettings.ldapdisabled = LDAP\u9A57\u8B49\u6C92\u6709\u555F\u52D5\u3002\u8ACB\u5230\u9032\u968E\u8A2D\u5B9A\u3002 +usersettings.passwordnotsupportedforldap = \u7121\u6CD5\u8A2D\u5B9A\u6216\u8B8A\u66F4 LDAP \u9A57\u8B49\u7528\u6236\u7684\u5BC6\u78BC\u3002 +usersettings.ok = \u4F7F\u7528\u8005 {0} \u7684\u5BC6\u78BC\u5DF2\u7D93\u8B8A\u66F4\u3002 # main.jsp main.up = \u4E0A\u4E00\u9801 main.playall = \u5168\u90E8\u64AD\u653E main.playrandom = \u96A8\u8208\u64AD\u653E -main.addall = \u5168\u90E8\u52A0\u5230\u9EDE\u64AD\u6E05\u55AE\u4E2D +main.addall = \u5168\u90E8\u52A0\u5230\u64AD\u653E\u6E05\u55AE\u4E2D main.downloadall = \u5168\u90E8\u4E0B\u8F09 main.tags = \u7DE8\u8F2F\u6A19\u7C64 -main.playcount = \u9EDE\u64AD {0} \u6B21. -main.lastplayed =\u4E0A\u6B21\u9EDE\u64AD\u5728 {0}. +main.playcount = \u64AD\u653E {0} \u6B21\u3002 +main.lastplayed =\u4E0A\u6B21\u64AD\u653E\u5728 {0} \u3002 main.comment = \u8A55\u8AD6 main.wiki = \ - \ - \ - \ - \ + \ + \ + \ + \
__text__Bold text \\\\ Line break
~~text~~Italic text (empty line) New paragraph
* text List item http://foo.com/ Link
1. text Enumerated list item{link:Foo|http://foo.com}Named link
__text__\u7C97\u9AD4 \\\\ \u63DB\u884C
~~text~~\u659C\u9AD4 (empty line) \u65B0\u6BB5\u843D
* text \u6E05\u55AE http://foo.com/ \u934A\u7D50
1. text \u5217\u8209\u6E05\u55AE{link:Foo|http://foo.com}\u5DF2\u547D\u540D\u934A\u7D50
+main.sharealbum = \u5206\u4EAB +main.more = \u66F4\u591A\u52D5\u4F5C\u2026 +main.more.selection = \u9078\u64C7\u6B4C\u66F2\u2026 +main.more.share = \u5206\u4EAB +main.premium = \u53D6\u5F97 Subsonic Premium
(\u4E26\u522A\u9664\u6B64\u5EE3\u544A) main.nowplaying =\u76EE\u524D\u64A5\u653E main.lyrics = \u6B4C\u8A5E main.minutesago = \u5206\u9418\u524D main.chat = \u4EA4\u8AC7 +main.scanning = \u6383\u63CF\u6A94\u6848\uFF1A main.message = \u5BEB\u5728\u9019\u88E1 main.clearchat = \u6E05\u9664 +main.addtoplaylist.title = \u589E\u52A0\u81F3\u64AD\u653E\u6E05\u55AE +main.addtoplaylist.text = \u589E\u52A0\u5DF2\u9078\u64C7\u7684\u6B4C\u66F2\u81F3\u6B64\u64AD\u653E\u6E05\u55AE\uFF1A +main.addnext = \u52A0\u5230\u4E0B\u4E00\u9996 +main.addlast = \u52A0\u5230\u6700\u5F8C\u4E00\u9996 +main.addnext.toast = \u6B64\u6B4C\u66F2\u5C07\u6703\u65BC\u4E0B\u4E00\u9996\u6642\u64AD\u653E +main.addlast.toast = \u6B64\u6B4C\u66F2\u5C07\u6703\u65BC\u6700\u5F8C\u4E00\u9996\u6642\u64AD\u653E +main.similarartists = \u76F8\u4F3C\u7684\u6B4C\u624B +main.startradio = Start radio +main.playtopsongs = \u64AD\u653E\u6392\u884C\u699C\u6B4C\u66F2 +main.showall = \u986F\u793A\u6240\u6709\u5C08\u8F2F +main.topsongs = \u6392\u884C\u699C\u6B4C\u66F2 # rating.jsp rating.rating = \u7B49\u7D1A @@ -457,17 +629,18 @@ coverart.change = \u8B8A\u66F4 coverart.zoom = \u653E\u5927 # allmusic.jsp -allmusic.text = \u5728 allmusic.com \u641C\u5C0B\u5C08\u8F2F {0} - \u8ACB\u7A0D\u5019. +allmusic.text = \u5728 allmusic.com \u641C\u5C0B\u5C08\u8F2F {0} - \u8ACB\u7A0D\u5019\u3002 # changeCoverArt.jsp changecoverart.title = \u8B8A\u66F4\u5C08\u8F2F\u5C01\u9762 changecoverart.address = \u6216\u662F\u8F38\u5165\u5716\u5F62\u7684\u4F4D\u5740 changecoverart.artist = \u6B4C\u624B changecoverart.album = \u5C08\u8F2F -changecoverart.wait = \u8ACB\u7A0D\u5019... -changecoverart.success = \u5716\u5F62\u4E0B\u8F09\u6210\u529F. -changecoverart.error = \u7121\u6CD5\u4E0B\u8F09\u5716\u5F62. -changecoverart.noimagesfound = \u627E\u4E0D\u5230\u5716\u5F62\u6A94. +changecoverart.search = Google \u5716\u7247\u641C\u5C0B +changecoverart.wait = \u8ACB\u7A0D\u5019\u2026 +changecoverart.success = \u5716\u7247\u4E0B\u8F09\u6210\u529F\u3002 +changecoverart.error = \u7121\u6CD5\u4E0B\u8F09\u5716\u7247\u3002 +changecoverart.noimagesfound = \u627E\u4E0D\u5230\u5716\u7247\u3002 # changeCoverArtConfirm.jsp changeCoverArtConfirm.failed = \u7121\u6CD5\u4FEE\u6539\u5C08\u8F2F\u5C01\u9762:
"{0}" @@ -492,8 +665,48 @@ edittags.updated = Updated edittags.skipped = \u7565\u904E edittags.error = \u932F\u8AA4 +# share.jsp +share.title = Share +share.warning =

IMPORTANT NOTICE!

Play fair – Don't share copyrighted material in any manner that violates the law.

+share.facebook = \u5206\u4EAB\u81F3 Facebook +share.twitter = \u5206\u4EAB\u81F3 Twitter +share.googleplus = \u5206\u4EAB\u81F3 Google+ +share.link = Or share this with someone by sending them this link: {0} +share.disabled = To share your music with someone you must first register your own libresonic.org address.
\ + Please go to Settings > Network (administrative rights required). +share.manage = Manage my shared media + +# premium.jsp +premium.title = Subsonic Premium +premium.invalidlicense = Invalid license key. +premium.text =

Upgrade to Subsonic Premium to enjoy these extra features:

\ +
    \ +
  • Apps for Android, iPhone, Windows Phone, Mac, Chrome and more*.
  • \ +
  • Video streaming.
  • \ +
  • Stream to your Chromecast and Sonos devices.
  • \ +
  • Podcast receiver.
  • \ +
  • Your personal server address: yourname.libresonic.org (see Settings > Network).
  • \ +
  • Play your media on compatible DLNA/UPnP devices.
  • \ +
  • Share your media on Facebook, Twitter, Google+.
  • \ +
  • No ads in the web interface.
  • \ +
  • Other features to be released later.
  • \ +
\ +

* Some apps must be purchased separately.

+premium.getpremium = \u53D6\u5F97 Subsonic Premium +premium.licensed = You have a valid Subsonic Premium license! +premium.licensedexpires = Your Subsonic Premium license is valid until {0} +premium.licensedexpired = Your Subsonic Premium license expired {0} +premium.licensedto = The license is registered to {0}. +premium.forcechange = Register a different license key +premium.register = When upgrading to Subsonic Premium you receive a license key by email. Please register it below. +premium.resend = Lost the license key? Send it again. +premium.register.email = Email +premium.register.license = License key + # podcastReceiver.jsp podcastreceiver.title = \u64AD\u5BA2\u63A5\u6536\u5668 +podcastreceiver.empty = You haven't subscribed to any podcasts yet. +podcastreceiver.episodes = {0} \u7AE0\u7BC0 podcastreceiver.expandall = \u986F\u793A\u6536\u85CF\u96C6 podcastreceiver.collapseall = \u96B1\u85CF\u6536\u85CF\u96C6 podcastreceiver.status.new = \u65B0\u7684 @@ -509,78 +722,86 @@ podcastreceiver.check = \u6838\u5C0D\u65B0\u7684\u6536\u85CF\u96C6 podcastreceiver.refresh = \u5237\u65B0\u672C\u9801 podcastreceiver.settings = \u64AD\u5BA2\u8A2D\u5B9A podcastreceiver.subscribe = \u8A02\u95B1\u64AD\u5BA2 +podcastreceiver.newestepisodes = \u6700\u65B0\u7AE0\u7BC0 # lyrics.jsp lyrics.title = \u6B4C\u8A5E lyrics.artist = \u6B4C\u624B lyrics.song = \u6B4C\u66F2 lyrics.search = \u641C\u5C0B -lyrics.wait = \u641C\u5C0B\u6B4C\u8A5E\u4E2D, \u8ACB\u7A0D\u5019... +lyrics.wait = \u641C\u5C0B\u6B4C\u8A5E\u4E2D\uFF0C\u8ACB\u7A0D\u5019\u2026 lyrics.courtesy = (\u6B4C\u8A5E\u7531chartlyrics.com\u63D0\u4F9B) -lyrics.nolyricsfound = \u627E\u4E0D\u5230\u6B4C\u8A5E. +lyrics.nolyricsfound = \u627E\u4E0D\u5230\u6B4C\u8A5E\u3002 +lyrics.trylater = Sorry, the lyrics search engine allows just one search every 20 seconds. Try again later. # helpPopup.jsp helppopup.title = {0} \u5354\u52A9 -helppopup.cover.title = \u5C08\u8F2F\u5C01\u9762\u5927\u5C0F -helppopup.cover.text =

\u7531\u60A8\u6307\u5B9A\u986F\u793A\u5C08\u8F2F\u5C01\u9762\u7684\u5927\u5C0F\uFF0C\u4E5F\u53EF\u4EE5\u5B8C\u5168\u95DC\u9589.

helppopup.transcode.title = \u6700\u5927\u50B3\u8F38\u7387 -helppopup.transcode.text =

\u5982\u679C\u60A8\u7684\u64AD\u653E\u983B\u5BEC\u6709\u9650\uFF0C\u53EF\u4EE5\u904E\u8A2D\u5B9A\u6700\u5927\u50B3\u8F38\u7387\u4F86\u6539\u5584. \ - \u4F8B\u5982,\u5982\u679Cmp3\u539F\u672C\u7684\u58D3\u7E2E\u6BD4\u4F8B\u70BA256Kbps(kilobits per second), \u5982\u679C\u8A2D\u5B9A\u6700\u5927\u50B3\u8F38\u7387\u70BA128\ - \u6703\u4F7F{0}\u81EA\u52D5\u5C07\u539F\u672C 256Kbps\u7684\u97F3\u6A02\u8ABF\u964D\u6210 128 Kbps.

-helppopup.playlistfolder.title = \u9EDE\u64AD\u6E05\u55AE\u8CC7\u6599\u593E -helppopup.playlistfolder.text =

\u5B58\u653E\u9EDE\u64AD\u6E05\u55AE\u7684\u8CC7\u6599\u593E.

+helppopup.transcode.text =

\u5982\u679C\u60A8\u7684\u64AD\u653E\u983B\u5BEC\u6709\u9650\uFF0C\u53EF\u4EE5\u904E\u8A2D\u5B9A\u6700\u5927\u50B3\u8F38\u7387\u4F86\u6539\u5584\u3002 \ + \u4F8B\u5982\uFF0C\u5982\u679C\u60A8\u539F\u672C\u7684 mp3 \u6A94\u6848\u7684\u7DE8\u78BC\u7387\u70BA 256Kbps(\u6BCF\u79D2\u5343\u4F4D\u5143)\uFF0C\u5982\u679C\u8A2D\u5B9A\u6700\u5927\u50B3\u8F38\u7387\u70BA128\ + \u6703\u4F7F {0} \u81EA\u52D5\u5C07\u539F\u672C 256Kbps \u7684\u97F3\u6A02\u7DE8\u78BC\u70BA\u6210 128 Kbps\u3002

+helppopup.playlistfolder.title = \u64AD\u653E\u6E05\u55AE\u8CC7\u6599\u593E +helppopup.playlistfolder.text =

\u5B58\u653E\u64AD\u653E\u6E05\u55AE\u7684\u8CC7\u6599\u593E\u3002

helppopup.musicmask.title = \u97F3\u6A02\u7684\u9644\u5C6C\u6A94\u540D helppopup.musicmask.text =

\u6307\u5B9A\u97F3\u6A02\u6A94\u6848\u7684\u9644\u5C6C\u6A94\u540D

helppopup.videomask.title = \u8996\u8A0A\u6A94\u7684\u9644\u5C6C\u6A94\u540D helppopup.videomask.text =

\u6307\u5B9A\u8996\u8A0A\u6A94\u6848\u7684\u8CA0\u6578\u6A94\u540D

helppopup.coverartmask.title = \u5C08\u8F2F\u5C01\u9762\u9644\u5C6C\u6A94\u540D -helppopup.coverartmask.text =

\u8207\u97F3\u6A02\u593E\u653E\u5728\u4E00\u8D77\u7684\u5C08\u8F2F\u5C01\u9762\uFF0C\u5148\u6307\u5B9A\u5C08\u8F2F\u5C01\u9762\u6A94\u6848\u7684\u9644\u5C6C\u6A94\u540D.

+helppopup.coverartmask.text =

\u8207\u97F3\u6A02\u8CC7\u6599\u593E\u653E\u5728\u4E00\u8D77\u7684\u5C08\u8F2F\u5C01\u9762\uFF0C\u5148\u6307\u5B9A\u5C08\u8F2F\u5C01\u9762\u6A94\u6848\u7684\u9644\u5C6C\u6A94\u540D\u3002

helppopup.downsamplecommand.title = \u964D\u983B\u6307\u4EE4 -helppopup.downsamplecommand.text =

\u8B93\u60A8\u8A2D\u5B9A\u8ABF\u964D\u64AD\u653E\u97F3\u6A02\u6642\u964D\u4F4E\u53D6\u6A23\u983B\u7387\u7684\u6307\u4EE4.

\ -

(%s = \u8981\u964D\u983B\u7684\u6A94\u6848, %b = \u64A5\u653E\u5668\u7684\u6700\u5927\u50B3\u8F38\u7387)

+helppopup.downsamplecommand.text =

\u8B93\u60A8\u8A2D\u5B9A\u8ABF\u964D\u64AD\u653E\u97F3\u6A02\u6642\u964D\u4F4E\u53D6\u6A23\u983B\u7387\u7684\u6307\u4EE4\u3002

\ +

(%s = \u8981\u964D\u983B\u7684\u6A94\u6848\uFF0C%b = \u64A5\u653E\u5668\u7684\u6700\u5927\u50B3\u8F38\u7387\uFF0C%t = \u6A19\u984C\uFF0C%a = \u6B4C\u624B\uFF0C%l = \u5C08\u8F2F)

+helppopup.hlscommand.title = HTTP Live Streaming command +helppopup.hlscommand.text =

The command used to create video segments for Apple''s HLS (HTTP Live Streaming) protocol.

helppopup.index.title = \u5206\u985E\u6AA2\u7D22 -helppopup.index.text =

\u8A2D\u5B9A\u97F3\u6A02\u6AA2\u7D22\u7684\u65B9\u5F0F\uFF0C\uFF08\u5C31\u5982\u540C\u73FE\u5728\u5728\u87A2\u5E55\u5DE6\u4E0A\u65B9\u7684\u5206\u985E\uFF09. \u5728\u97F3\u6A02\u593E\u88E1\u7684\u6A94\u6848\u5F88\u5BB9\u6613\u5206\u985E\u6AA2\u7D22

\ -

\u901A\u5E38\u4EE5\u7A7A\u767D\u4F86\u5206\u9694\u6AA2\u7D22\u9805\u76EE. \u4E00\u822C\u4F86\u8AAA\uFF0C\u4E00\u500B\u5B57\u6BCD\uFF08\u570B\u5B57\uFF09\u70BA\u4E00\u500B\u9805\u76EE, \ - \u4F46\u4E5F\u53EF\u4EE5\u591A\u500B\u5B57\u6BCD\uFF08\u570B\u5B57\uFF09\u653E\u5728\u540C\u4E00\u5206\u985E\u9805\u76EE\u4E2D. \u4F8B\u5982\uFF1A\u3105(\u5305\u9B91),\u53EF\u4EE5\u5C07 \u5305\u9B91\u8996\u70BA\u540C\u4E00\u5206\u985E\ -

\u800C\u7121\u6CD5\u6B78\u985E\u7684\u6A94\u6848\uFF0C\u5C07\u5168\u90E8\u6B78\u65BC "#"\u9805\u76EE\u4E2D.

+helppopup.index.text =

\u8A2D\u5B9A\u97F3\u6A02\u7D22\u5F15(\u5728\u87A2\u5E55\u5DE6\u65B9)\u6B78\u985E\u7684\u65B9\u5F0F\u3002\u5728\u97F3\u6A02\u8CC7\u6599\u593E\u88E1\u7684 \ + \u6A94\u6848\u5F88\u5BB9\u6613\u900F\u904E\u7D22\u5F15\u5B58\u53D6\u3002

\ +

\u5B9A\u7FA9\u65B9\u5F0F\u662F\u4EE5\u7A7A\u767D\u5206\u9694\u7684\u7D22\u5F15\u9805\u76EE\u3002\u4E00\u822C\u4F86\u8AAA\uFF0C\u9805\u76EE\u662F\u55AE\u4E00\u5B57\u6BCD\uFF0C \ + \u4F46\u60A8\u4E5F\u53EF\u4EE5\u6307\u5B9A\u591A\u500B\u5B57\u6BCD\u3002\u4F8B\u5982\uFF1A\u9805\u76EE The \u6703\u9023\u7D50\u5230\u6240\u6709 \ + \u958B\u982D\u70BA "The" \u7684\u8CC7\u6599\u593E\u8207\u6A94\u6848\u3002

\ +

\u60A8\u4E5F\u53EF\u4EE5\u7528\u62EC\u5F27\u4F86\u5305\u542B\u591A\u500B\u7D22\u5F15\u5B57\u5143\u3002\u4F8B\u5982\uFF1A \ + A-E(ABCDE) \u6703\u986F\u793A\u70BA A-E \u4E26\u9023\u7D50\u5230\u6240\u6709\u958B\u982D\u70BA \ + A\u3001B\u3001C\u3001D\u6216E\u7684\u8CC7\u6599\u593E\u8207\u6A94\u6848\u3002\u9019\u5C0D\u65BC\u6536\u7D0D\u5C11\u898B\u7684\u5B57\u5143(\u50CF\u662FX\u3001Y\u8207Z)\u5F88\u6709\u5E6B\u52A9\uFF0C\u6216 \ + \u6B78\u985E\u91CD\u97F3\u5B57\u5143(\u5982A\u3001\u00C0\u8207\u00C1)

\ +

\u7121\u6CD5\u6B78\u985E\u7684\u8CC7\u6599\u593E\u8207\u6A94\u6848\uFF0C\u5C07\u5168\u90E8\u6B78\u65BC "#" \u9805\u76EE\u4E2D\u3002

helppopup.ignoredarticles.title = \u5FFD\u7565\u5B57\u9996 -helppopup.ignoredarticles.text =

\u6709\u4E9B\u5B57\u9996(\u4F8B\u5982"The") \u901A\u5E38\u5728\u66F2\u76EE\u6B78\u985E\u4E2D\u61C9\u8A72\u5FFD\u7565\uFF0C\u8ACB\u5728\u6B64\u8655\u8A2D\u5B9A.

+helppopup.ignoredarticles.text =

\u6709\u4E9B\u5B57\u9996(\u4F8B\u5982"The") \u901A\u5E38\u5728\u66F2\u76EE\u6B78\u985E\u4E2D\u61C9\u8A72\u5FFD\u7565\uFF0C\u8ACB\u5728\u6B64\u8655\u8A2D\u5B9A\u3002

helppopup.shortcuts.title = \u6377\u5F91 -helppopup.shortcuts.text =

\u4EE5\u7A7A\u767D\u4F86\u5206\u9694\u5728\u6700\u4E0A\u5C64\u76EE\u9304\u4E2D\u5EFA\u7ACB\u6377\u5F91\u6AA2\u7D22. \u7528\u5F15\u865F\u4F86\u5206\u7D44\u5B57\u5143, \u4F8B\u5982:

\ +helppopup.shortcuts.text =

\u4EE5\u7A7A\u767D\u4F86\u5206\u9694\u5728\u6700\u4E0A\u5C64\u76EE\u9304\u4E2D\u5EFA\u7ACB\u6377\u5F91\u6AA2\u7D22\u3002\u7528\u5F15\u865F\u4F86\u5206\u7D44\u5B57\u5143\uFF0C\u4F8B\u5982\uFF1A

\

New Incoming "Sound tracks"

-helppopup.language.title = Language -helppopup.language.text =

\u5728\u9019\u88E1\u9078\u64C7\u6240\u63D0\u4F9B\u7684\u986F\u793A\u8A9E\u8A00.

+helppopup.language.title = \u8A9E\u8A00 +helppopup.language.text =

\u5728\u9019\u88E1\u9078\u64C7\u6240\u63D0\u4F9B\u7684\u986F\u793A\u8A9E\u8A00\u3002

helppopup.visibility.title = \u986F\u793A\u9805\u76EE -helppopup.visibility.text =

\u9078\u64C7\u5728\u700F\u89BD\u6216\u662F\u5728\u9EDE\u64AD\u6E05\u55AE\u4E2D\uFF0C\u986F\u793A\u97F3\u6A02\u7684\u5404\u7A2E\u8A73\u7D30\u8CC7\u8A0A

+helppopup.visibility.text =

\u9078\u64C7\u5728\u700F\u89BD\u6216\u662F\u5728\u64AD\u653E\u6E05\u55AE\u4E2D\uFF0C\u986F\u793A\u97F3\u6A02\u7684\u5404\u7A2E\u8A73\u7D30\u8CC7\u8A0A

helppopup.partymode.title = \u5BB4\u6703\u6A21\u5F0F helppopup.partymode.text =

\u4F7F\u7528\u5BB4\u6703\u6A21\u5F0F\u7C21\u5316\u4F7F\u7528\u8005\u754C\u9762\uFF0C\u63D0\u4F9B\u7D66\u7121\u7D93\u9A57\u7684\u4F7F\u7528\u8005\u64CD\u4F5C\ - \u4E5F\u53EF\u4EE5\u907F\u514D\u56E0\u70BA\u610F\u5916\u64CD\u4F5C\u800C\u5F04\u4E82\u4E86\u9EDE\u64AD\u6E05\u55AE.

+ \u4E5F\u53EF\u4EE5\u907F\u514D\u56E0\u70BA\u610F\u5916\u64CD\u4F5C\u800C\u5F04\u4E82\u4E86\u64AD\u653E\u6E05\u55AE\u3002

helppopup.theme.title = \u4F48\u666F\u4E3B\u984C -helppopup.theme.text =

\u8B93\u60A8\u53EF\u4EE5\u9078\u64C7\u4E0D\u540C\u7684\u4F48\u666F\u4E3B\u984C. \u4F48\u666F\u4E3B\u984C\u900F\u904E\u4E0D\u540C\u7684\u984F\u8272\u3001\u5B57\u9AD4\u3001\u5716\u50CF\u7B49\uFF0C\u5E36\u7D66\u60A8\u4E0D\u540C\u7684{0}\u611F\u53D7.

+helppopup.theme.text =

\u8B93\u60A8\u53EF\u4EE5\u9078\u64C7\u4E0D\u540C\u7684\u4F48\u666F\u4E3B\u984C\u3002\u4F48\u666F\u4E3B\u984C\u900F\u904E\u4E0D\u540C\u7684\u984F\u8272\u3001\u5B57\u9AD4\u3001\u5716\u50CF\u7B49\uFF0C\u5E36\u7D66\u60A8\u4E0D\u540C\u7684{0}\u611F\u53D7\u3002

helppopup.welcomemessage.title = \u6B61\u8FCE\u6A19\u984C -helppopup.welcomemessage.text =

\u5728\u9996\u9801\u4E2D\u986F\u793A\u7684\u6A19\u984C.

+helppopup.welcomemessage.text =

\u5728\u9996\u9801\u4E2D\u986F\u793A\u7684\u6A19\u984C\u3002

helppopup.loginmessage.title = \u767B\u5165\u8A0A\u606F -helppopup.loginmessage.text =

\u5728\u767B\u5165\u756B\u9762\u986F\u793A\u7684\u63D0\u793A\u8A0A\u606F.

+helppopup.loginmessage.text =

\u5728\u767B\u5165\u756B\u9762\u986F\u793A\u7684\u63D0\u793A\u8A0A\u606F\u3002

helppopup.coverartlimit.title = \u5C08\u8F2F\u5C01\u9762\u9650\u5236 -helppopup.coverartlimit.text =

\u5728\u4E00\u9801\u756B\u9762\u4E2D\u986F\u793A\u5C08\u8F2F\u5C01\u9762\u7684\u6700\u5927\u6578\u91CF.

+helppopup.coverartlimit.text =

\u5728\u4E00\u9801\u756B\u9762\u4E2D\u986F\u793A\u5C08\u8F2F\u5C01\u9762\u7684\u6700\u5927\u6578\u91CF\u3002

helppopup.downloadlimit.title = \u4E0B\u8F09\u9650\u5236 -helppopup.downloadlimit.text =

\u4E0B\u8F09\u6A94\u6848\u6642\u7684\u983B\u5BEC\u9650\u5236.

+helppopup.downloadlimit.text =

\u4E0B\u8F09\u6A94\u6848\u6642\u7684\u983B\u5BEC\u9650\u5236\u3002

helppopup.uploadlimit.title = \u4E0A\u50B3\u9650\u5236 -helppopup.uploadlimit.text =

\u4E0A\u50B3\u6A94\u6848\u6642\u7684\u983B\u5BEC\u9650\u5236.

-helppopup.streamport.title = \u975E-SSL \u4E32\u6D41 Port -helppopup.streamport.text =

\u672C\u9078\u9805\u53EA\u662F\u7528\u65BC\u5728\u4F3A\u670D\u5668\u4E0A\u7684 {0} \u4F7F\u7528 SSL (HTTPS)\u50B3\u8F38\u5354\u5B9A.

\u6709\u4E9B\u64AD\u653E\u5668 \ - (\u4F8B\u5982 Winamp) \u4E26\u672A\u652F\u63F4\u7D93\u7531SSL\u7684\u4E32\u6D41\u5354\u5B9A. \u5982\u679C\u60A8\u4E0D\u7D93\u7531SSL\u50B3\u9001\u4E32\u6D41\uFF0C\u8ACB\u6307\u5B9A\u901A\u8A0APORT(\u901A\u5E38\u662F80\u62164040)\ - \u8ACB\u6CE8\u610F\uFF0C\u4E32\u6D41\u97F3\u6A02\u4E26\u4E0D\u6703\u88AB\u52A0\u5BC6.

+helppopup.uploadlimit.text =

\u4E0A\u50B3\u6A94\u6848\u6642\u7684\u983B\u5BEC\u9650\u5236\u3002

+helppopup.streamport.title = \u975ESSL \u4E32\u6D41 Port +helppopup.streamport.text =

\u672C\u9078\u9805\u53EA\u662F\u7528\u65BC\u5728\u4F3A\u670D\u5668\u4E0A\u7684 {0} \u4F7F\u7528 SSL (HTTPS)\u50B3\u8F38\u5354\u5B9A\u3002

\u6709\u4E9B\u64AD\u653E\u5668 \ + (\u4F8B\u5982 Winamp) \u4E0D\u652F\u63F4\u7D93\u7531SSL\u7684\u4E32\u6D41\u5354\u5B9A\u3002\u5982\u679C\u60A8\u4E0D\u7D93\u7531SSL\u50B3\u9001\u4E32\u6D41\uFF0C\u8ACB\u6307\u5B9A\u901A\u8A0APORT(\u901A\u5E38\u662F80\u62164040)\ + \u8ACB\u6CE8\u610F\uFF0C\u4E32\u6D41\u97F3\u6A02\u4E26\u4E0D\u6703\u88AB\u52A0\u5BC6\u3002

helppopup.ldap.title = LDAP \u9A57\u8B49 -helppopup.ldap.text =

\u4F7F\u7528\u8005\u53EF\u4EE5\u7D93\u7531\u5916\u90E8\u7684LDAP\u4F3A\u670D\u5668\u9A57\u8B49 (\u5305\u62ECWindows Active Directory). \ - \u7576\u8A2D\u5B9A\u4F7F\u7528LDAP\u4F7F\u7528\u8005\u767B\u5165 {0}, \u5E33\u865F\u53CA\u5BC6\u78BC\u5C31\u7531\u5916\u90E8\u4F3A\u670D\u5668\u9A57\u8B49, \u800C\u4E0D\u662F\u7531{0}\u4F86\u9A57\u8B49.

+helppopup.ldap.text =

\u4F7F\u7528\u8005\u53EF\u4EE5\u7D93\u7531\u5916\u90E8\u7684LDAP\u4F3A\u670D\u5668\u9A57\u8B49 (\u5305\u62ECWindows Active Directory)\u3002\ + \u7576\u8A2D\u5B9A\u4F7F\u7528LDAP\u4F7F\u7528\u8005\u767B\u5165 {0}\uFF0C\u5E33\u865F\u53CA\u5BC6\u78BC\u5C31\u7531\u5916\u90E8\u4F3A\u670D\u5668\u9A57\u8B49\uFF0C\u800C\u4E0D\u662F\u7531{0}\u4F86\u9A57\u8B49\u3002

helppopup.ldapurl.title = LDAP \u4F4D\u5740 -helppopup.ldapurl.text =

\u8A2D\u5B9A LDAP \u4F3A\u670D\u5668\u7684\u4F4D\u5740. \u5354\u5B9A\u61C9\u8A72\u662F ldap:// \u6216 ldaps:// \ - (\u7D93\u7531SSL\u7684LDAP\u5354\u5B9A). \u8ACB\u53C3\u8003\u9019\u88E1 \ - \u6709\u66F4\u591A\u8A73\u7D30\u8AAA\u660E.

+helppopup.ldapurl.text =

\u8A2D\u5B9A LDAP \u4F3A\u670D\u5668\u7684\u4F4D\u5740\u3002\u5354\u5B9A\u61C9\u8A72\u662F ldap:// \u6216 ldaps:// \ + (\u7D93\u7531SSL\u7684LDAP\u5354\u5B9A)\u3002\u8ACB\u53C3\u8003\u9019\u88E1 \ + \u6709\u66F4\u591A\u8A73\u7D30\u8AAA\u660E\u3002

helppopup.ldapsearchfilter.title = LDAP \u641C\u5C0B\u904E\u6FFE helppopup.ldapsearchfilter.text =

\u8490\u5C0BLDAP\u7528\u6236\u6642\uFF0C\u5728\u9019\u88E1\u8A2D\u5B9A\u904E\u6FFE\u8868\u793A\u5F0F \ - (\u5B9A\u7FA9\u5728RFC 2254). \ + (\u5B9A\u7FA9\u5728RFC 2254)\u3002 \ The pattern "'{0'}" is replaced by the username, \u4F8B\u5982: \

    \
  • (uid='{0'}) - this would search for a username match on the uid attribute.
  • \ @@ -588,22 +809,33 @@ helppopup.ldapsearchfilter.text =

    \u8490\u5C0BLDAP\u7528\u6236\u6642\uFF0C\u5

helppopup.ldapmanagerdn.title = LDAP \u7BA1\u7406\u8005 DN helppopup.ldapmanagerdn.text =

\u5982\u679C LDAP \u4F3A\u670D\u5668\u4E0D\u652F\u63F4\u533F\u540D\u4F7F\u7528\u8005\u9023\u7DDA\uFF0C\u60A8\u5FC5\u9808\u6307\u5B9A DN \ - (Distinguished Name)\u53CALDAP\u4F7F\u7528\u8005\u7684\u5BC6\u78BC.

+ (Distinguished Name)\u53CALDAP\u4F7F\u7528\u8005\u7684\u5BC6\u78BC\u3002

helppopup.ldapautoshadowing.title = \u5728 {0} \u81EA\u52D5\u5EFA\u7ACB LDAP \u5E33\u865F -helppopup.ldapautoshadowing.text =

\u8A2D\u5B9A\u9019\u500B\u9078\u9805, \u5247LDAP \u7528\u6236\u4E0D\u5FC5\u5728\u767B\u5165\u4E4B\u524D\u624B\u52D5\u5EFA\u7ACB{0}\u7684\u5E33\u865F.

\ -

\u6CE8\u610F! \u9019\u610F\u5473\u6240\u6709\u5728LDAP\u4E0A\u7684\u4F7F\u7528\u8005\u90FD\u53EF\u4EE5\u767B\u5165\u60A8\u7684{0}, \ - \u4E5F\u8A31\u9019\u4E0D\u662F\u60A8\u60F3\u8981\u7684\u529F\u80FD.

+helppopup.ldapautoshadowing.text =

\u8A2D\u5B9A\u9019\u500B\u9078\u9805\uFF0C\u5247LDAP \u7528\u6236\u4E0D\u5FC5\u5728\u767B\u5165\u4E4B\u524D\u624B\u52D5\u5EFA\u7ACB{0}\u7684\u5E33\u865F\u3002

\ +

\u6CE8\u610F\uFF01 \u9019\u8868\u793A\u6240\u6709\u5728LDAP\u4E0A\u7684\u4F7F\u7528\u8005\u90FD\u53EF\u4EE5\u767B\u5165\u60A8\u7684{0}\uFF0C\ + \u4E5F\u8A31\u9019\u4E0D\u662F\u60A8\u60F3\u8981\u7684\u529F\u80FD\u3002

helppopup.playername.title = \u64A5\u653E\u5668\u540D\u7A31 -helppopup.playername.text =

\u8B93\u4F60\u5E6B\u64AD\u653E\u5668\u6307\u5B9A\u4E00\u500B\u5BB9\u6613\u8A18\u4F4F\u7684\u540D\u5B57\uFF0C\u5982\u201C\u5DE5\u4F5C\u5BA4\u201D\u6216\u201C\u5BA2\u5EF3\u201D

+helppopup.playername.text =

\u8B93\u60A8\u5E6B\u64AD\u653E\u5668\u6307\u5B9A\u4E00\u500B\u5BB9\u6613\u8A18\u4F4F\u7684\u540D\u5B57\uFF0C\u5982\u201C\u5DE5\u4F5C\u5BA4\u201D\u6216\u201C\u5BA2\u5EF3\u201D

helppopup.autocontrol.title = \u63A7\u5236\u64AD\u653E\u5668\u81EA\u52D5\u64AD\u653E -helppopup.autocontrol.text =

\u8A2D\u5B9A\u9019\u500B\u9078\u9805, {0} \u5728\u60A8\u958B\u59CB\u64AD\u653E\u6642\uFF0C\u6703\u81EA\u52D5\u555F\u52D5\u64AD\u653E\u5668\ - \u5426\u5247\u60A8\u5FC5\u9808\u81EA\u5DF1\u555F\u52D5\u4E26\u4E14\u9023\u63A5\u60A8\u7684\u64A5\u653E\u5668.

+helppopup.autocontrol.text =

\u8A2D\u5B9A\u9019\u500B\u9078\u9805\uFF0C {0} \u5728\u60A8\u958B\u59CB\u64AD\u653E\u6642\uFF0C\u6703\u81EA\u52D5\u555F\u52D5\u64AD\u653E\u5668\ + \u5426\u5247\u60A8\u5FC5\u9808\u81EA\u5DF1\u555F\u52D5\u4E26\u4E14\u9023\u63A5\u60A8\u7684\u64A5\u653E\u5668\u3002

helppopup.dynamicip.title = \u52D5\u614B IP \u4F4D\u5740 -helppopup.dynamicip.text =

\u95DC\u9589\u6B64\u9078\u9805\uFF0C\u5982\u679C\u60A8\u4F7F\u7528\u975C\u614BIP\u4F4D\u5740.

+helppopup.dynamicip.text =

\u95DC\u9589\u6B64\u9078\u9805\uFF0C\u5982\u679C\u60A8\u4F7F\u7528\u975C\u614BIP\u4F4D\u5740\u3002

+helppopup.smtpServer.title = SMTP \u4F3A\u670D\u5668 +helppopup.smtpServer.text =

The hostname of the SMTP server. This server will be used to send e-mails to users \ + who have requested a password reset.

+helppopup.smtpPort.title = SMTP Port +helppopup.smtpPort.text =

The server's port that should be connected to for SMTP traffic.

+helppopup.smtpCredentials.title = SMTP Credentials +helppopup.smtpCredentials.text =

The credentials to be used to connect to the SMTP server. Leave empty to connect without authentication.

+helppopup.smtpEncryption.title = SMTP Encryption +helppopup.smtpEncryption.text =

The encryption method to be used to connect to the SMTP server. Choose "None" for no encryption.

+helppopup.smtpFrom.title = From address +helppopup.smtpFrom.text =

The sender address for mails originating from the Libresonic server. Must be a valid e-mail address.

# wap/index.jsp wap.index.missing = \u627E\u4E0D\u5230\u97F3\u6A02 -wap.index.playlist = \u9EDE\u64AD\u6E05\u55AE +wap.index.playlist = \u64AD\u653E\u6E05\u55AE wap.index.search = \u641C\u5C0B wap.index.settings = \u8A2D\u5B9A @@ -616,7 +848,7 @@ wap.browse.downloadone = \u4E0B\u8F09\u6B4C\u66F2 wap.browse.downloadall = \u5168\u90E8\u4E0B\u8F09 # wap/playlist.jsp -wap.playlist.title =\u9EDE\u64AD\u6E05\u55AE +wap.playlist.title = \u64AD\u653E\u6E05\u55AE wap.playlist.noplayer = \u9023\u63A5\u4E0D\u5230\u64AD\u653E\u5668 wap.playlist.clear = \u6E05\u9664 wap.playlist.load = \u8F09\u5165 @@ -627,7 +859,7 @@ wap.playlist.play = \u5728\u96FB\u8A71\u4E2D\u64AD\u9001 wap.search.title = \u641C\u5C0B # wap/searchResult.jsp -wap.searchresult.index = \u6B63\u5728\u5EFA\u7ACB\u641C\u5C0B\u7D22\u5F15\u3002\u8ACB\u7A0D\u5F8C\u518D\u8A66. +wap.searchresult.index = \u6B63\u5728\u5EFA\u7ACB\u641C\u5C0B\u7D22\u5F15\u3002\u8ACB\u7A0D\u5F8C\u518D\u8A66\u3002 # wap/settings.jsp wap.settings.selectplayer = \u9078\u64C7\u64AD\u653E\u5668 diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-cache.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-cache.xml index da4c296a..3a33be97 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-cache.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-cache.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-service.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-service.xml index ee7ab0ac..daa22901 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-service.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-service.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-sonos.xml b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-sonos.xml index ae2e9b60..b3157491 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/applicationContext-sonos.xml +++ b/libresonic-main/src/main/webapp/WEB-INF/applicationContext-sonos.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp index 19fd2f79..429275b5 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp @@ -481,6 +481,7 @@ + diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/artistMain.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/artistMain.jsp index c7290c15..f843dac0 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/artistMain.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/artistMain.jsp @@ -273,6 +273,7 @@ + diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp index c4242ecd..8d9eee77 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp @@ -15,6 +15,7 @@ PARAMETERS showZoom: Whether to display a link for zooming the cover art. showChange: Whether to display a link for changing the cover art. appearAfter: Fade in after this many milliseconds, or nil if no fading in should happen. + hideOverflow: Hide cover art overflow when height is greater than width --%> @@ -32,7 +33,7 @@ PARAMETERS
-
+
overflow:hidden;" title="${param.caption1}" id="${divId}"> diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/home.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/home.jsp index 124d16a3..38040f27 100644 --- a/libresonic-main/src/main/webapp/WEB-INF/jsp/home.jsp +++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/home.jsp @@ -7,7 +7,9 @@