use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.
the class LoggingTest method testLoggingConfig.
@Test
public void testLoggingConfig() throws ConfigurationException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// Set up a test (default) configuration
PMS.get();
PmsConfiguration configuration = new PmsConfiguration(false);
PMS.setConfiguration(configuration);
// Load logback configuration
LoggingConfig.loadFile();
// Silence logger
LoggingConfig.setRootLevel(Level.OFF);
// Get access to logger
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME);
/* During UMS build a valid configuration should be accessible at least under "external resources"
* and thus testing for a valid configuration is considered OK to be able to do the other tests.
* "internal defaults" is returned if a valid configuration can't be found.
*/
// Test for a valid configuration
File file = new File(LoggingConfig.getConfigFilePath());
assertTrue("LoggingConfigIsFile", file.isFile());
assertFalse("LoggingConfigIsFile", file.isDirectory());
// Test getLogFilePaths() and LoggingConfigFileLoader.getLogFilePaths()
HashMap<String, String> logFilePaths = LoggingConfig.getLogFilePaths();
@SuppressWarnings("deprecation") HashMap<String, String> compLogFilePaths = LoggingConfigFileLoader.getLogFilePaths();
Iterator<Appender<ILoggingEvent>> iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof FileAppender) {
FileAppender<ILoggingEvent> fa = (FileAppender<ILoggingEvent>) appender;
assertTrue("LogFilePathsContainsKey", logFilePaths.containsKey(fa.getName()));
assertEquals("LogFilePathsHasPath", logFilePaths.get(fa.getName()), fa.getFile());
if (fa.getName().equals("default.log")) {
assertTrue("CompatibleLogFilePathsContainsKey", compLogFilePaths.containsKey("debug.log"));
assertEquals("CompatibleLogFilePathsHasPath", compLogFilePaths.get("debug.log"), fa.getFile());
} else {
assertTrue("CompatibleLogFilePathsContainsKey", compLogFilePaths.containsKey(fa.getName()));
assertEquals("CompatibleLogFilePathsHasPath", compLogFilePaths.get(fa.getName()), fa.getFile());
}
}
}
// Reset LogBack configuration and create a fake one to not rely on the existing configuration file
context.reset();
TestFileAppender<ILoggingEvent> testDefaultAppender = new TestFileAppender<>();
testDefaultAppender.setName("default.log");
testDefaultAppender.setContext(context);
PatternLayoutEncoder layoutEncoder = new PatternLayoutEncoder();
layoutEncoder.setPattern("%-5level %d{HH:mm:ss.SSS} [%thread] %msg%n");
layoutEncoder.setContext(context);
testDefaultAppender.setEncoder(layoutEncoder);
rootLogger.addAppender(testDefaultAppender);
TestFileAppender<ILoggingEvent> testGenericAppender = new TestFileAppender<>();
testGenericAppender.setName("SomeOtherFileAppender");
testGenericAppender.setContext(context);
layoutEncoder = new PatternLayoutEncoder();
layoutEncoder.setPattern("%-5level %d %msg%n");
layoutEncoder.setContext(context);
testGenericAppender.setEncoder(layoutEncoder);
rootLogger.addAppender(testGenericAppender);
TestAppender<ILoggingEvent> testNonFileAppender = new TestAppender<>();
testNonFileAppender.setName("SomeNonFileAppender");
testNonFileAppender.setContext(context);
rootLogger.addAppender(testNonFileAppender);
// Test setBuffered()
LoggingConfig.setBuffered(true);
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
// Appender has ImmediateFlush property
assertFalse("LogFileIsBuffered", ((OutputStreamAppender<ILoggingEvent>) appender).isImmediateFlush());
}
}
LoggingConfig.setBuffered(false);
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
assertTrue("LogFileIsNotBuffered", ((OutputStreamAppender<ILoggingEvent>) appender).isImmediateFlush());
// Appender has ImmediateFlush property
}
}
// Test getRootLevel()
assertEquals("GetRootLevel", LoggingConfig.getRootLevel(), rootLogger.getLevel());
// Test setRootLevel()
LoggingConfig.setRootLevel(Level.ALL);
assertEquals("SetRootLevel", LoggingConfig.getRootLevel(), Level.ALL);
LoggingConfig.setRootLevel(Level.INFO);
assertEquals("SetRootLevel", LoggingConfig.getRootLevel(), Level.INFO);
LoggingConfig.setRootLevel(Level.OFF);
// Test setConsoleFilter()
configuration.setLoggingFilterConsole(Level.WARN);
ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>();
consoleAppender.setContext(context);
PatternLayoutEncoder patternEncoder = new PatternLayoutEncoder();
patternEncoder.setPattern("%msg%n");
patternEncoder.setContext(context);
patternEncoder.start();
consoleAppender.setEncoder(patternEncoder);
consoleAppender.start();
rootLogger.addAppender(consoleAppender);
LoggingConfig.setConsoleFilter();
List<Filter<ILoggingEvent>> filterList = consoleAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfConsoleFilters", filterList.size(), 1);
assertTrue("ConsoleFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
ThresholdFilter thresholdFilter = (ThresholdFilter) filterList.get(0);
Field field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("ConsoleFilterLevel", field.get(thresholdFilter), Level.WARN);
configuration.setLoggingFilterConsole(Level.TRACE);
LoggingConfig.setConsoleFilter();
filterList = consoleAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfConsoleFilters", filterList.size(), 1);
assertTrue("ConsoleFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("ConsoleFilterLevel", field.get(thresholdFilter), Level.TRACE);
rootLogger.detachAppender(consoleAppender);
// Test setTracesFilter()
configuration.setLoggingFilterLogsTab(Level.WARN);
FrameAppender<ILoggingEvent> frameAppender = new FrameAppender<>();
frameAppender.setContext(context);
patternEncoder = new PatternLayoutEncoder();
patternEncoder.setPattern("%msg%n");
patternEncoder.setContext(context);
patternEncoder.start();
frameAppender.setEncoder(patternEncoder);
frameAppender.start();
rootLogger.addAppender(frameAppender);
LoggingConfig.setTracesFilter();
filterList = frameAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfTracesFilters", filterList.size(), 1);
assertTrue("TracesFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("TracesFilterLevel", field.get(thresholdFilter), Level.WARN);
configuration.setLoggingFilterLogsTab(Level.TRACE);
LoggingConfig.setTracesFilter();
filterList = frameAppender.getCopyOfAttachedFiltersList();
assertEquals("NumberOfTracesFilters", filterList.size(), 1);
assertTrue("TracesFilterIsThresholdFilter", filterList.get(0) instanceof ThresholdFilter);
thresholdFilter = (ThresholdFilter) filterList.get(0);
field = thresholdFilter.getClass().getDeclaredField("level");
field.setAccessible(true);
assertEquals("TracesFilterLevel", field.get(thresholdFilter), Level.TRACE);
rootLogger.detachAppender(frameAppender);
// Test isSyslogDisabled()
if (syslogAppenderFound(rootLogger.iteratorForAppenders())) {
assertTrue("SyslogDisabledByConfiguration", LoggingConfig.isSyslogDisabled());
} else {
assertFalse("SyslogNotDisabledByConfiguration", LoggingConfig.isSyslogDisabled());
}
// Test setSyslog() if possible
if (!syslogAppenderFound(rootLogger.iteratorForAppenders())) {
configuration.setLoggingSyslogHost("localhost");
configuration.setLoggingUseSyslog(true);
LoggingConfig.setSyslog();
assertTrue("SyslogEnabled", syslogAppenderFound(rootLogger.iteratorForAppenders()));
configuration.setLoggingUseSyslog(false);
LoggingConfig.setSyslog();
assertFalse("SyslogDisabled", syslogAppenderFound(rootLogger.iteratorForAppenders()));
}
// Test forceVerboseFileEncoder() given that LogBack configuration
// contains at least one file appender with PatternLayoutEncoder
LoggingConfig.forceVerboseFileEncoder();
iterator = rootLogger.iteratorForAppenders();
while (iterator.hasNext()) {
Appender<ILoggingEvent> appender = iterator.next();
if (appender instanceof OutputStreamAppender && !(appender instanceof ConsoleAppender<?>)) {
// Appender has Encoder property
Encoder<ILoggingEvent> encoder = ((OutputStreamAppender<ILoggingEvent>) appender).getEncoder();
if (encoder instanceof PatternLayoutEncoder) {
// Encoder has pattern
patternEncoder = (PatternLayoutEncoder) encoder;
assertTrue("AppenderPatternHasCorrectTimestamp", patternEncoder.getPattern().matches(".*%(d|date)\\{yyyy-MM-dd HH:mm:ss.SSS\\}.*"));
assertTrue("AppenderPatternHasLogger", patternEncoder.getPattern().matches(".*%logger.*"));
}
}
}
context.reset();
}
use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.
the class DbgPacker method poll.
private void poll() {
// call the client callbacks
for (ExternalListener listener : ExternalFactory.getExternalListeners()) {
if (listener instanceof DebugPacker) {
LOGGER.debug("Found client {}", listener.name());
Object obj = ((DebugPacker) listener).dbgpack_cb();
if (obj instanceof String) {
add(((String) obj).split(","));
} else if (obj instanceof String[]) {
add((String[]) obj);
}
}
}
PmsConfiguration configuration = PMS.getConfiguration();
// check dbgpack property in UMS.conf
LOGGER.debug("Checking dbgpack property in UMS.conf");
String f = (String) configuration.getCustomProperty("dbgpack");
if (f != null) {
add(f.split(","));
}
// add confs of connected renderers
for (RendererConfiguration r : RendererConfiguration.getConnectedRenderersConfigurations()) {
add(r.getFile());
if (((DeviceConfiguration) r).isCustomized()) {
add(((DeviceConfiguration) r).getParentFile());
}
}
// add core items with the default logfile last (LinkedHashMap preserves insertion order)
String profileDirectory = configuration.getProfileDirectory();
// add virtual folders file if it exists
String vfolders = configuration.getVirtualFoldersFile(null);
if (StringUtils.isNotEmpty(vfolders)) {
add(new File(profileDirectory, vfolders));
}
add(new File(profileDirectory, "WEB.conf"));
add(new File(configuration.getProfilePath()));
if (defaultLogFile != null && !defaultLogFile.isEmpty()) {
add(new File(defaultLogFile + ".prev"));
add(new File(defaultLogFile));
}
}
use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.
the class TsMuxeRVideo method launchTranscode.
@Override
public ProcessWrapper launchTranscode(DLNAResource dlna, DLNAMediaInfo media, OutputParams params) throws IOException {
// Use device-specific pms conf
PmsConfiguration prev = configuration;
configuration = (DeviceConfiguration) params.mediaRenderer;
final String filename = dlna.getFileName();
setAudioAndSubs(filename, media, params);
PipeIPCProcess ffVideoPipe;
ProcessWrapperImpl ffVideo;
PipeIPCProcess[] ffAudioPipe = null;
ProcessWrapperImpl[] ffAudio = null;
String fps = media.getValidFps(false);
int width = media.getWidth();
int height = media.getHeight();
if (width < 320 || height < 240) {
width = -1;
height = -1;
}
String videoType = "V_MPEG4/ISO/AVC";
if (media.getCodecV() != null && media.getCodecV().startsWith("mpeg2")) {
videoType = "V_MPEG-2";
}
boolean aacTranscode = false;
String[] ffmpegCommands;
if (this instanceof TsMuxeRAudio && media.getFirstAudioTrack() != null) {
ffVideoPipe = new PipeIPCProcess(System.currentTimeMillis() + "fakevideo", System.currentTimeMillis() + "videoout", false, true);
String timeEndValue1 = "-t";
String timeEndValue2 = "" + params.timeend;
if (params.timeend < 1) {
timeEndValue1 = "-y";
timeEndValue2 = "-y";
}
ffmpegCommands = new String[] { configuration.getFfmpegPath(), timeEndValue1, timeEndValue2, "-loop", "1", "-i", "DummyInput.jpg", "-f", "h264", "-c:v", "libx264", "-level", "31", "-tune", "zerolatency", "-pix_fmt", "yuv420p", "-an", "-y", ffVideoPipe.getInputPipe() };
videoType = "V_MPEG4/ISO/AVC";
OutputParams ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffVideo = new ProcessWrapperImpl(ffmpegCommands, ffparams);
if (filename.toLowerCase().endsWith(".flac") && media.getFirstAudioTrack().getBitsperSample() >= 24 && media.getFirstAudioTrack().getSampleRate() % 48000 == 0) {
ffAudioPipe = new PipeIPCProcess[1];
ffAudioPipe[0] = new PipeIPCProcess(System.currentTimeMillis() + "flacaudio", System.currentTimeMillis() + "audioout", false, true);
String[] flacCmd = new String[] { configuration.getFlacPath(), "--output-name=" + ffAudioPipe[0].getInputPipe(), "-d", "-f", "-F", filename };
ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffAudio = new ProcessWrapperImpl[1];
ffAudio[0] = new ProcessWrapperImpl(flacCmd, ffparams);
} else {
ffAudioPipe = new PipeIPCProcess[1];
ffAudioPipe[0] = new PipeIPCProcess(System.currentTimeMillis() + "mlpaudio", System.currentTimeMillis() + "audioout", false, true);
String depth = "pcm_s16le";
String rate = "48000";
if (media.getFirstAudioTrack().getBitsperSample() >= 24) {
depth = "pcm_s24le";
}
if (media.getFirstAudioTrack().getSampleRate() > 48000) {
rate = "" + media.getFirstAudioTrack().getSampleRate();
}
String[] flacCmd = new String[] { configuration.getFfmpegPath(), "-i", filename, "-ar", rate, "-f", "wav", "-acodec", depth, "-y", ffAudioPipe[0].getInputPipe() };
ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffAudio = new ProcessWrapperImpl[1];
ffAudio[0] = new ProcessWrapperImpl(flacCmd, ffparams);
}
} else {
params.waitbeforestart = 5000;
params.manageFastStart();
ffVideoPipe = new PipeIPCProcess(System.currentTimeMillis() + "ffmpegvideo", System.currentTimeMillis() + "videoout", false, true);
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-c", "copy", "-f", "rawvideo", "-y", ffVideoPipe.getInputPipe() };
InputFile newInput = new InputFile();
newInput.setFilename(filename);
newInput.setPush(params.stdin);
/**
* Note: This logic is weird; on one hand we check if the renderer requires videos to be Level 4.1 or below, but then
* the other function allows the video to exceed those limits.
* In reality this won't cause problems since renderers typically don't support above 4.1 anyway - nor are many
* videos encoded higher than that either - but it's worth acknowledging the logic discrepancy.
*/
if (!media.isVideoWithinH264LevelLimits(newInput, params.mediaRenderer) && params.mediaRenderer.isH264Level41Limited()) {
LOGGER.info("The video will not play or will show a black screen");
}
if (media.getH264AnnexB() != null && media.getH264AnnexB().length > 0) {
StreamModifier sm = new StreamModifier();
sm.setHeader(media.getH264AnnexB());
sm.setH264AnnexB(true);
ffVideoPipe.setModifier(sm);
}
OutputParams ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffparams.stdin = params.stdin;
ffVideo = new ProcessWrapperImpl(ffmpegCommands, ffparams);
int numAudioTracks = 1;
if (media.getAudioTracksList() != null && media.getAudioTracksList().size() > 1 && configuration.isMuxAllAudioTracks()) {
numAudioTracks = media.getAudioTracksList().size();
}
boolean singleMediaAudio = media.getAudioTracksList().size() <= 1;
if (params.aid != null) {
boolean ac3Remux;
boolean dtsRemux;
boolean encodedAudioPassthrough;
boolean pcm;
if (numAudioTracks <= 1) {
ffAudioPipe = new PipeIPCProcess[numAudioTracks];
ffAudioPipe[0] = new PipeIPCProcess(System.currentTimeMillis() + "ffmpegaudio01", System.currentTimeMillis() + "audioout", false, true);
encodedAudioPassthrough = configuration.isEncodedAudioPassthrough() && params.aid.isNonPCMEncodedAudio() && params.mediaRenderer.isWrapEncodedAudioIntoPCM();
ac3Remux = params.aid.isAC3() && configuration.isAudioRemuxAC3() && !encodedAudioPassthrough && !params.mediaRenderer.isTranscodeToAAC();
dtsRemux = configuration.isAudioEmbedDtsInPcm() && params.aid.isDTS() && params.mediaRenderer.isDTSPlayable() && !encodedAudioPassthrough;
pcm = configuration.isAudioUsePCM() && media.isValidForLPCMTranscoding() && (params.aid.isLossless() || (params.aid.isDTS() && params.aid.getAudioProperties().getNumberOfChannels() <= 6) || params.aid.isTrueHD() || (!configuration.isMencoderUsePcmForHQAudioOnly() && (params.aid.isAC3() || params.aid.isMP3() || params.aid.isAAC() || params.aid.isVorbis() || // params.aid.isWMA() ||
params.aid.isMpegAudio()))) && params.mediaRenderer.isLPCMPlayable();
int channels;
if (ac3Remux) {
// AC-3 remux
channels = params.aid.getAudioProperties().getNumberOfChannels();
} else if (dtsRemux || encodedAudioPassthrough) {
channels = 2;
} else if (pcm) {
channels = params.aid.getAudioProperties().getNumberOfChannels();
} else {
// 5.1 max for AC-3 encoding
channels = configuration.getAudioChannelCount();
}
if (!ac3Remux && (dtsRemux || pcm || encodedAudioPassthrough)) {
// DTS remux or LPCM
StreamModifier sm = new StreamModifier();
sm.setPcm(pcm);
sm.setDtsEmbed(dtsRemux);
sm.setEncodedAudioPassthrough(encodedAudioPassthrough);
sm.setNbChannels(channels);
sm.setSampleFrequency(params.aid.getSampleRate() < 48000 ? 48000 : params.aid.getSampleRate());
sm.setBitsPerSample(16);
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + sm.getNbChannels(), "-f", "ac3", "-c:a", sm.isDtsEmbed() || sm.isEncodedAudioPassthrough() ? "copy" : "pcm", "-y", ffAudioPipe[0].getInputPipe() };
// Use PCM trick when media renderer does not support DTS in MPEG
if (!params.mediaRenderer.isMuxDTSToMpeg()) {
ffAudioPipe[0].setModifier(sm);
}
} else if (!ac3Remux && params.mediaRenderer.isTranscodeToAAC()) {
// AAC audio
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + channels, "-f", "adts", "-c:a", "aac", "-ab", Math.min(configuration.getAudioBitrate(), 320) + "k", "-y", ffAudioPipe[0].getInputPipe() };
aacTranscode = true;
} else {
// AC-3 audio
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + channels, "-f", "ac3", "-c:a", (ac3Remux) ? "copy" : "ac3", "-ab", String.valueOf(CodecUtil.getAC3Bitrate(configuration, params.aid)) + "k", "-y", ffAudioPipe[0].getInputPipe() };
}
ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffparams.stdin = params.stdin;
ffAudio = new ProcessWrapperImpl[numAudioTracks];
ffAudio[0] = new ProcessWrapperImpl(ffmpegCommands, ffparams);
} else {
ffAudioPipe = new PipeIPCProcess[numAudioTracks];
ffAudio = new ProcessWrapperImpl[numAudioTracks];
for (int i = 0; i < media.getAudioTracksList().size(); i++) {
DLNAMediaAudio audio = media.getAudioTracksList().get(i);
ffAudioPipe[i] = new PipeIPCProcess(System.currentTimeMillis() + "ffmpeg" + i, System.currentTimeMillis() + "audioout" + i, false, true);
encodedAudioPassthrough = configuration.isEncodedAudioPassthrough() && params.aid.isNonPCMEncodedAudio() && params.mediaRenderer.isWrapEncodedAudioIntoPCM();
ac3Remux = audio.isAC3() && configuration.isAudioRemuxAC3() && !encodedAudioPassthrough && !params.mediaRenderer.isTranscodeToAAC();
dtsRemux = configuration.isAudioEmbedDtsInPcm() && audio.isDTS() && params.mediaRenderer.isDTSPlayable() && !encodedAudioPassthrough;
pcm = configuration.isAudioUsePCM() && media.isValidForLPCMTranscoding() && (audio.isLossless() || (audio.isDTS() && audio.getAudioProperties().getNumberOfChannels() <= 6) || audio.isTrueHD() || (!configuration.isMencoderUsePcmForHQAudioOnly() && (audio.isAC3() || audio.isMP3() || audio.isAAC() || audio.isVorbis() || // audio.isWMA() ||
audio.isMpegAudio()))) && params.mediaRenderer.isLPCMPlayable();
int channels;
if (ac3Remux) {
// AC-3 remux
channels = audio.getAudioProperties().getNumberOfChannels();
} else if (dtsRemux || encodedAudioPassthrough) {
channels = 2;
} else if (pcm) {
channels = audio.getAudioProperties().getNumberOfChannels();
} else {
// 5.1 max for AC-3 encoding
channels = configuration.getAudioChannelCount();
}
if (!ac3Remux && (dtsRemux || pcm || encodedAudioPassthrough)) {
// DTS remux or LPCM
StreamModifier sm = new StreamModifier();
sm.setPcm(pcm);
sm.setDtsEmbed(dtsRemux);
sm.setEncodedAudioPassthrough(encodedAudioPassthrough);
sm.setNbChannels(channels);
sm.setSampleFrequency(audio.getSampleRate() < 48000 ? 48000 : audio.getSampleRate());
sm.setBitsPerSample(16);
if (!params.mediaRenderer.isMuxDTSToMpeg()) {
ffAudioPipe[i].setModifier(sm);
}
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + sm.getNbChannels(), "-f", "ac3", singleMediaAudio ? "-y" : "-map", singleMediaAudio ? "-y" : ("0:a:" + (media.getAudioTracksList().indexOf(audio))), "-c:a", sm.isDtsEmbed() || sm.isEncodedAudioPassthrough() ? "copy" : "pcm", "-y", ffAudioPipe[i].getInputPipe() };
} else if (!ac3Remux && params.mediaRenderer.isTranscodeToAAC()) {
// AAC audio
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + channels, "-f", "adts", singleMediaAudio ? "-y" : "-map", singleMediaAudio ? "-y" : ("0:a:" + (media.getAudioTracksList().indexOf(audio))), "-c:a", "aac", "-strict", "experimental", "-ab", Math.min(configuration.getAudioBitrate(), 320) + "k", "-y", ffAudioPipe[i].getInputPipe() };
aacTranscode = true;
} else {
// AC-3 remux or encoding
ffmpegCommands = new String[] { configuration.getFfmpegPath(), "-ss", params.timeseek > 0 ? "" + params.timeseek : "0", "-i", filename, "-ac", "" + channels, "-f", "ac3", singleMediaAudio ? "-y" : "-map", singleMediaAudio ? "-y" : ("0:a:" + (media.getAudioTracksList().indexOf(audio))), "-c:a", (ac3Remux) ? "copy" : "ac3", "-ab", String.valueOf(CodecUtil.getAC3Bitrate(configuration, audio)) + "k", "-y", ffAudioPipe[i].getInputPipe() };
}
ffparams = new OutputParams(configuration);
ffparams.maxBufferSize = 1;
ffparams.stdin = params.stdin;
ffAudio[i] = new ProcessWrapperImpl(ffmpegCommands, ffparams);
}
}
}
}
File f = new File(configuration.getTempFolder(), "pms-tsmuxer.meta");
params.log = false;
try (PrintWriter pw = new PrintWriter(f)) {
pw.print("MUXOPT --no-pcr-on-video-pid");
pw.print(" --new-audio-pes");
pw.print(" --no-asyncio");
pw.print(" --vbr");
pw.println(" --vbv-len=500");
String sei = "insertSEI";
if (params.mediaRenderer.isPS3() && media.isWebDl(filename, params)) {
sei = "forceSEI";
}
String videoparams = "level=4.1, " + sei + ", contSPS, track=1";
if (this instanceof TsMuxeRAudio) {
videoparams = "track=224";
}
if (configuration.isFix25FPSAvMismatch()) {
fps = "25";
}
pw.println(videoType + ", \"" + ffVideoPipe.getOutputPipe() + "\", " + (fps != null ? ("fps=" + fps + ", ") : "") + (width != -1 ? ("video-width=" + width + ", ") : "") + (height != -1 ? ("video-height=" + height + ", ") : "") + videoparams);
if (ffAudioPipe != null && ffAudioPipe.length == 1) {
String timeshift = "";
boolean ac3Remux;
boolean dtsRemux;
boolean encodedAudioPassthrough;
boolean pcm;
encodedAudioPassthrough = configuration.isEncodedAudioPassthrough() && params.aid.isNonPCMEncodedAudio() && params.mediaRenderer.isWrapEncodedAudioIntoPCM();
ac3Remux = params.aid.isAC3() && configuration.isAudioRemuxAC3() && !encodedAudioPassthrough && !params.mediaRenderer.isTranscodeToAAC();
dtsRemux = configuration.isAudioEmbedDtsInPcm() && params.aid.isDTS() && params.mediaRenderer.isDTSPlayable() && !encodedAudioPassthrough;
pcm = configuration.isAudioUsePCM() && media.isValidForLPCMTranscoding() && (params.aid.isLossless() || (params.aid.isDTS() && params.aid.getAudioProperties().getNumberOfChannels() <= 6) || params.aid.isTrueHD() || (!configuration.isMencoderUsePcmForHQAudioOnly() && (params.aid.isAC3() || params.aid.isMP3() || params.aid.isAAC() || params.aid.isVorbis() || // params.aid.isWMA() ||
params.aid.isMpegAudio()))) && params.mediaRenderer.isLPCMPlayable();
String type = "A_AC3";
if (ac3Remux) {
// AC-3 remux takes priority
type = "A_AC3";
} else if (aacTranscode) {
type = "A_AAC";
} else {
if (pcm || this instanceof TsMuxeRAudio) {
type = "A_LPCM";
}
if (encodedAudioPassthrough || this instanceof TsMuxeRAudio) {
type = "A_LPCM";
}
if (dtsRemux || this instanceof TsMuxeRAudio) {
type = "A_LPCM";
if (params.mediaRenderer.isMuxDTSToMpeg()) {
type = "A_DTS";
}
}
}
if (params.aid != null && params.aid.getAudioProperties().getAudioDelay() != 0 && params.timeseek == 0) {
timeshift = "timeshift=" + params.aid.getAudioProperties().getAudioDelay() + "ms, ";
}
pw.println(type + ", \"" + ffAudioPipe[0].getOutputPipe() + "\", " + timeshift + "track=2");
} else if (ffAudioPipe != null) {
for (int i = 0; i < media.getAudioTracksList().size(); i++) {
DLNAMediaAudio lang = media.getAudioTracksList().get(i);
String timeshift = "";
boolean ac3Remux;
boolean dtsRemux;
boolean encodedAudioPassthrough;
boolean pcm;
encodedAudioPassthrough = configuration.isEncodedAudioPassthrough() && params.aid.isNonPCMEncodedAudio() && params.mediaRenderer.isWrapEncodedAudioIntoPCM();
ac3Remux = lang.isAC3() && configuration.isAudioRemuxAC3() && !encodedAudioPassthrough;
dtsRemux = configuration.isAudioEmbedDtsInPcm() && lang.isDTS() && params.mediaRenderer.isDTSPlayable() && !encodedAudioPassthrough;
pcm = configuration.isAudioUsePCM() && media.isValidForLPCMTranscoding() && (lang.isLossless() || (lang.isDTS() && lang.getAudioProperties().getNumberOfChannels() <= 6) || lang.isTrueHD() || (!configuration.isMencoderUsePcmForHQAudioOnly() && (params.aid.isAC3() || params.aid.isMP3() || params.aid.isAAC() || params.aid.isVorbis() || // params.aid.isWMA() ||
params.aid.isMpegAudio()))) && params.mediaRenderer.isLPCMPlayable();
String type = "A_AC3";
if (ac3Remux) {
// AC-3 remux takes priority
type = "A_AC3";
} else {
if (pcm) {
type = "A_LPCM";
}
if (encodedAudioPassthrough) {
type = "A_LPCM";
}
if (dtsRemux) {
type = "A_LPCM";
if (params.mediaRenderer.isMuxDTSToMpeg()) {
type = "A_DTS";
}
}
}
if (lang.getAudioProperties().getAudioDelay() != 0 && params.timeseek == 0) {
timeshift = "timeshift=" + lang.getAudioProperties().getAudioDelay() + "ms, ";
}
pw.println(type + ", \"" + ffAudioPipe[i].getOutputPipe() + "\", " + timeshift + "track=" + (2 + i));
}
}
}
PipeProcess tsPipe = new PipeProcess(System.currentTimeMillis() + "tsmuxerout.ts");
/**
* Use the newer version of tsMuxeR on PS3 since other renderers
* like Panasonic TVs don't always recognize the new output
*/
String executable = executable();
if (params.mediaRenderer.isPS3()) {
executable = configuration.getTsmuxerNewPath();
}
String[] cmdArray = new String[] { executable, f.getAbsolutePath(), tsPipe.getInputPipe() };
cmdArray = finalizeTranscoderArgs(filename, dlna, media, params, cmdArray);
ProcessWrapperImpl p = new ProcessWrapperImpl(cmdArray, params);
params.maxBufferSize = 100;
params.input_pipes[0] = tsPipe;
params.stdin = null;
ProcessWrapper pipe_process = tsPipe.getPipeProcess();
p.attachProcess(pipe_process);
pipe_process.runInNewThread();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
tsPipe.deleteLater();
ProcessWrapper ff_pipe_process = ffVideoPipe.getPipeProcess();
p.attachProcess(ff_pipe_process);
ff_pipe_process.runInNewThread();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
ffVideoPipe.deleteLater();
p.attachProcess(ffVideo);
ffVideo.runInNewThread();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
if (ffAudioPipe != null && params.aid != null) {
for (int i = 0; i < ffAudioPipe.length; i++) {
ff_pipe_process = ffAudioPipe[i].getPipeProcess();
p.attachProcess(ff_pipe_process);
ff_pipe_process.runInNewThread();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
ffAudioPipe[i].deleteLater();
p.attachProcess(ffAudio[i]);
ffAudio[i].runInNewThread();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
p.runInNewThread();
configuration = prev;
return p;
}
use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.
the class VideoLanVideoStreaming method launchTranscode.
@Override
public ProcessWrapper launchTranscode(DLNAResource dlna, DLNAMediaInfo media, OutputParams params) throws IOException {
// Use device-specific pms conf
PmsConfiguration prev = configuration;
configuration = (DeviceConfiguration) params.mediaRenderer;
boolean isWindows = Platform.isWindows();
final String filename = dlna.getFileName();
PipeProcess tsPipe = new PipeProcess("VLC" + System.currentTimeMillis() + "." + getMux());
ProcessWrapper pipe_process = tsPipe.getPipeProcess();
// XXX it can take a long time for Windows to create a named pipe
// (and mkfifo can be slow if /tmp isn't memory-mapped), so start this as early as possible
pipe_process.runInNewThread();
tsPipe.deleteLater();
params.input_pipes[0] = tsPipe;
params.minBufferSize = params.minFileSize;
params.secondread_minsize = 100000;
List<String> cmdList = new ArrayList<>();
cmdList.add(executable());
cmdList.add("-I");
cmdList.add("dummy");
// TODO: either
// 1) add this automatically if enabled (probe)
// 2) add a GUI option to "enable GPU acceleration"
// 3) document it as an option the user can enable themselves in the vlc GUI (saved to a config file used by cvlc)
// XXX: it's still experimental (i.e. unstable), causing (consistent) segfaults on Windows and Linux,
// so don't even document it for now
// cmdList.add("--ffmpeg-hw");
String transcodeSpec = String.format("#transcode{%s}:standard{access=file,mux=%s,dst=\"%s%s\"}", getEncodingArgs(), getMux(), (isWindows ? "\\\\" : ""), tsPipe.getInputPipe());
if (isWindows) {
cmdList.add("--dummy-quiet");
}
if (isWindows || Platform.isMac()) {
cmdList.add("--sout=" + transcodeSpec);
} else {
cmdList.add("--sout");
cmdList.add(transcodeSpec);
}
// via: https://code.google.com/p/ps3mediaserver/issues/detail?id=711
if (Platform.isMac()) {
cmdList.add("");
}
cmdList.add(filename);
cmdList.add("vlc://quit");
String[] cmdArray = new String[cmdList.size()];
cmdList.toArray(cmdArray);
cmdArray = finalizeTranscoderArgs(filename, dlna, media, params, cmdArray);
ProcessWrapperImpl pw = new ProcessWrapperImpl(cmdArray, params);
pw.attachProcess(pipe_process);
try {
Thread.sleep(150);
} catch (InterruptedException e) {
}
pw.runInNewThread();
configuration = prev;
return pw;
}
use of net.pms.configuration.PmsConfiguration in project UniversalMediaServer by UniversalMediaServer.
the class FFmpegDVRMSRemux method getFFMpegTranscode.
// pointless redirection of launchTranscode
@Deprecated
protected ProcessWrapperImpl getFFMpegTranscode(DLNAResource dlna, DLNAMediaInfo media, OutputParams params) {
PmsConfiguration prev = configuration;
// Use device-specific pms conf
configuration = (DeviceConfiguration) params.mediaRenderer;
String ffmpegAlternativePath = configuration.getFfmpegAlternativePath();
List<String> cmdList = new ArrayList<>();
final String filename = dlna.getFileName();
if (ffmpegAlternativePath != null && ffmpegAlternativePath.length() > 0) {
cmdList.add(ffmpegAlternativePath);
} else {
cmdList.add(executable());
}
if (params.timeseek > 0) {
cmdList.add("-ss");
cmdList.add("" + params.timeseek);
}
cmdList.add("-i");
cmdList.add(filename);
cmdList.addAll(Arrays.asList(args()));
String customSettingsString = configuration.getMPEG2MainSettingsFFmpeg();
if (StringUtils.isNotBlank(customSettingsString)) {
String[] customSettingsArray = StringUtils.split(customSettingsString);
if (customSettingsArray != null) {
cmdList.addAll(Arrays.asList(customSettingsArray));
}
}
cmdList.add("pipe:");
String[] cmdArray = new String[cmdList.size()];
cmdList.toArray(cmdArray);
cmdArray = finalizeTranscoderArgs(filename, dlna, media, params, cmdArray);
ProcessWrapperImpl pw = new ProcessWrapperImpl(cmdArray, params);
pw.runInNewThread();
configuration = prev;
return pw;
}
Aggregations