add BOM support for generating m3u file
Signed-off-by: Shen-Ta Hsieh <ibmibmibm.tw@gmail.com>
This commit is contained in:
@@ -41,6 +41,7 @@ public class PlayerSettingsCommand {
|
|||||||
private Date lastSeen;
|
private Date lastSeen;
|
||||||
private boolean isDynamicIp;
|
private boolean isDynamicIp;
|
||||||
private boolean isAutoControlEnabled;
|
private boolean isAutoControlEnabled;
|
||||||
|
private boolean isM3uBomEnabled;
|
||||||
private String technologyName;
|
private String technologyName;
|
||||||
private String transcodeSchemeName;
|
private String transcodeSchemeName;
|
||||||
private boolean transcodingSupported;
|
private boolean transcodingSupported;
|
||||||
@@ -109,6 +110,14 @@ public class PlayerSettingsCommand {
|
|||||||
isAutoControlEnabled = autoControlEnabled;
|
isAutoControlEnabled = autoControlEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isM3uBomEnabled() {
|
||||||
|
return isM3uBomEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setM3uBomEnabled(boolean m3uBomEnabled) {
|
||||||
|
isM3uBomEnabled = m3uBomEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTranscodeSchemeName() {
|
public String getTranscodeSchemeName() {
|
||||||
return transcodeSchemeName;
|
return transcodeSchemeName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ public class M3UController implements Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createClientSidePlaylist(PrintWriter out, Player player, String url) throws Exception {
|
private void createClientSidePlaylist(PrintWriter out, Player player, String url) throws Exception {
|
||||||
|
if (player.isM3uBomEnabled()) {
|
||||||
|
out.print("\ufeff");
|
||||||
|
}
|
||||||
out.println("#EXTM3U");
|
out.println("#EXTM3U");
|
||||||
List<MediaFile> result;
|
List<MediaFile> result;
|
||||||
synchronized (player.getPlayQueue()) {
|
synchronized (player.getPlayQueue()) {
|
||||||
@@ -99,6 +102,9 @@ public class M3UController implements Controller {
|
|||||||
url += "&suffix=." + suffix;
|
url += "&suffix=." + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player.isM3uBomEnabled()) {
|
||||||
|
out.print("\ufeff");
|
||||||
|
}
|
||||||
out.println("#EXTM3U");
|
out.println("#EXTM3U");
|
||||||
out.println("#EXTINF:-1,Libresonic");
|
out.println("#EXTINF:-1,Libresonic");
|
||||||
out.println(url);
|
out.println(url);
|
||||||
|
|||||||
+2
@@ -72,6 +72,7 @@ public class PlayerSettingsController extends SimpleFormController {
|
|||||||
command.setLastSeen(player.getLastSeen());
|
command.setLastSeen(player.getLastSeen());
|
||||||
command.setDynamicIp(player.isDynamicIp());
|
command.setDynamicIp(player.isDynamicIp());
|
||||||
command.setAutoControlEnabled(player.isAutoControlEnabled());
|
command.setAutoControlEnabled(player.isAutoControlEnabled());
|
||||||
|
command.setM3uBomEnabled(player.isM3uBomEnabled());
|
||||||
command.setTranscodeSchemeName(player.getTranscodeScheme().name());
|
command.setTranscodeSchemeName(player.getTranscodeScheme().name());
|
||||||
command.setTechnologyName(player.getTechnology().name());
|
command.setTechnologyName(player.getTechnology().name());
|
||||||
command.setAllTranscodings(transcodingService.getAllTranscodings());
|
command.setAllTranscodings(transcodingService.getAllTranscodings());
|
||||||
@@ -99,6 +100,7 @@ public class PlayerSettingsController extends SimpleFormController {
|
|||||||
Player player = playerService.getPlayerById(command.getPlayerId());
|
Player player = playerService.getPlayerById(command.getPlayerId());
|
||||||
|
|
||||||
player.setAutoControlEnabled(command.isAutoControlEnabled());
|
player.setAutoControlEnabled(command.isAutoControlEnabled());
|
||||||
|
player.setM3uBomEnabled(command.isM3uBomEnabled());
|
||||||
player.setDynamicIp(command.isDynamicIp());
|
player.setDynamicIp(command.isDynamicIp());
|
||||||
player.setName(StringUtils.trimToNull(command.getName()));
|
player.setName(StringUtils.trimToNull(command.getName()));
|
||||||
player.setTranscodeScheme(TranscodeScheme.valueOf(command.getTranscodeSchemeName()));
|
player.setTranscodeScheme(TranscodeScheme.valueOf(command.getTranscodeSchemeName()));
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.libresonic.player.dao.schema.hsql.Schema51;
|
|||||||
import org.libresonic.player.dao.schema.hsql.Schema52;
|
import org.libresonic.player.dao.schema.hsql.Schema52;
|
||||||
import org.libresonic.player.dao.schema.hsql.Schema53;
|
import org.libresonic.player.dao.schema.hsql.Schema53;
|
||||||
import org.libresonic.player.dao.schema.hsql.Schema61;
|
import org.libresonic.player.dao.schema.hsql.Schema61;
|
||||||
|
import org.libresonic.player.dao.schema.hsql.Schema62;
|
||||||
import org.libresonic.player.service.SettingsService;
|
import org.libresonic.player.service.SettingsService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,7 +69,8 @@ public class HsqlDaoHelper implements DaoHelper {
|
|||||||
new Schema30(), new Schema31(), new Schema32(), new Schema33(), new Schema34(),
|
new Schema30(), new Schema31(), new Schema32(), new Schema33(), new Schema34(),
|
||||||
new Schema35(), new Schema36(), new Schema37(), new Schema38(), new Schema40(),
|
new Schema35(), new Schema36(), new Schema37(), new Schema38(), new Schema40(),
|
||||||
new Schema43(), new Schema45(), new Schema46(), new Schema47(), new Schema49(),
|
new Schema43(), new Schema45(), new Schema46(), new Schema47(), new Schema49(),
|
||||||
new Schema50(), new Schema51(), new Schema52(), new Schema53(), new Schema61()};
|
new Schema50(), new Schema51(), new Schema52(), new Schema53(), new Schema61(),
|
||||||
|
new Schema62()};
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
private static boolean shutdownHookAdded;
|
private static boolean shutdownHookAdded;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import org.libresonic.player.domain.TranscodeScheme;
|
|||||||
public class PlayerDao extends AbstractDao {
|
public class PlayerDao extends AbstractDao {
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(PlayerDao.class);
|
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";
|
"last_seen, cover_art_scheme, transcode_scheme, dynamic_ip, technology, client_id";
|
||||||
|
|
||||||
private PlayerRowMapper rowMapper = new PlayerRowMapper();
|
private PlayerRowMapper rowMapper = new PlayerRowMapper();
|
||||||
@@ -99,7 +99,7 @@ public class PlayerDao extends AbstractDao {
|
|||||||
player.setId(String.valueOf(id));
|
player.setId(String.valueOf(id));
|
||||||
String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")";
|
String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")";
|
||||||
update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(),
|
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.getLastSeen(), CoverArtScheme.MEDIUM.name(),
|
||||||
player.getTranscodeScheme().name(), player.isDynamicIp(),
|
player.getTranscodeScheme().name(), player.isDynamicIp(),
|
||||||
player.getTechnology().name(), player.getClientId());
|
player.getTechnology().name(), player.getClientId());
|
||||||
@@ -148,6 +148,7 @@ public class PlayerDao extends AbstractDao {
|
|||||||
"username = ?," +
|
"username = ?," +
|
||||||
"ip_address = ?," +
|
"ip_address = ?," +
|
||||||
"auto_control_enabled = ?," +
|
"auto_control_enabled = ?," +
|
||||||
|
"m3u_bom_enabled = ?," +
|
||||||
"last_seen = ?," +
|
"last_seen = ?," +
|
||||||
"transcode_scheme = ?, " +
|
"transcode_scheme = ?, " +
|
||||||
"dynamic_ip = ?, " +
|
"dynamic_ip = ?, " +
|
||||||
@@ -155,7 +156,7 @@ public class PlayerDao extends AbstractDao {
|
|||||||
"client_id = ? " +
|
"client_id = ? " +
|
||||||
"where id = ?";
|
"where id = ?";
|
||||||
update(sql, player.getName(), player.getType(), player.getUsername(),
|
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.getLastSeen(), player.getTranscodeScheme().name(), player.isDynamicIp(),
|
||||||
player.getTechnology(), player.getClientId(), player.getId());
|
player.getTechnology(), player.getClientId(), player.getId());
|
||||||
}
|
}
|
||||||
@@ -179,6 +180,7 @@ public class PlayerDao extends AbstractDao {
|
|||||||
player.setUsername(rs.getString(col++));
|
player.setUsername(rs.getString(col++));
|
||||||
player.setIpAddress(rs.getString(col++));
|
player.setIpAddress(rs.getString(col++));
|
||||||
player.setAutoControlEnabled(rs.getBoolean(col++));
|
player.setAutoControlEnabled(rs.getBoolean(col++));
|
||||||
|
player.setM3uBomEnabled(rs.getBoolean(col++));
|
||||||
player.setLastSeen(rs.getTimestamp(col++));
|
player.setLastSeen(rs.getTimestamp(col++));
|
||||||
col++; // Ignore cover art scheme.
|
col++; // Ignore cover art scheme.
|
||||||
player.setTranscodeScheme(TranscodeScheme.valueOf(rs.getString(col++)));
|
player.setTranscodeScheme(TranscodeScheme.valueOf(rs.getString(col++)));
|
||||||
|
|||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ public class Player {
|
|||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
private boolean isDynamicIp = true;
|
private boolean isDynamicIp = true;
|
||||||
private boolean isAutoControlEnabled = true;
|
private boolean isAutoControlEnabled = true;
|
||||||
|
private boolean isM3uBomEnabled = true;
|
||||||
private Date lastSeen;
|
private Date lastSeen;
|
||||||
private TranscodeScheme transcodeScheme = TranscodeScheme.OFF;
|
private TranscodeScheme transcodeScheme = TranscodeScheme.OFF;
|
||||||
private PlayQueue playQueue;
|
private PlayQueue playQueue;
|
||||||
@@ -188,6 +189,24 @@ public class Player {
|
|||||||
this.isAutoControlEnabled = isAutoControlEnabled;
|
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.
|
* Returns the time when the player was last seen.
|
||||||
*
|
*
|
||||||
|
|||||||
+1
@@ -512,6 +512,7 @@ playersettings.name = Player name
|
|||||||
playersettings.maxbitrate = Max bitrate
|
playersettings.maxbitrate = Max bitrate
|
||||||
playersettings.notranscoder = <em>Notice:</em> Transcoders does not appear to be installed.<br>Click Help button for more information.
|
playersettings.notranscoder = <em>Notice:</em> Transcoders does not appear to be installed.<br>Click Help button for more information.
|
||||||
playersettings.autocontrol = Control player automatically
|
playersettings.autocontrol = Control player automatically
|
||||||
|
playersettings.m3ubom = Apply BOM signature in the generated M3U file
|
||||||
playersettings.dynamicip = Player has dynamic IP address
|
playersettings.dynamicip = Player has dynamic IP address
|
||||||
playersettings.transcodings = Active transcodings
|
playersettings.transcodings = Active transcodings
|
||||||
playersettings.ok = Save
|
playersettings.ok = Save
|
||||||
|
|||||||
+1
@@ -512,6 +512,7 @@ playersettings.name = \u64A5\u653E\u5668\u540D\u7A31
|
|||||||
playersettings.maxbitrate = \u6700\u5927\u50B3\u8F38\u7387
|
playersettings.maxbitrate = \u6700\u5927\u50B3\u8F38\u7387
|
||||||
playersettings.notranscoder = <em>\u6CE8\u610F:</em> \u8F49\u78BC\u5F15\u64CE\u5C1A\u672A\u5B89\u88DD\u3002<br>\u9EDE\u9078\u3010\u8AAA\u660E\u3011\u7372\u5F97\u66F4\u591A\u8CC7\u8A0A\u3002
|
playersettings.notranscoder = <em>\u6CE8\u610F:</em> \u8F49\u78BC\u5F15\u64CE\u5C1A\u672A\u5B89\u88DD\u3002<br>\u9EDE\u9078\u3010\u8AAA\u660E\u3011\u7372\u5F97\u66F4\u591A\u8CC7\u8A0A\u3002
|
||||||
playersettings.autocontrol = \u81EA\u52D5\u64AD\u653E
|
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.dynamicip = \u64A5\u653E\u5668\u4F7F\u7528\u52D5\u614BIP\u4F4D\u5740
|
||||||
playersettings.transcodings = \u555F\u52D5\u7684\u8F49\u78BC\u7A0B\u5F0F
|
playersettings.transcodings = \u555F\u52D5\u7684\u8F49\u78BC\u7A0B\u5F0F
|
||||||
playersettings.ok = \u5132\u5B58
|
playersettings.ok = \u5132\u5B58
|
||||||
|
|||||||
@@ -132,6 +132,14 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><c:import url="helpToolTip.jsp"><c:param name="topic" value="autocontrol"/></c:import></td>
|
<td><c:import url="helpToolTip.jsp"><c:param name="topic" value="autocontrol"/></c:import></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<form:checkbox path="m3uBomEnabled" id="m3uBomEnabled" cssClass="checkbox"/>
|
||||||
|
<label for="m3uBomEnabled"><fmt:message key="playersettings.m3ubom"/></label>
|
||||||
|
</td>
|
||||||
|
<td><c:import url="helpToolTip.jsp"><c:param name="topic" value="m3ubom"/></c:import></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<c:if test="${not empty command.allTranscodings}">
|
<c:if test="${not empty command.allTranscodings}">
|
||||||
|
|||||||
Reference in New Issue
Block a user