/* * PS3 Media Server, for streaming any medias to your PS3. * Copyright (C) 2008 A.Brochard * * This program 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; version 2 * of the License only. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.pms.configuration; import com.sun.jna.Platform; import net.pms.Messages; import net.pms.io.SystemUtils; import net.pms.util.FileUtil; import net.pms.util.FileUtil.FileLocation; import net.pms.util.PropertiesUtil; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.event.ConfigurationListener; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; import static java.util.Arrays.asList; import static org.apache.commons.lang3.StringUtils.join; import static org.apache.commons.lang3.StringUtils.split; /** * Container for all configurable PMS settings. Settings are typically defined by three things: * a unique key for use in the configuration file "PMS.conf", a getter (and setter) method and * a default value. When a key cannot be found in the current configuration, the getter will * return a default value. Setters only store a value, they do not permanently save it to * file. */ public class PmsConfiguration { private static final Logger logger = LoggerFactory.getLogger(PmsConfiguration.class); private static final int DEFAULT_SERVER_PORT = 5001; /* * MEncoder has a hardwired maximum of 8 threads for -lavcopts and 16 * for -lavdopts. */ // https://code.google.com/p/ps3mediaserver/issues/detail?id=517 private static final int MENCODER_MAX_THREADS = 8; private static final String KEY_ALTERNATE_SUBTITLE_FOLDER = "alternate_subtitle_folder"; private static final String KEY_ALTERNATE_THUMB_FOLDER = "alternate_thumb_folder"; private static final String KEY_SHOW_APERTURE_LIBRARY = "show_aperture_library"; private static final String KEY_AUDIO_BITRATE = "audio_bitrate"; private static final String KEY_AUDIO_CHANNEL_COUNT = "audio_channels"; private static final String KEY_AUDIO_LANGUAGES = "audio_languages"; private static final String KEY_AUDIO_RESAMPLE = "audio_resample"; private static final String KEY_AUDIO_SUB_LANGS = "audio_subtitle_languages"; private static final String KEY_AUDIO_THUMBNAIL_METHOD = "audio_thumbnail_method"; private static final String KEY_AUTO_UPDATE = "auto_update"; private static final String KEY_AUTOLOAD_SUBTITLES = "autoload_external_subtitles"; private static final String KEY_AVISYNTH_CONVERT_FPS = "avisynth_convert_fps"; private static final String KEY_AVISYNTH_SCRIPT = "avisynth_script"; private static final String KEY_ASS_MARGIN = "subtitle_ass_margin"; private static final String KEY_ASS_OUTLINE = "subtitle_ass_outline"; private static final String KEY_ASS_SCALE = "subtitle_ass_scale"; private static final String KEY_ASS_SHADOW = "subtitle_ass_shadow"; private static final String KEY_BUFFER_MAX = "buffer_max"; private static final String KEY_CHAPTER_INTERVAL = "chapter_interval"; private static final String KEY_CHAPTER_SUPPORT = "chapter_support"; private static final String KEY_MENCODER_CODEC_SPECIFIC_SCRIPT = "mencoder_codec_specific_script"; private static final String KEY_DISABLE_FAKESIZE = "disable_fakesize"; public static final String KEY_DISABLE_SUBTITLES = "disable_subtitles"; // used by MEncoderVideo private static final String KEY_DVD_ISO_THUMBNAILS = "dvd_iso_thumbnails"; private static final String KEY_AUDIO_EMBED_DTS_IN_PCM = "audio_embed_dts_in_pcm"; private static final String KEY_ENGINES = "engines"; private static final String KEY_FFMPEG_ALTERNATIVE_PATH = "alternativeffmpegpath"; // TODO deprecated: FFmpegDVRMSRemux will be removed and DVR-MS will be transcoded private static final String KEY_FFMPEG_MULTITHREADING = "ffmpeg_multithreading"; private static final String KEY_FFMPEG_MUX_COMPATIBLE = "ffmpeg_mux_compatible"; private static final String KEY_FILENAME_FORMAT_LONG = "filename_format_long"; private static final String KEY_FILENAME_FORMAT_SHORT = "filename_format_short"; private static final String KEY_FIX_25FPS_AV_MISMATCH = "fix_25fps_av_mismatch"; private static final String KEY_FONT = "subtitle_font"; private static final String KEY_FORCED_SUBTITLE_LANGUAGE = "forced_subtitle_language"; private static final String KEY_FORCED_SUBTITLE_TAGS = "forced_subtitle_tags"; private static final String KEY_FORCE_TRANSCODE_FOR_EXTENSIONS = "force_transcode_for_extensions"; private static final String KEY_HIDE_EMPTY_FOLDERS = "hide_empty_folders"; private static final String KEY_HIDE_ENGINENAMES = "hide_engine_names"; private static final String KEY_HIDE_EXTENSIONS = "hide_extensions"; private static final String KEY_HIDE_MEDIA_LIBRARY_FOLDER = "hide_media_library_folder"; private static final String KEY_HIDE_TRANSCODE_FOLDER = "hide_transcode_folder"; private static final String KEY_HIDE_VIDEO_SETTINGS = "hide_video_settings"; private static final String KEY_HTTP_ENGINE_V2 = "http_engine_v2"; private static final String KEY_IMAGE_THUMBNAILS_ENABLED = "image_thumbnails"; private static final String KEY_IP_FILTER = "ip_filter"; private static final String KEY_SHOW_IPHOTO_LIBRARY = "show_iphoto_library"; private static final String KEY_SHOW_ITUNES_LIBRARY = "show_itunes_library"; private static final String KEY_LANGUAGE = "language"; private static final String KEY_MAX_AUDIO_BUFFER = "maximum_audio_buffer_size"; private static final String KEY_MAX_BITRATE = "maximum_bitrate"; private static final String KEY_MAX_MEMORY_BUFFER_SIZE = "maximum_video_buffer_size"; private static final String KEY_MENCODER_ASS = "mencoder_ass"; private static final String KEY_MENCODER_AC3_FIXED = "mencoder_ac3_fixed"; private static final String KEY_MENCODER_ASS_DEFAULTSTYLE = "mencoder_ass_defaultstyle"; private static final String KEY_MENCODER_CUSTOM_OPTIONS = "mencoder_custom_options"; private static final String KEY_MENCODER_FONT_CONFIG = "mencoder_fontconfig"; private static final String KEY_MENCODER_FORCE_FPS = "mencoder_forcefps"; private static final String KEY_MENCODER_INTELLIGENT_SYNC = "mencoder_intelligent_sync"; private static final String KEY_MENCODER_MAX_THREADS = "mencoder_max_threads"; private static final String KEY_MENCODER_MT = "mencoder_mt"; private static final String KEY_MENCODER_NOASS_BLUR = "mencoder_noass_blur"; private static final String KEY_MENCODER_NOASS_OUTLINE = "mencoder_noass_outline"; private static final String KEY_MENCODER_NOASS_SCALE = "mencoder_noass_scale"; private static final String KEY_MENCODER_NOASS_SUBPOS = "mencoder_noass_subpos"; private static final String KEY_MENCODER_NO_OUT_OF_SYNC = "mencoder_no_out_of_sync"; private static final String KEY_MENCODER_OVERSCAN_COMPENSATION_HEIGHT = "mencoder_overscan_compensation_height"; private static final String KEY_MENCODER_OVERSCAN_COMPENSATION_WIDTH = "mencoder_overscan_compensation_width"; private static final String KEY_AUDIO_REMUX_AC3 = "audio_remux_ac3"; private static final String KEY_MENCODER_REMUX_MPEG2 = "mencoder_remux_mpeg2"; private static final String KEY_MENCODER_SCALER = "mencoder_scaler"; private static final String KEY_MENCODER_SCALEX = "mencoder_scalex"; private static final String KEY_MENCODER_SCALEY = "mencoder_scaley"; private static final String KEY_MENCODER_SUB_FRIBIDI = "mencoder_sub_fribidi"; private static final String KEY_MENCODER_USE_PCM_FOR_HQ_AUDIO_ONLY = "mencoder_usepcm_for_hq_audio_only"; private static final String KEY_MENCODER_VOBSUB_SUBTITLE_QUALITY = "mencoder_vobsub_subtitle_quality"; private static final String KEY_MENCODER_YADIF = "mencoder_yadif"; private static final String KEY_MINIMIZED = "minimized"; private static final String KEY_MIN_MEMORY_BUFFER_SIZE = "minimum_video_buffer_size"; private static final String KEY_MIN_STREAM_BUFFER = "minimum_web_buffer_size"; private static final String KEY_MPEG2_MAIN_SETTINGS = "mpeg2_main_settings"; private static final String KEY_MUX_ALLAUDIOTRACKS = "tsmuxer_mux_all_audiotracks"; private static final String KEY_NETWORK_INTERFACE = "network_interface"; private static final String KEY_DISABLE_TRANSCODE_FOR_EXTENSIONS = "disable_transcode_for_extensions"; private static final String KEY_NUMBER_OF_CPU_CORES = "number_of_cpu_cores"; private static final String KEY_OPEN_ARCHIVES = "enable_archive_browsing"; private static final String KEY_OVERSCAN = "mencoder_overscan"; private static final String KEY_PLUGIN_DIRECTORY = "plugins"; private static final String KEY_PREVENTS_SLEEP = "prevents_sleep_mode"; private static final String KEY_PROFILE_NAME = "name"; private static final String KEY_RENDERER_DEFAULT = "renderer_default"; private static final String KEY_RENDERER_FORCE_DEFAULT = "renderer_force_default"; private static final String KEY_RENDERER_FORCE_IP = "renderer_force_ip"; private static final String KEY_SERVER_HOSTNAME = "hostname"; private static final String KEY_SERVER_PORT = "port"; private static final String KEY_SHARES = "shares"; private static final String KEY_SKIP_LOOP_FILTER_ENABLED = "mencoder_skip_loop_filter"; private static final String KEY_SKIP_NETWORK_INTERFACES = "skip_network_interfaces"; private static final String KEY_SORT_METHOD = "sort_method"; private static final String KEY_SUBS_COLOR = "subtitle_color"; private static final String KEY_SUBTITLE_CODEPAGE = "subtitle_codepage"; private static final String KEY_SUBTITLE_LANGUAGES = "subtitle_languages"; private static final String KEY_TEMP_FOLDER_PATH = "temp_directory"; private static final String KEY_THUMBNAIL_GENERATION_ENABLED = "generate_thumbnails"; private static final String KEY_THUMBNAIL_SEEK_POS = "thumbnail_seek_position"; private static final String KEY_TRANSCODE_BLOCKS_MULTIPLE_CONNECTIONS = "transcode_block_multiple_connections"; private static final String KEY_TRANSCODE_FOLDER_NAME = "transcode_folder_name"; private static final String KEY_TRANSCODE_KEEP_FIRST_CONNECTION = "transcode_keep_first_connection"; private static final String KEY_TSMUXER_FORCEFPS = "tsmuxer_forcefps"; private static final String KEY_UPNP_PORT = "upnp_port"; private static final String KEY_USE_CACHE = "use_cache"; private static final String KEY_USE_MPLAYER_FOR_THUMBS = "use_mplayer_for_video_thumbs"; private static final String KEY_AUDIO_USE_PCM = "audio_use_pcm"; private static final String KEY_UUID = "uuid"; private static final String KEY_VIDEOTRANSCODE_START_DELAY = "videotranscode_start_delay"; private static final String KEY_VIRTUAL_FOLDERS = "vfolders"; private static final String KEY_VLC_USE_EXPERIMENTAL_CODECS = "vlc_use_experimental_codecs"; private static final String KEY_VLC_AUDIO_SYNC_ENABLED = "vlc_audio_sync_enabled"; private static final String KEY_VLC_SUBTITLE_ENABLED = "vlc_subtitle_enabled"; private static final String KEY_VLC_SCALE = "vlc_scale"; private static final String KEY_VLC_SAMPLE_RATE_OVERRIDE = "vlc_sample_rate_override"; private static final String KEY_VLC_SAMPLE_RATE = "vlc_sample_rate"; private static final String KEY_VIDEO_HW_ACCELERATION = "video_hardware_acceleration"; private static final String KEY_WEB_CONF_PATH = "web_conf"; // The name of the subdirectory under which PMS config files are stored for this build (default: UMS). // See Build for more details private static final String PROFILE_DIRECTORY_NAME = Build.getProfileDirectoryName(); // The default profile name displayed on the renderer private static String hostName; private static String DEFAULT_AVI_SYNTH_SCRIPT; private static final int MAX_MAX_MEMORY_DEFAULT_SIZE = 400; private static final int BUFFER_MEMORY_FACTOR = 368; private static int MAX_MAX_MEMORY_BUFFER_SIZE = MAX_MAX_MEMORY_DEFAULT_SIZE; private static final char LIST_SEPARATOR = ','; private static final String KEY_FOLDERS = "folders"; private final PropertiesConfiguration configuration; private final ConfigurationReader configurationReader; private final TempFolder tempFolder; private final ProgramPaths programPaths; private final IpFilter filter = new IpFilter(); /* * aCodec - audio codec * aFlavor - audio flavor * aFull - audio language full name * aShort - audio language short name * dvdLen - DVD track duration * eFull - engine full name * eShort - engine short name * fFull - file name with extension * fShort - file name without extension * isVTS - true if the resource is a DVD VIDEO_TS folder * sExt - external subtitles * sFlavor - subtitle flavor * sFull - subtitle language full name * sShort - subtitle language short name * sType - subtitle type * vtsDVD - the name of the parent folder of the VIDEO_TS folder */ private static final String FILENAME_FORMAT_SHORT = StringUtils.join( asList( "<[,eFull,]>", "<if aCodec> {<aLabel>: <aCodec>/<aFull>< (,aFlavor,)>} <end>", "<if sType> {<sLabel>: <sType>/<sFull>< (,sFlavor,)>} <end>" ), " " ); private static final String FILENAME_FORMAT_LONG = StringUtils.join( asList( "<fFull>", "<if isVTS>< {,vtsDVD,}><end>", "<if extra> - <end>", "<dvdLen>", "<[,eFull,]>", "<{,sExt,}>", "<if sType> {<sLabel>: <sType>/<sFull>< (,sFlavor,)>} <end>" ), " " ); /** * The set of keys defining when the HTTP server has to restarted due to a configuration change */ public static final Set<String> NEED_RELOAD_FLAGS = new HashSet<String>( asList( KEY_ALTERNATE_THUMB_FOLDER, KEY_NETWORK_INTERFACE, KEY_IP_FILTER, KEY_SORT_METHOD, KEY_HIDE_EMPTY_FOLDERS, KEY_HIDE_TRANSCODE_FOLDER, KEY_HIDE_MEDIA_LIBRARY_FOLDER, KEY_OPEN_ARCHIVES, KEY_USE_CACHE, KEY_HIDE_ENGINENAMES, KEY_SHOW_ITUNES_LIBRARY, KEY_SHOW_IPHOTO_LIBRARY, KEY_SHOW_APERTURE_LIBRARY, KEY_ENGINES, KEY_FOLDERS, KEY_HIDE_VIDEO_SETTINGS, KEY_AUDIO_THUMBNAIL_METHOD, KEY_DISABLE_TRANSCODE_FOR_EXTENSIONS, KEY_FORCE_TRANSCODE_FOR_EXTENSIONS, KEY_SERVER_PORT, KEY_SERVER_HOSTNAME, KEY_CHAPTER_SUPPORT, KEY_HIDE_EXTENSIONS ) ); /* The following code enables a single setting - PMS_PROFILE - to be used to initialize PROFILE_PATH i.e. the path to the current session's profile (AKA PMS.conf). It also initializes PROFILE_DIRECTORY - i.e. the directory the profile is located in - which is needed to detect the default WEB.conf location (anything else?). PMS_PROFILE is read (in this order) from the property pms.profile.path or the environment variable PMS_PROFILE. If PMS is launched with the command-line option "profiles" (e.g. from a shortcut), it displays a file chooser dialog that allows the pms.profile.path property to be set. This makes it easy to run PMS under multiple profiles without fiddling with environment variables, properties or command-line arguments. 1) if PMS_PROFILE is not set, PMS.conf is located in: Windows: %ALLUSERSPROFILE%\$build Mac OS X: $HOME/Library/Application Support/$build Everything else: $HOME/.config/$build - where $build is a subdirectory that ensures incompatible PMS builds don't target/clobber the same configuration files. The default value for $build is "PMS". Other builds might use e.g. "PMS Rendr Edition" or "pms-mlx". 2) if a relative or absolute *directory path* is supplied (the directory must exist), it is used as the profile directory and the profile is located there under the default profile name (PMS.conf): PMS_PROFILE = /absolute/path/to/dir PMS_PROFILE = relative/path/to/dir # relative to the working directory Amongst other things, this can be used to restore the legacy behaviour of locating PMS.conf in the current working directory e.g.: PMS_PROFILE=. ./PMS.sh 3) if a relative or absolute *file path* is supplied (the file doesn't have to exist), it is taken to be the profile, and its parent dir is taken to be the profile (i.e. config file) dir: PMS_PROFILE = PMS.conf # profile dir = . PMS_PROFILE = folder/dev.conf # profile dir = folder PMS_PROFILE = /path/to/some.file # profile dir = /path/to/ */ private static final String DEFAULT_PROFILE_FILENAME = "PMS.conf"; private static final String ENV_PROFILE_PATH = "PMS_PROFILE"; private static final String DEFAULT_WEB_CONF_FILENAME = "WEB.conf"; // Path to directory containing PMS config files private static final String PROFILE_DIRECTORY; // Absolute path to profile file e.g. /path/to/PMS.conf private static final String PROFILE_PATH; // Absolute path to WEB.conf file e.g. /path/to/WEB.conf private static String WEB_CONF_PATH; // Absolute path to skel (default) profile file e.g. /etc/skel/.config/ps3mediaserver/PMS.conf // "project.skelprofile.dir" project property private static final String SKEL_PROFILE_PATH; private static final String PROPERTY_PROFILE_PATH = "pms.profile.path"; private static final String SYSTEM_PROFILE_DIRECTORY; static { // first of all, set up the path to the default system profile directory if (Platform.isWindows()) { String programData = System.getenv("ALLUSERSPROFILE"); if (programData != null) { SYSTEM_PROFILE_DIRECTORY = String.format("%s\\%s", programData, PROFILE_DIRECTORY_NAME); } else { SYSTEM_PROFILE_DIRECTORY = ""; // i.e. current (working) directory } } else if (Platform.isMac()) { SYSTEM_PROFILE_DIRECTORY = String.format( "%s/%s/%s", System.getProperty("user.home"), "/Library/Application Support", PROFILE_DIRECTORY_NAME ); } else { String xdgConfigHome = System.getenv("XDG_CONFIG_HOME"); if (xdgConfigHome == null) { SYSTEM_PROFILE_DIRECTORY = String.format("%s/.config/%s", System.getProperty("user.home"), PROFILE_DIRECTORY_NAME); } else { SYSTEM_PROFILE_DIRECTORY = String.format("%s/%s", xdgConfigHome, PROFILE_DIRECTORY_NAME); } } // now set the profile path. first: check for a custom setting. // try the system property, typically set via the profile chooser String customProfilePath = System.getProperty(PROPERTY_PROFILE_PATH); // failing that, try the environment variable if (StringUtils.isBlank(customProfilePath)) { customProfilePath = System.getenv(ENV_PROFILE_PATH); } // if customProfilePath is still blank, the default profile dir/filename is used FileLocation profileLocation = FileUtil.getFileLocation( customProfilePath, SYSTEM_PROFILE_DIRECTORY, DEFAULT_PROFILE_FILENAME ); PROFILE_PATH = profileLocation.getFilePath(); PROFILE_DIRECTORY = profileLocation.getDirectoryPath(); // Set SKEL_PROFILE_PATH for Linux systems String skelDir = PropertiesUtil.getProjectProperties().get("project.skelprofile.dir"); if (Platform.isLinux() && StringUtils.isNotBlank(skelDir)) { SKEL_PROFILE_PATH = FilenameUtils.normalize( new File( new File( skelDir, PROFILE_DIRECTORY_NAME ).getAbsolutePath(), DEFAULT_PROFILE_FILENAME ).getAbsolutePath() ); } else { SKEL_PROFILE_PATH = null; } } /** * Default constructor that will attempt to load the PMS configuration file * from the profile path. * * @throws org.apache.commons.configuration.ConfigurationException */ public PmsConfiguration() throws ConfigurationException { this(true); } /** * Constructor that will initialize the PMS configuration. * * @param loadFile Set to true to attempt to load the PMS configuration * file from the profile path. Set to false to skip * loading. * @throws org.apache.commons.configuration.ConfigurationException */ public PmsConfiguration(boolean loadFile) throws ConfigurationException { configuration = new PropertiesConfiguration(); configurationReader = new ConfigurationReader(configuration, true); // true: log configuration.setListDelimiter((char) 0); if (loadFile) { File pmsConfFile = new File(PROFILE_PATH); if (pmsConfFile.isFile()) { if (FileUtil.isFileReadable(pmsConfFile)) { configuration.load(PROFILE_PATH); } else { logger.warn("Can't load {}", PROFILE_PATH); } } else if (SKEL_PROFILE_PATH != null) { File pmsSkelConfFile = new File(SKEL_PROFILE_PATH); if (pmsSkelConfFile.isFile()) { if (FileUtil.isFileReadable(pmsSkelConfFile)) { // Load defaults from skel file, save them later to PROFILE_PATH configuration.load(pmsSkelConfFile); logger.info("Default configuration loaded from " + SKEL_PROFILE_PATH); } else { logger.warn("Can't load {}", SKEL_PROFILE_PATH); } } } } configuration.setPath(PROFILE_PATH); tempFolder = new TempFolder(getString(KEY_TEMP_FOLDER_PATH, null)); programPaths = createProgramPathsChain(configuration); Locale.setDefault(new Locale(getLanguage())); // Set DEFAULT_AVI_SYNTH_SCRIPT according to language DEFAULT_AVI_SYNTH_SCRIPT = "<movie>\n<sub>\n"; long usableMemory = (Runtime.getRuntime().maxMemory() / 1048576) - BUFFER_MEMORY_FACTOR; if (usableMemory > MAX_MAX_MEMORY_DEFAULT_SIZE) { MAX_MAX_MEMORY_BUFFER_SIZE = (int) usableMemory; } } /** * Check if we have disabled something first, then check the config file, * then the Windows registry, then check for a platform-specific * default. */ private static ProgramPaths createProgramPathsChain(Configuration configuration) { return new ConfigurationProgramPaths( configuration, new WindowsRegistryProgramPaths( new PlatformSpecificDefaultPathsFactory().get() ) ); } /** * Return the <code>int</code> value for a given configuration key. First, the key * is looked up in the current configuration settings. If it exists and contains a * valid value, that value is returned. If the key contains an invalid value or * cannot be found, the specified default value is returned. * * @param key The key to look up. * @param def The default value to return when no valid key value can be found. * @return The value configured for the key. */ private int getInt(String key, int def) { return configurationReader.getInt(key, def); } /** * Return the <code>boolean</code> value for a given configuration key. First, the * key is looked up in the current configuration settings. If it exists and contains * a valid value, that value is returned. If the key contains an invalid value or * cannot be found, the specified default value is returned. * * @param key The key to look up. * @param def The default value to return when no valid key value can be found. * @return The value configured for the key. */ private boolean getBoolean(String key, boolean def) { return configurationReader.getBoolean(key, def); } /** * Return the <code>String</code> value for a given configuration key if the * value is non-blank (i.e. not null, not an empty string, not all whitespace). * Otherwise return the supplied default value. * The value is returned with leading and trailing whitespace removed in both cases. * * @param key The key to look up. * @param def The default value to return when no valid key value can be found. * @return The value configured for the key. */ private String getString(String key, String def) { return configurationReader.getNonBlankConfigurationString(key, def); } /** * Return a <code>List</code> of <code>String</code> values for a given configuration * key. First, the key is looked up in the current configuration settings. If it * exists and contains a valid value, that value is returned. If the key contains an * invalid value or cannot be found, a list with the specified default values is * returned. * * @param key The key to look up. * @param def The default values to return when no valid key value can be found. * These values should be entered as a comma-separated string. Whitespace * will be trimmed. For example: <code>"gnu, gnat ,moo "</code> will be * returned as <code>{ "gnu", "gnat", "moo" }</code>. * @return The list of value strings configured for the key. */ private List<String> getStringList(String key, String def) { return configurationReader.getStringList(key, def); } public File getTempFolder() throws IOException { return tempFolder.getTempFolder(); } public String getVlcPath() { return programPaths.getVlcPath(); } public String getMencoderPath() { return programPaths.getMencoderPath(); } public int getMencoderMaxThreads() { return Math.min(getInt(KEY_MENCODER_MAX_THREADS, getNumberOfCpuCores()), MENCODER_MAX_THREADS); } public String getDCRawPath() { return programPaths.getDCRaw(); } public String getFfmpegPath() { return programPaths.getFfmpegPath(); } public String getMplayerPath() { return programPaths.getMplayerPath(); } public String getTsmuxerPath() { return programPaths.getTsmuxerPath(); } public String getFlacPath() { return programPaths.getFlacPath(); } /** * If the framerate is not recognized correctly and the video runs too fast or too * slow, tsMuxeR can be forced to parse the fps from FFmpeg. Default value is true. * @return True if tsMuxeR should parse fps from FFmpeg. */ public boolean isTsmuxerForceFps() { return getBoolean(KEY_TSMUXER_FORCEFPS, true); } /** * The AC3 audio bitrate determines the quality of digital audio sound. An AV-receiver * or amplifier has to be capable of playing this quality. Default value is 640. * @return The AC3 audio bitrate. */ public int getAudioBitrate() { return getInt(KEY_AUDIO_BITRATE, 640); } /** * If the framerate is not recognized correctly and the video runs too fast or too * slow, tsMuxeR can be forced to parse the fps from FFmpeg. * @param value Set to true if tsMuxeR should parse fps from FFmpeg. */ public void setTsmuxerForceFps(boolean value) { configuration.setProperty(KEY_TSMUXER_FORCEFPS, value); } /** * The server port where PMS listens for TCP/IP traffic. Default value is 5001. * @return The port number. */ public int getServerPort() { return getInt(KEY_SERVER_PORT, DEFAULT_SERVER_PORT); } /** * Set the server port where PMS must listen for TCP/IP traffic. * @param value The TCP/IP port number. */ public void setServerPort(int value) { configuration.setProperty(KEY_SERVER_PORT, value); } /** * The hostname of the server. * @return The hostname if it is defined, otherwise <code>null</code>. */ public String getServerHostname() { return getString(KEY_SERVER_HOSTNAME, null); } /** * Set the hostname of the server. * @param value The hostname. */ public void setHostname(String value) { configuration.setProperty(KEY_SERVER_HOSTNAME, value); } /** * Get the code of the preferred language for the PMS user interface. Default * is based on the locale. * @return The ISO 639 language code. */ public String getLanguage() { String def = Locale.getDefault().getLanguage(); if (def == null) { def = "en"; } return getString(KEY_LANGUAGE, def); } /** * Returns the preferred minimum size for the transcoding memory buffer in megabytes. * Default value is 12. * @return The minimum memory buffer size. */ public int getMinMemoryBufferSize() { return getInt(KEY_MIN_MEMORY_BUFFER_SIZE, 12); } /** * Returns the preferred maximum size for the transcoding memory buffer in megabytes. * The value returned has a top limit of {@link #MAX_MAX_MEMORY_BUFFER_SIZE}. Default * value is 200. * * @return The maximum memory buffer size. */ public int getMaxMemoryBufferSize() { return Math.max(0, Math.min(MAX_MAX_MEMORY_BUFFER_SIZE, getInt(KEY_MAX_MEMORY_BUFFER_SIZE, 200))); } /** * Set the preferred maximum for the transcoding memory buffer in megabytes. The top * limit for the value is {@link #MAX_MAX_MEMORY_BUFFER_SIZE}. * * @param value The maximum buffer size. */ public void setMaxMemoryBufferSize(int value) { configuration.setProperty(KEY_MAX_MEMORY_BUFFER_SIZE, Math.max(0, Math.min(MAX_MAX_MEMORY_BUFFER_SIZE, value))); } /** * Returns the font scale used for ASS subtitling. Default value is 1.4. * @return The ASS font scale. */ public String getAssScale() { return getString(KEY_ASS_SCALE, "1.4"); } /** * Some versions of MEncoder produce garbled audio because the "ac3" codec is used * instead of the "ac3_fixed" codec. Returns true if "ac3_fixed" should be used. * Default is false. * See https://code.google.com/p/ps3mediaserver/issues/detail?id=1092#c1 * @return True if "ac3_fixed" should be used. */ public boolean isMencoderAc3Fixed() { return getBoolean(KEY_MENCODER_AC3_FIXED, false); } /** * Returns the margin used for ASS subtitling. Default value is 10. * @return The ASS margin. */ public String getAssMargin() { return getString(KEY_ASS_MARGIN, "10"); } /** * Returns the outline parameter used for ASS subtitling. Default value is 1. * @return The ASS outline parameter. */ public String getAssOutline() { return getString(KEY_ASS_OUTLINE, "1"); } /** * Returns the shadow parameter used for ASS subtitling. Default value is 1. * @return The ASS shadow parameter. */ public String getAssShadow() { return getString(KEY_ASS_SHADOW, "1"); } /** * Returns the subfont text scale parameter used for subtitling without ASS. * Default value is 3. * @return The subfont text scale parameter. */ public String getMencoderNoAssScale() { return getString(KEY_MENCODER_NOASS_SCALE, "3"); } /** * Returns the subpos parameter used for subtitling without ASS. * Default value is 2. * @return The subpos parameter. */ public String getMencoderNoAssSubPos() { return getString(KEY_MENCODER_NOASS_SUBPOS, "2"); } /** * Returns the subfont blur parameter used for subtitling without ASS. * Default value is 1. * @return The subfont blur parameter. */ public String getMencoderNoAssBlur() { return getString(KEY_MENCODER_NOASS_BLUR, "1"); } /** * Returns the subfont outline parameter used for subtitling without ASS. * Default value is 1. * @return The subfont outline parameter. */ public String getMencoderNoAssOutline() { return getString(KEY_MENCODER_NOASS_OUTLINE, "1"); } /** * Set the subfont outline parameter used for subtitling without ASS. * @param value The subfont outline parameter value to set. */ public void setMencoderNoAssOutline(String value) { configuration.setProperty(KEY_MENCODER_NOASS_OUTLINE, value); } /** * Some versions of MEncoder produce garbled audio because the "ac3" codec is used * instead of the "ac3_fixed" codec. * See https://code.google.com/p/ps3mediaserver/issues/detail?id=1092#c1 * @param value Set to true if "ac3_fixed" should be used. */ public void setMencoderAc3Fixed(boolean value) { configuration.setProperty(KEY_MENCODER_AC3_FIXED, value); } /** * Set the margin used for ASS subtitling. * @param value The ASS margin value to set. */ public void setAssMargin(String value) { configuration.setProperty(KEY_ASS_MARGIN, value); } /** * Set the outline parameter used for ASS subtitling. * @param value The ASS outline parameter value to set. */ public void setAssOutline(String value) { configuration.setProperty(KEY_ASS_OUTLINE, value); } /** * Set the shadow parameter used for ASS subtitling. * @param value The ASS shadow parameter value to set. */ public void setAssShadow(String value) { configuration.setProperty(KEY_ASS_SHADOW, value); } /** * Set the font scale used for ASS subtitling. * @param value The ASS font scale value to set. */ public void setAssScale(String value) { configuration.setProperty(KEY_ASS_SCALE, value); } /** * Set the subfont text scale parameter used for subtitling without ASS. * @param value The subfont text scale parameter value to set. */ public void setMencoderNoAssScale(String value) { configuration.setProperty(KEY_MENCODER_NOASS_SCALE, value); } /** * Set the subfont blur parameter used for subtitling without ASS. * @param value The subfont blur parameter value to set. */ public void setMencoderNoAssBlur(String value) { configuration.setProperty(KEY_MENCODER_NOASS_BLUR, value); } /** * Set the subpos parameter used for subtitling without ASS. * @param value The subpos parameter value to set. */ public void setMencoderNoAssSubPos(String value) { configuration.setProperty(KEY_MENCODER_NOASS_SUBPOS, value); } /** * Set the maximum number of concurrent MEncoder threads. * XXX Currently unused. * @param value The maximum number of concurrent threads. */ public void setMencoderMaxThreads(int value) { configuration.setProperty(KEY_MENCODER_MAX_THREADS, value); } /** * Set the preferred language for the PMS user interface. * @param value The ISO 639 language code. */ public void setLanguage(String value) { configuration.setProperty(KEY_LANGUAGE, value); Locale.setDefault(new Locale(getLanguage())); } /** * Returns the number of seconds from the start of a video file (the seek * position) where the thumbnail image for the movie should be extracted * from. Default is 2 seconds. * @return The seek position in seconds. */ public int getThumbnailSeekPos() { return getInt(KEY_THUMBNAIL_SEEK_POS, 2); } /** * Sets the number of seconds from the start of a video file (the seek * position) where the thumbnail image for the movie should be extracted * from. * @param value The seek position in seconds. */ public void setThumbnailSeekPos(int value) { configuration.setProperty(KEY_THUMBNAIL_SEEK_POS, value); } /** * Returns whether the user wants ASS/SSA subtitle support. Default is * true. * * @return True if MEncoder should use ASS/SSA support. */ public boolean isMencoderAss() { return getBoolean(KEY_MENCODER_ASS, true); } /** * Returns whether or not subtitles should be disabled for all * transcoding engines. Default is false, meaning subtitles should not * be disabled. * * @return True if subtitles should be disabled, false otherwise. */ public boolean isDisableSubtitles() { return getBoolean(KEY_DISABLE_SUBTITLES, false); } /** * Set whether or not subtitles should be disabled for * all transcoding engines. * * @param value Set to true if subtitles should be disabled. */ public void setDisableSubtitles(boolean value) { configuration.setProperty(KEY_DISABLE_SUBTITLES, value); } /** * Returns whether or not the Pulse Code Modulation audio format should be * forced. The default is false. * @return True if PCM should be forced, false otherwise. */ public boolean isAudioUsePCM() { return getBoolean(KEY_AUDIO_USE_PCM, false); } /** * Returns whether or not the Pulse Code Modulation audio format should be * used only for HQ audio codecs. The default is false. * @return True if PCM should be used only for HQ audio codecs, false otherwise. */ public boolean isMencoderUsePcmForHQAudioOnly() { return getBoolean(KEY_MENCODER_USE_PCM_FOR_HQ_AUDIO_ONLY, false); } /** * Returns the name of a TrueType font to use for subtitles. * Default is <code>""</code>. * @return The font name. */ public String getFont() { return getString(KEY_FONT, ""); } /** * Returns the audio language priority as a comma separated * string. For example: <code>"loc,eng,fre,jpn,ger,und"</code>, where "und" * stands for "undefined". * Can be a blank string. * Default value is "loc,eng,fre,jpn,ger,und". * * @return The audio language priority string. */ public String getAudioLanguages() { return configurationReader.getPossiblyBlankConfigurationString( KEY_AUDIO_LANGUAGES, Messages.getString("MEncoderVideo.126") ); } /** * Returns the subtitle language priority as a comma-separated * string. For example: <code>"loc,eng,fre,jpn,ger,und"</code>, where "und" * stands for "undefined". * Can be a blank string. * Default value is a localized list (e.g. "loc,eng,fre,jpn,ger,und"). * * @return The subtitle language priority string. */ public String getSubtitlesLanguages() { return configurationReader.getPossiblyBlankConfigurationString( KEY_SUBTITLE_LANGUAGES, Messages.getString("MEncoderVideo.127") ); } /** * Returns the ISO 639 language code for the subtitle language that should * be forced. * Can be a blank string. * @return The subtitle language code. */ public String getForcedSubtitleLanguage() { return configurationReader.getPossiblyBlankConfigurationString( KEY_FORCED_SUBTITLE_LANGUAGE, getLanguage() ); } /** * Returns the tag string that identifies the subtitle language that * should be forced. * @return The tag string. */ public String getForcedSubtitleTags() { return getString(KEY_FORCED_SUBTITLE_TAGS, "forced"); } /** * Returns a string of audio language and subtitle language pairs * ordered by priority to try to match. Audio language * and subtitle language should be comma separated as a pair, * individual pairs should be semicolon separated. "*" can be used to * match any language. Subtitle language can be defined as "off". * Default value is <code>"*,*"</code>. * * @return The audio and subtitle languages priority string. */ public String getAudioSubLanguages() { return configurationReader.getPossiblyBlankConfigurationString( KEY_AUDIO_SUB_LANGS, Messages.getString("MEncoderVideo.128") ); } /** * Returns whether or not MEncoder should use FriBiDi mode, which * is needed to display subtitles in languages that read from right to * left, like Arabic, Farsi, Hebrew, Urdu, etc. Default value is false. * @return True if FriBiDi mode should be used, false otherwise. */ public boolean isMencoderSubFribidi() { return getBoolean(KEY_MENCODER_SUB_FRIBIDI, false); } /** * Returns the character encoding (or code page) that should used * for displaying non-Unicode external subtitles. Default is empty string * (do not force encoding with -subcp key). * @return The character encoding. */ public String getSubtitlesCodepage() { return getString(KEY_SUBTITLE_CODEPAGE, ""); } /** * Returns whether or not MEncoder should use fontconfig for displaying * subtitles. Default is false. * @return True if fontconfig should be used, false otherwise. */ public boolean isMencoderFontConfig() { return getBoolean(KEY_MENCODER_FONT_CONFIG, true); } /** * Set to true if MEncoder should be forced to use the framerate that is * parsed by FFmpeg. * @param value Set to true if the framerate should be forced, false * otherwise. */ public void setMencoderForceFps(boolean value) { configuration.setProperty(KEY_MENCODER_FORCE_FPS, value); } /** * Returns true if MEncoder should be forced to use the framerate that is * parsed by FFmpeg. * @return True if the framerate should be forced, false otherwise. */ public boolean isMencoderForceFps() { return getBoolean(KEY_MENCODER_FORCE_FPS, false); } /** * Sets the audio language priority as a comma separated * string. For example: <code>"eng,fre,jpn,ger,und"</code>, where "und" * stands for "undefined". * @param value The audio language priority string. */ public void setAudioLanguages(String value) { configuration.setProperty(KEY_AUDIO_LANGUAGES, value); } /** * Sets the subtitle language priority as a comma * separated string. For example: <code>"eng,fre,jpn,ger,und"</code>, * where "und" stands for "undefined". * @param value The subtitle language priority string. */ public void setSubtitlesLanguages(String value) { configuration.setProperty(KEY_SUBTITLE_LANGUAGES, value); } /** * Sets the ISO 639 language code for the subtitle language that should * be forced. * @param value The subtitle language code. */ public void setForcedSubtitleLanguage(String value) { configuration.setProperty(KEY_FORCED_SUBTITLE_LANGUAGE, value); } /** * Sets the tag string that identifies the subtitle language that * should be forced. * @param value The tag string. */ public void setForcedSubtitleTags(String value) { configuration.setProperty(KEY_FORCED_SUBTITLE_TAGS, value); } /** * Sets a string of audio language and subtitle language pairs * ordered by priority to try to match. Audio language * and subtitle language should be comma separated as a pair, * individual pairs should be semicolon separated. "*" can be used to * match any language. Subtitle language can be defined as "off". For * example: <code>"en,off;jpn,eng;*,eng;*;*"</code>. * @param value The audio and subtitle languages priority string. */ public void setAudioSubLanguages(String value) { configuration.setProperty(KEY_AUDIO_SUB_LANGS, value); } /** * Returns custom commandline options to pass on to MEncoder. * @return The custom options string. */ public String getMencoderCustomOptions() { return getString(KEY_MENCODER_CUSTOM_OPTIONS, ""); } /** * Sets custom commandline options to pass on to MEncoder. * @param value The custom options string. */ public void setMencoderCustomOptions(String value) { configuration.setProperty(KEY_MENCODER_CUSTOM_OPTIONS, value); } /** * Sets the character encoding (or code page) that should be used * for displaying non-Unicode external subtitles. Default is empty (autodetect). * @param value The character encoding. */ public void setSubtitlesCodepage(String value) { configuration.setProperty(KEY_SUBTITLE_CODEPAGE, value); } /** * Sets whether or not MEncoder should use FriBiDi mode, which * is needed to display subtitles in languages that read from right to * left, like Arabic, Farsi, Hebrew, Urdu, etc. Default value is false. * @param value Set to true if FriBiDi mode should be used. */ public void setMencoderSubFribidi(boolean value) { configuration.setProperty(KEY_MENCODER_SUB_FRIBIDI, value); } /** * Sets the name of a TrueType font to use for subtitles. * @param value The font name. */ public void setFont(String value) { configuration.setProperty(KEY_FONT, value); } /** * Older versions of MEncoder do not support ASS/SSA subtitles on all * platforms. Set to true if MEncoder supports them. Default should be * true on Windows and OS X, false otherwise. * See https://code.google.com/p/ps3mediaserver/issues/detail?id=1097 * @param value Set to true if MEncoder supports ASS/SSA subtitles. */ public void setMencoderAss(boolean value) { configuration.setProperty(KEY_MENCODER_ASS, value); } /** * Sets whether or not MEncoder should use fontconfig for displaying * subtitles. * @param value Set to true if fontconfig should be used. */ public void setMencoderFontConfig(boolean value) { configuration.setProperty(KEY_MENCODER_FONT_CONFIG, value); } /** * Sets whether or not the Pulse Code Modulation audio format should be * forced. * @param value Set to true if PCM should be forced. */ public void setAudioUsePCM(boolean value) { configuration.setProperty(KEY_AUDIO_USE_PCM, value); } /** * Sets whether or not the Pulse Code Modulation audio format should be * used only for HQ audio codecs. * @param value Set to true if PCM should be used only for HQ audio. */ public void setMencoderUsePcmForHQAudioOnly(boolean value) { configuration.setProperty(KEY_MENCODER_USE_PCM_FOR_HQ_AUDIO_ONLY, value); } /** * Returns true if archives (e.g. .zip or .rar) should be browsable by * PMS, false otherwise. * @return True if archives should be browsable. */ public boolean isArchiveBrowsing() { return getBoolean(KEY_OPEN_ARCHIVES, false); } /** * Set to true if archives (e.g. .zip or .rar) should be browsable by * PMS, false otherwise. * @param value Set to true if archives should be browsable. */ public void setArchiveBrowsing(boolean value) { configuration.setProperty(KEY_OPEN_ARCHIVES, value); } /** * Returns true if MEncoder should use the deinterlace filter, false * otherwise. * @return True if the deinterlace filter should be used. */ public boolean isMencoderYadif() { return getBoolean(KEY_MENCODER_YADIF, false); } /** * Set to true if MEncoder should use the deinterlace filter, false * otherwise. * @param value Set ot true if the deinterlace filter should be used. */ public void setMencoderYadif(boolean value) { configuration.setProperty(KEY_MENCODER_YADIF, value); } /** * Returns true if MEncoder should be used to upscale the video to an * optimal resolution. Default value is false, meaning the renderer will * upscale the video itself. * * @return True if MEncoder should be used, false otherwise. * @see #getMencoderScaleX() * @see #getMencoderScaleY() */ public boolean isMencoderScaler() { return getBoolean(KEY_MENCODER_SCALER, false); } /** * Set to true if MEncoder should be used to upscale the video to an * optimal resolution. Set to false to leave upscaling to the renderer. * * @param value Set to true if MEncoder should be used to upscale. * @see #setMencoderScaleX(int) * @see #setMencoderScaleY(int) */ public void setMencoderScaler(boolean value) { configuration.setProperty(KEY_MENCODER_SCALER, value); } /** * Returns the width in pixels to which a video should be scaled when * {@link #isMencoderScaler()} returns true. * * @return The width in pixels. */ public int getMencoderScaleX() { return getInt(KEY_MENCODER_SCALEX, 0); } /** * Sets the width in pixels to which a video should be scaled when * {@link #isMencoderScaler()} returns true. * * @param value The width in pixels. */ public void setMencoderScaleX(int value) { configuration.setProperty(KEY_MENCODER_SCALEX, value); } /** * Returns the height in pixels to which a video should be scaled when * {@link #isMencoderScaler()} returns true. * * @return The height in pixels. */ public int getMencoderScaleY() { return getInt(KEY_MENCODER_SCALEY, 0); } /** * Sets the height in pixels to which a video should be scaled when * {@link #isMencoderScaler()} returns true. * * @param value The height in pixels. */ public void setMencoderScaleY(int value) { configuration.setProperty(KEY_MENCODER_SCALEY, value); } /** * Returns the number of audio channels that should be used for * transcoding. Default value is 6 (for 5.1 audio). * * @return The number of audio channels. */ public int getAudioChannelCount() { return getInt(KEY_AUDIO_CHANNEL_COUNT, 6); } /** * Sets the number of audio channels that MEncoder should use for * transcoding. * * @param value The number of audio channels. */ public void setAudioChannelCount(int value) { configuration.setProperty(KEY_AUDIO_CHANNEL_COUNT, value); } /** * Sets the AC3 audio bitrate, which determines the quality of digital * audio sound. An AV-receiver or amplifier has to be capable of playing * this quality. * * @param value The AC3 audio bitrate. */ public void setAudioBitrate(int value) { configuration.setProperty(KEY_AUDIO_BITRATE, value); } /** * Returns the maximum video bitrate to be used by MEncoder and FFmpeg. * * @return The maximum video bitrate. */ public String getMaximumBitrate() { String maximumBitrate = getString(KEY_MAX_BITRATE, "110"); if ("0".equals(maximumBitrate)) { maximumBitrate = "1000"; } return maximumBitrate; } /** * Sets the maximum video bitrate to be used by MEncoder. * * @param value The maximum video bitrate. */ public void setMaximumBitrate(String value) { configuration.setProperty(KEY_MAX_BITRATE, value); } /** * Returns true if thumbnail generation is enabled, false otherwise. * * @return boolean indicating whether thumbnail generation is enabled. */ public boolean isThumbnailGenerationEnabled() { return getBoolean(KEY_THUMBNAIL_GENERATION_ENABLED, true); } /** * Sets the thumbnail generation option. */ public void setThumbnailGenerationEnabled(boolean value) { configuration.setProperty(KEY_THUMBNAIL_GENERATION_ENABLED, value); } /** * Returns true if PMS should generate thumbnails for images. Default value * is true. * * @return True if image thumbnails should be generated. */ public boolean getImageThumbnailsEnabled() { return getBoolean(KEY_IMAGE_THUMBNAILS_ENABLED, true); } /** * Set to true if PMS should generate thumbnails for images. * * @param value True if image thumbnails should be generated. */ public void setImageThumbnailsEnabled(boolean value) { configuration.setProperty(KEY_IMAGE_THUMBNAILS_ENABLED, value); } /** * Returns the number of CPU cores that should be used for transcoding. * * @return The number of CPU cores. */ public int getNumberOfCpuCores() { int nbcores = Runtime.getRuntime().availableProcessors(); if (nbcores < 1) { nbcores = 1; } return getInt(KEY_NUMBER_OF_CPU_CORES, nbcores); } /** * Sets the number of CPU cores that should be used for transcoding. The * maximum value depends on the physical available count of "real processor * cores". That means hyperthreading virtual CPU cores do not count! If you * are not sure, analyze your CPU with the free tool CPU-z on Windows * systems. On Linux have a look at the virtual proc-filesystem: in the * file "/proc/cpuinfo" you will find more details about your CPU. You also * get much information about CPUs from AMD and Intel from their Wikipedia * articles. * <p> * PMS will detect and set the correct amount of cores as the default value. * * @param value The number of CPU cores. */ public void setNumberOfCpuCores(int value) { configuration.setProperty(KEY_NUMBER_OF_CPU_CORES, value); } /** * Returns true if PMS should start minimized, i.e. without its window * opened. Default value false: to start with a window. * * @return True if PMS should start minimized, false otherwise. */ public boolean isMinimized() { return getBoolean(KEY_MINIMIZED, false); } /** * Set to true if PMS should start minimized, i.e. without its window * opened. * * @param value True if PMS should start minimized, false otherwise. */ public void setMinimized(boolean value) { configuration.setProperty(KEY_MINIMIZED, value); } /** * Returns true when PMS should check for external subtitle files with the * same name as the media (*.srt, *.sub, *.ass, etc.). The default value is * true. * * @return True if PMS should check for external subtitle files, false if * they should be ignored. */ public boolean isAutoloadExternalSubtitles() { return getBoolean(KEY_AUTOLOAD_SUBTITLES, true); } /** * Set to true if PMS should check for external subtitle files with the * same name as the media (*.srt, *.sub, *.ass etc.). * * @param value True if PMS should check for external subtitle files. */ public void setAutoloadExternalSubtitles(boolean value) { configuration.setProperty(KEY_AUTOLOAD_SUBTITLES, value); } /** * Returns true if PMS should hide the "# Videosettings #" folder on the * DLNA device. The default value is false: PMS will display the folder. * * @return True if PMS should hide the folder, false othewise. */ public boolean getHideVideoSettings() { return getBoolean(KEY_HIDE_VIDEO_SETTINGS, true); } /** * Set to true if PMS should hide the "# Videosettings #" folder on the * DLNA device, or set to false to make PMS display the folder. * * @param value True if PMS should hide the folder. */ public void setHideVideoSettings(boolean value) { configuration.setProperty(KEY_HIDE_VIDEO_SETTINGS, value); } /** * Returns true if PMS should cache scanned media in its internal database, * speeding up later retrieval. When false is returned, PMS will not use * cache and media will have to be rescanned. * * @return True if PMS should cache media. */ public boolean getUseCache() { return getBoolean(KEY_USE_CACHE, false); } /** * Set to true if PMS should cache scanned media in its internal database, * speeding up later retrieval. * * @param value True if PMS should cache media. */ public void setUseCache(boolean value) { configuration.setProperty(KEY_USE_CACHE, value); } /** * Set to true if PMS should pass the flag "convertfps=true" to AviSynth. * * @param value True if PMS should pass the flag. */ public void setAvisynthConvertFps(boolean value) { configuration.setProperty(KEY_AVISYNTH_CONVERT_FPS, value); } /** * Returns true if PMS should pass the flag "convertfps=true" to AviSynth. * * @return True if PMS should pass the flag. */ public boolean getAvisynthConvertFps() { return getBoolean(KEY_AVISYNTH_CONVERT_FPS, false); } /** * Returns the template for the AviSynth script. The script string can * contain the character "\u0001", which should be treated as the newline * separator character. * * @return The AviSynth script template. */ public String getAvisynthScript() { return getString(KEY_AVISYNTH_SCRIPT, DEFAULT_AVI_SYNTH_SCRIPT); } /** * Sets the template for the AviSynth script. The script string may contain * the character "\u0001", which will be treated as newline character. * * @param value The AviSynth script template. */ public void setAvisynthScript(String value) { configuration.setProperty(KEY_AVISYNTH_SCRIPT, value); } /** * Returns additional codec specific configuration options for MEncoder. * * @return The configuration options. */ public String getMencoderCodecSpecificConfig() { return getString(KEY_MENCODER_CODEC_SPECIFIC_SCRIPT, ""); } /** * Sets additional codec specific configuration options for MEncoder. * * @param value The additional configuration options. */ public void setMencoderCodecSpecificConfig(String value) { configuration.setProperty(KEY_MENCODER_CODEC_SPECIFIC_SCRIPT, value); } /** * Returns the maximum size (in MB) that PMS should use for buffering * audio. * * @return The maximum buffer size. */ public int getMaxAudioBuffer() { return getInt(KEY_MAX_AUDIO_BUFFER, 100); } /** * Returns the minimum size (in MB) that PMS should use for the buffer used * for streaming media. * * @return The minimum buffer size. */ public int getMinStreamBuffer() { return getInt(KEY_MIN_STREAM_BUFFER, 1); } /** * Converts the getMPEG2MainSettings() from MEncoder's format to FFmpeg's. * * @return MPEG-2 settings formatted for FFmpeg. */ public String getMPEG2MainSettingsFFmpeg() { String mpegSettings = getMPEG2MainSettings(); if (mpegSettings.contains("Automatic")) { return mpegSettings; } String mpegSettingsArray[] = mpegSettings.split(":"); String pairArray[]; String returnString = ""; for (String pair : mpegSettingsArray) { pairArray = pair.split("="); if ("keyint".equals(pairArray[0])) { returnString += "-g " + pairArray[1] + " "; } else if ("vqscale".equals(pairArray[0])) { returnString += "-q:v " + pairArray[1] + " "; } else if ("vqmin".equals(pairArray[0])) { returnString += "-qmin " + pairArray[1] + " "; } else if ("vqmax".equals(pairArray[0])) { returnString += "-qmax " + pairArray[1] + " "; } } return returnString; } public void setFfmpegMultithreading(boolean value) { configuration.setProperty(KEY_FFMPEG_MULTITHREADING, value); } public boolean isFfmpegMultithreading() { boolean isMultiCore = getNumberOfCpuCores() > 1; return getBoolean(KEY_FFMPEG_MULTITHREADING, isMultiCore); } public boolean isMencoderNoOutOfSync() { return getBoolean(KEY_MENCODER_NO_OUT_OF_SYNC, true); } public void setMencoderNoOutOfSync(boolean value) { configuration.setProperty(KEY_MENCODER_NO_OUT_OF_SYNC, value); } public boolean getTrancodeBlocksMultipleConnections() { return getBoolean(KEY_TRANSCODE_BLOCKS_MULTIPLE_CONNECTIONS, false); } public void setTranscodeBlocksMultipleConnections(boolean value) { configuration.setProperty(KEY_TRANSCODE_BLOCKS_MULTIPLE_CONNECTIONS, value); } public boolean getTrancodeKeepFirstConnections() { return getBoolean(KEY_TRANSCODE_KEEP_FIRST_CONNECTION, true); } public void setTrancodeKeepFirstConnections(boolean value) { configuration.setProperty(KEY_TRANSCODE_KEEP_FIRST_CONNECTION, value); } public boolean isMencoderIntelligentSync() { return getBoolean(KEY_MENCODER_INTELLIGENT_SYNC, true); } public void setMencoderIntelligentSync(boolean value) { configuration.setProperty(KEY_MENCODER_INTELLIGENT_SYNC, value); } @Deprecated public String getFfmpegAlternativePath() { return getString(KEY_FFMPEG_ALTERNATIVE_PATH, null); } @Deprecated public void setFfmpegAlternativePath(String value) { configuration.setProperty(KEY_FFMPEG_ALTERNATIVE_PATH, value); } public boolean getSkipLoopFilterEnabled() { return getBoolean(KEY_SKIP_LOOP_FILTER_ENABLED, false); } /** * The list of network interfaces that should be skipped when checking * for an available network interface. Entries should be comma separated * and typically exclude the number at the end of the interface name. * <p> * Default is to skip the interfaces created by Virtualbox, OpenVPN and * Parallels: "tap,vmnet,vnic,virtualbox". * @return The string of network interface names to skip. */ public List<String> getSkipNetworkInterfaces() { return getStringList(KEY_SKIP_NETWORK_INTERFACES, "tap,vmnet,vnic,virtualbox"); } public void setSkipLoopFilterEnabled(boolean value) { configuration.setProperty(KEY_SKIP_LOOP_FILTER_ENABLED, value); } public String getMPEG2MainSettings() { return getString(KEY_MPEG2_MAIN_SETTINGS, "Automatic (Wired)"); } public void setMPEG2MainSettings(String value) { configuration.setProperty(KEY_MPEG2_MAIN_SETTINGS, value); } public String getMencoderVobsubSubtitleQuality() { return getString(KEY_MENCODER_VOBSUB_SUBTITLE_QUALITY, "3"); } public void setMencoderVobsubSubtitleQuality(String value) { configuration.setProperty(KEY_MENCODER_VOBSUB_SUBTITLE_QUALITY, value); } public String getMencoderOverscanCompensationWidth() { return getString(KEY_MENCODER_OVERSCAN_COMPENSATION_WIDTH, "0"); } public void setMencoderOverscanCompensationWidth(String value) { if (value.trim().length() == 0) { value = "0"; } configuration.setProperty(KEY_MENCODER_OVERSCAN_COMPENSATION_WIDTH, value); } public String getMencoderOverscanCompensationHeight() { return getString(KEY_MENCODER_OVERSCAN_COMPENSATION_HEIGHT, "0"); } public void setMencoderOverscanCompensationHeight(String value) { if (value.trim().length() == 0) { value = "0"; } configuration.setProperty(KEY_MENCODER_OVERSCAN_COMPENSATION_HEIGHT, value); } public void setEnginesAsList(ArrayList<String> enginesAsList) { configuration.setProperty(KEY_ENGINES, listToString(enginesAsList)); } /** * @deprecated Use {@link #getEnginesAsList()} instead. */ @Deprecated public List<String> getEnginesAsList(SystemUtils registry) { return getEnginesAsList(); } // TODO this should use Player.id() instead of hardwiring the identifiers // TODO rather than loading the players here, this should delegate // to (or solely be implemented in) PlayerFactory public List<String> getEnginesAsList() { final String defaultEngines = join( asList( "mencoder", "avsmencoder", "tsmuxer", "ffmpegvideo", "vlctranscoder", // (VLCVideo) TODO: rename "vlcvideo" "ffmpegaudio", "tsmuxeraudio", "ffmpegwebvideo", "vlcwebvideo", // (VLCWebVideo) "vlcvideo", // (VideoLanVideoStreaming) TODO (legacy web video engine): remove "mencoderwebvideo", "ffmpegwebaudio", "vlcaudio", // (VideoLanAudioStreaming) TODO (legacy web audio engine): remove "ffmpegdvrmsremux", "rawthumbs" ), LIST_SEPARATOR ); return stringToList( // possibly blank: an empty string means: disable all engines // http://www.ps3mediaserver.org/forum/viewtopic.php?f=6&t=15416 configurationReader.getPossiblyBlankConfigurationString( KEY_ENGINES, defaultEngines ) ); } private static String listToString(List<String> enginesAsList) { return join(enginesAsList, LIST_SEPARATOR); } private static List<String> stringToList(String input) { return new ArrayList<String>(asList(split(input, LIST_SEPARATOR))); } public void save() throws ConfigurationException { configuration.save(); logger.info("Configuration saved to: " + PROFILE_PATH); } public String getFolders() { return getString(KEY_FOLDERS, ""); } public void setFolders(String value) { configuration.setProperty(KEY_FOLDERS, value); } public String getNetworkInterface() { return getString(KEY_NETWORK_INTERFACE, ""); } public void setNetworkInterface(String value) { configuration.setProperty(KEY_NETWORK_INTERFACE, value); } public boolean isHideEngineNames() { return getBoolean(KEY_HIDE_ENGINENAMES, false); } public void setHideEngineNames(boolean value) { configuration.setProperty(KEY_HIDE_ENGINENAMES, value); } public boolean isHideExtensions() { return getBoolean(KEY_HIDE_EXTENSIONS, false); } public void setHideExtensions(boolean value) { configuration.setProperty(KEY_HIDE_EXTENSIONS, value); } public String getShares() { return getString(KEY_SHARES, ""); } public void setShares(String value) { configuration.setProperty(KEY_SHARES, value); } public String getDisableTranscodeForExtensions() { return getString(KEY_DISABLE_TRANSCODE_FOR_EXTENSIONS, ""); } public void setDisableTranscodeForExtensions(String value) { configuration.setProperty(KEY_DISABLE_TRANSCODE_FOR_EXTENSIONS, value); } public String getForceTranscodeForExtensions() { return getString(KEY_FORCE_TRANSCODE_FOR_EXTENSIONS, ""); } public void setForceTranscodeForEtensions(String value) { configuration.setProperty(KEY_FORCE_TRANSCODE_FOR_EXTENSIONS, value); } public void setMencoderMT(boolean value) { configuration.setProperty(KEY_MENCODER_MT, value); } public boolean getMencoderMT() { boolean isMultiCore = getNumberOfCpuCores() > 1; return getBoolean(KEY_MENCODER_MT, isMultiCore); } public void setAudioRemuxAC3(boolean value) { configuration.setProperty(KEY_AUDIO_REMUX_AC3, value); } public boolean isAudioRemuxAC3() { return getBoolean(KEY_AUDIO_REMUX_AC3, true); } public void setMencoderRemuxMPEG2(boolean value) { configuration.setProperty(KEY_MENCODER_REMUX_MPEG2, value); } public boolean isMencoderRemuxMPEG2() { return getBoolean(KEY_MENCODER_REMUX_MPEG2, true); } public void setDisableFakeSize(boolean value) { configuration.setProperty(KEY_DISABLE_FAKESIZE, value); } public boolean isDisableFakeSize() { return getBoolean(KEY_DISABLE_FAKESIZE, false); } public void setMencoderAssDefaultStyle(boolean value) { configuration.setProperty(KEY_MENCODER_ASS_DEFAULTSTYLE, value); } public boolean isMencoderAssDefaultStyle() { return getBoolean(KEY_MENCODER_ASS_DEFAULTSTYLE, true); } public int getMEncoderOverscan() { return getInt(KEY_OVERSCAN, 0); } public void setMEncoderOverscan(int value) { configuration.setProperty(KEY_OVERSCAN, value); } /** * Returns sort method to use for ordering lists of files. One of the * following values is returned: * <ul> * <li>0: Locale-sensitive A-Z</li> * <li>1: Sort by modified date, newest first</li> * <li>2: Sort by modified date, oldest first</li> * <li>3: Case-insensitive ASCIIbetical sort</li> * <li>4: Locale-sensitive natural sort</li> * <li>5: Random</li> * </ul> * Default value is 4: locale-sensitive natural sort. * @return The sort method */ public int getSortMethod() { return getInt(KEY_SORT_METHOD, 4); } /** * Set the sort method to use for ordering lists of files. The following * values are recognized: * <ul> * <li>0: Locale-sensitive A-Z</li> * <li>1: Sort by modified date, newest first</li> * <li>2: Sort by modified date, oldest first</li> * <li>3: Case-insensitive ASCIIbetical sort</li> * <li>4: Locale-sensitive natural sort</li> * <li>5: Random</li> * </ul> * @param value The sort method to use */ public void setSortMethod(int value) { configuration.setProperty(KEY_SORT_METHOD, value); } public int getAudioThumbnailMethod() { return getInt(KEY_AUDIO_THUMBNAIL_METHOD, 0); } public void setAudioThumbnailMethod(int value) { configuration.setProperty(KEY_AUDIO_THUMBNAIL_METHOD, value); } public String getAlternateThumbFolder() { return getString(KEY_ALTERNATE_THUMB_FOLDER, ""); } public void setAlternateThumbFolder(String value) { configuration.setProperty(KEY_ALTERNATE_THUMB_FOLDER, value); } public String getAlternateSubtitlesFolder() { return getString(KEY_ALTERNATE_SUBTITLE_FOLDER, ""); } public void setAlternateSubtitlesFolder(String value) { configuration.setProperty(KEY_ALTERNATE_SUBTITLE_FOLDER, value); } public void setAudioEmbedDtsInPcm(boolean value) { configuration.setProperty(KEY_AUDIO_EMBED_DTS_IN_PCM, value); } public boolean isAudioEmbedDtsInPcm() { return getBoolean(KEY_AUDIO_EMBED_DTS_IN_PCM, false); } public void setFFmpegMuxWhenCompatible(boolean value) { configuration.setProperty(KEY_FFMPEG_MUX_COMPATIBLE, value); } public boolean isFFmpegMuxWhenCompatible() { return getBoolean(KEY_FFMPEG_MUX_COMPATIBLE, true); } public void setMuxAllAudioTracks(boolean value) { configuration.setProperty(KEY_MUX_ALLAUDIOTRACKS, value); } public boolean isMuxAllAudioTracks() { return getBoolean(KEY_MUX_ALLAUDIOTRACKS, false); } public void setUseMplayerForVideoThumbs(boolean value) { configuration.setProperty(KEY_USE_MPLAYER_FOR_THUMBS, value); } public boolean isUseMplayerForVideoThumbs() { return getBoolean(KEY_USE_MPLAYER_FOR_THUMBS, false); } public String getIpFilter() { return getString(KEY_IP_FILTER, ""); } public synchronized IpFilter getIpFiltering() { filter.setRawFilter(getIpFilter()); return filter; } public void setIpFilter(String value) { configuration.setProperty(KEY_IP_FILTER, value); } public void setPreventsSleep(boolean value) { configuration.setProperty(KEY_PREVENTS_SLEEP, value); } public boolean isPreventsSleep() { return getBoolean(KEY_PREVENTS_SLEEP, false); } public void setHTTPEngineV2(boolean value) { configuration.setProperty(KEY_HTTP_ENGINE_V2, value); } public boolean isHTTPEngineV2() { return getBoolean(KEY_HTTP_ENGINE_V2, true); } public boolean isShowIphotoLibrary() { return getBoolean(KEY_SHOW_IPHOTO_LIBRARY, false); } public void setShowIphotoLibrary(boolean value) { configuration.setProperty(KEY_SHOW_IPHOTO_LIBRARY, value); } public boolean isShowApertureLibrary() { return getBoolean(KEY_SHOW_APERTURE_LIBRARY, false); } public void setShowApertureLibrary(boolean value) { configuration.setProperty(KEY_SHOW_APERTURE_LIBRARY, value); } public boolean isShowItunesLibrary() { return getBoolean(KEY_SHOW_ITUNES_LIBRARY, false); } public void setShowItunesLibrary(boolean value) { configuration.setProperty(KEY_SHOW_ITUNES_LIBRARY, value); } public boolean isHideEmptyFolders() { return getBoolean(PmsConfiguration.KEY_HIDE_EMPTY_FOLDERS, false); } public void setHideEmptyFolders(final boolean value) { this.configuration.setProperty(PmsConfiguration.KEY_HIDE_EMPTY_FOLDERS, value); } public boolean isHideMediaLibraryFolder() { return getBoolean(PmsConfiguration.KEY_HIDE_MEDIA_LIBRARY_FOLDER, false); } public void setHideMediaLibraryFolder(final boolean value) { this.configuration.setProperty(PmsConfiguration.KEY_HIDE_MEDIA_LIBRARY_FOLDER, value); } // TODO (breaking change): rename to e.g. isTranscodeFolderEnabled // (and return true by default) public boolean getHideTranscodeEnabled() { return getBoolean(KEY_HIDE_TRANSCODE_FOLDER, false); } // TODO (breaking change): rename to e.g. setTranscodeFolderEnabled // (and negate the value in the caller) public void setHideTranscodeEnabled(boolean value) { configuration.setProperty(KEY_HIDE_TRANSCODE_FOLDER, value); } public boolean isDvdIsoThumbnails() { return getBoolean(KEY_DVD_ISO_THUMBNAILS, false); } public void setDvdIsoThumbnails(boolean value) { configuration.setProperty(KEY_DVD_ISO_THUMBNAILS, value); } public Object getCustomProperty(String property) { return configurationReader.getCustomProperty(property); } public void setCustomProperty(String property, Object value) { configuration.setProperty(property, value); } public boolean isChapterSupport() { return getBoolean(KEY_CHAPTER_SUPPORT, false); } public void setChapterSupport(boolean value) { configuration.setProperty(KEY_CHAPTER_SUPPORT, value); } public int getChapterInterval() { return getInt(KEY_CHAPTER_INTERVAL, 5); } public void setChapterInterval(int value) { configuration.setProperty(KEY_CHAPTER_INTERVAL, value); } public int getSubsColor() { return getInt(KEY_SUBS_COLOR, 0xffffffff); } public void setSubsColor(int value) { configuration.setProperty(KEY_SUBS_COLOR, value); } public boolean isFix25FPSAvMismatch() { return getBoolean(KEY_FIX_25FPS_AV_MISMATCH, false); } public void setFix25FPSAvMismatch(boolean value) { configuration.setProperty(KEY_FIX_25FPS_AV_MISMATCH, value); } public int getVideoTranscodeStartDelay() { return getInt(KEY_VIDEOTRANSCODE_START_DELAY, 6); } public void setVideoTranscodeStartDelay(int value) { configuration.setProperty(KEY_VIDEOTRANSCODE_START_DELAY, value); } public boolean isAudioResample() { return getBoolean(KEY_AUDIO_RESAMPLE, true); } public void setAudioResample(boolean value) { configuration.setProperty(KEY_AUDIO_RESAMPLE, value); } /** * Returns the name of the renderer to fall back on when header matching * fails. PMS will recognize the configured renderer instead of "Unknown * renderer". Default value is "", which means PMS will return the unknown * renderer when no match can be made. * * @return The name of the renderer PMS should fall back on when header * matching fails. * @see #isRendererForceDefault() */ public String getRendererDefault() { return getString(KEY_RENDERER_DEFAULT, ""); } /** * Sets the name of the renderer to fall back on when header matching * fails. PMS will recognize the configured renderer instead of "Unknown * renderer". Set to "" to make PMS return the unknown renderer when no * match can be made. * * @param value The name of the renderer to fall back on. This has to be * <code>""</code> or a case insensitive match with the name * used in any render configuration file. * @see #setRendererForceDefault(boolean) */ public void setRendererDefault(String value) { configuration.setProperty(KEY_RENDERER_DEFAULT, value); } /** * Returns true when PMS should not try to guess connecting renderers * and instead force picking the defined fallback renderer. Default * value is false, which means PMS will attempt to recognize connecting * renderers by their headers. * * @return True when the fallback renderer should always be picked. * @see #getRendererDefault() */ public boolean isRendererForceDefault() { return getBoolean(KEY_RENDERER_FORCE_DEFAULT, false); } /** * Set to true when PMS should not try to guess connecting renderers * and instead force picking the defined fallback renderer. Set to false * to make PMS attempt to recognize connecting renderers by their headers. * * @param value True when the fallback renderer should always be picked. * @see #setRendererDefault(String) */ public void setRendererForceDefault(boolean value) { configuration.setProperty(KEY_RENDERER_FORCE_DEFAULT, value); } /** * Returns a string containing a list of IP addresses and the renderer * profiles that should be forced to match them. Can be empty if no profile * should be forced on any IP address. * * @return The string containing the list. * @see #setRendererForceIp(String) */ public String getRendererForceIp() { return getString(KEY_RENDERER_FORCE_IP, ""); } /** * Set the string that contains a list of IP adresses and the renderer * profiles that should be forced to match for them. The comma separated * list contains pairs of a renderer name followed by "@" and an IP * address. The renderer name should match the value of the RendererName * property in a .conf file. The IP address can be specified as a range. * If there are multiple matches, the first that is found will be forced. * <p> * Example: "Sony Bravia HX@192.168.1.34,Sony Bravia EX@192.168.0-1.*" will * use regular detection for a renderer connecting from "192.168.2.1" (as * there is no match), will force "Sony Bravia EX" for a renderer connecting * from "192.168.1.2" (match with the range) and will force "Sony Bravia HX" * for a renderer connecting from "192.168.1.34" (matches both entries, but * the HX was found first). * <p> * Default: "", which means PMS will not force anything and use regular * detection. * * @param value The string containing the list. */ public void setRendererForceIp(String value) { configuration.setProperty(KEY_RENDERER_FORCE_IP, value); } public String getVirtualFolders() { return getString(KEY_VIRTUAL_FOLDERS, ""); } public String getProfilePath() { return PROFILE_PATH; } public String getProfileDirectory() { return PROFILE_DIRECTORY; } /** * Returns the absolute path to the WEB.conf file. By default * this is <pre>PROFILE_DIRECTORY + File.pathSeparator + WEB.conf</pre>, * but it can be overridden via the <pre>web_conf</pre> profile option. * The existence of the file is not checked. * * @return the path to the WEB.conf file. */ public String getWebConfPath() { // initialise this here rather than in the constructor // or statically so that custom settings are logged // to the debug.log/Logs tab. if (WEB_CONF_PATH == null) { WEB_CONF_PATH = FileUtil.getFileLocation( getString(KEY_WEB_CONF_PATH, null), PROFILE_DIRECTORY, DEFAULT_WEB_CONF_FILENAME ).getFilePath(); } return WEB_CONF_PATH; } public String getPluginDirectory() { return getString(KEY_PLUGIN_DIRECTORY, "plugins"); } public void setPluginDirectory(String value) { configuration.setProperty(KEY_PLUGIN_DIRECTORY, value); } public String getProfileName() { String defaultValue = "defaultValue"; String profileName = getString(KEY_PROFILE_NAME, defaultValue); if(profileName.equals(defaultValue)) { if (hostName == null) { // initialise this lazily try { hostName = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { logger.info("Can't determine hostname"); hostName = "unknown host"; } } profileName = hostName; } return profileName; } /** * Returns whether or not to automatically download software updates. * Defaults to "true" when updating is possible, unless configured otherwise. * * @return Whether or not to auto update. */ public boolean isAutoUpdate() { return Build.isUpdatable() && getBoolean(KEY_AUTO_UPDATE, true); } public void setAutoUpdate(boolean value) { configuration.setProperty(KEY_AUTO_UPDATE, value); } public int getUpnpPort() { return getInt(KEY_UPNP_PORT, 1900); } public String getUuid() { return getString(KEY_UUID, null); } public void setUuid(String value){ configuration.setProperty(KEY_UUID, value); } public void addConfigurationListener(ConfigurationListener l) { configuration.addConfigurationListener(l); } public void removeConfigurationListener(ConfigurationListener l) { configuration.removeConfigurationListener(l); } // FIXME this is undocumented and misnamed @Deprecated public boolean initBufferMax() { return getBoolean(KEY_BUFFER_MAX, false); } /** * Retrieve the name of the folder used to select subtitles, audio channels, chapters, engines &c. * Defaults to the localized version of <pre>#--TRANSCODE--#</pre>. * @return The folder name. */ public String getTranscodeFolderName() { return getString(KEY_TRANSCODE_FOLDER_NAME, Messages.getString("TranscodeVirtualFolder.0")); } /** * Set a custom name for the <pre>#--TRANSCODE--#</pre> folder. * @param name The folder name. */ public void setTranscodeFolderName(String name) { configuration.setProperty(KEY_TRANSCODE_FOLDER_NAME, name); } public boolean isVlcExperimentalCodecs() { return getBoolean(KEY_VLC_USE_EXPERIMENTAL_CODECS, false); } public void setVlcExperimentalCodecs(boolean value) { configuration.setProperty(KEY_VLC_USE_EXPERIMENTAL_CODECS, value); } public boolean isVlcAudioSyncEnabled() { return getBoolean(KEY_VLC_AUDIO_SYNC_ENABLED, false); } public void setVlcAudioSyncEnabled(boolean value) { configuration.setProperty(KEY_VLC_AUDIO_SYNC_ENABLED, value); } public boolean isVlcSubtitleEnabled() { return getBoolean(KEY_VLC_SUBTITLE_ENABLED, true); } public void setVlcSubtitleEnabled(boolean value) { configuration.setProperty(KEY_VLC_SUBTITLE_ENABLED, value); } public String getVlcScale() { return getString(KEY_VLC_SCALE, "1.0"); } public void setVlcScale(String value) { configuration.setProperty(KEY_VLC_SCALE, value); } public boolean getVlcSampleRateOverride() { return getBoolean(KEY_VLC_SAMPLE_RATE_OVERRIDE, false); } public void setVlcSampleRateOverride(boolean value) { configuration.setProperty(KEY_VLC_SAMPLE_RATE_OVERRIDE, value); } public String getVlcSampleRate() { return getString(KEY_VLC_SAMPLE_RATE, "48000"); } public void setVlcSampleRate(String value) { configuration.setProperty(KEY_VLC_SAMPLE_RATE, value); } /** * State if the video hardware acceleration is allowed * @return true if hardware acceleration is allowed, false otherwise */ public boolean isVideoHardwareAcceleration() { return getBoolean(KEY_VIDEO_HW_ACCELERATION, false); } /** * Set the video hardware acceleration enable/disable * @param value true if hardware acceleration is allowed, false otherwise */ public void setVideoHardwareAcceleration(boolean value) { configuration.setProperty(KEY_VIDEO_HW_ACCELERATION, value); } /** * Return the long filename format used for files and folders * outside the <pre>#--TRANSCODE--#</pre> folder. See the * "Filename templates" section of PMS.conf for more details. * * @return the long filename format. */ public String getLongFilenameFormat() { return getString(KEY_FILENAME_FORMAT_LONG, FILENAME_FORMAT_LONG); } /** * Return the short filename format used for files inside * the <pre>#--TRANSCODE--#</pre> folder. See the * "Filename templates" section of PMS.conf for more details. * * @return the short filename format. */ public String getShortFilenameFormat() { return getString(KEY_FILENAME_FORMAT_SHORT, FILENAME_FORMAT_SHORT); } }