Search in sources :

Example 6 with PmsConfiguration

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();
}
Also used : ConsoleAppender(ch.qos.logback.core.ConsoleAppender) ThresholdFilter(ch.qos.logback.classic.filter.ThresholdFilter) OutputStreamAppender(ch.qos.logback.core.OutputStreamAppender) Logger(ch.qos.logback.classic.Logger) ILoggingEvent(ch.qos.logback.classic.spi.ILoggingEvent) Field(java.lang.reflect.Field) PmsConfiguration(net.pms.configuration.PmsConfiguration) ConsoleAppender(ch.qos.logback.core.ConsoleAppender) OutputStreamAppender(ch.qos.logback.core.OutputStreamAppender) FileAppender(ch.qos.logback.core.FileAppender) SyslogAppender(ch.qos.logback.classic.net.SyslogAppender) Appender(ch.qos.logback.core.Appender) FileAppender(ch.qos.logback.core.FileAppender) PatternLayoutEncoder(ch.qos.logback.classic.encoder.PatternLayoutEncoder) LoggerContext(ch.qos.logback.classic.LoggerContext) ThresholdFilter(ch.qos.logback.classic.filter.ThresholdFilter) Filter(ch.qos.logback.core.filter.Filter) File(java.io.File) Test(org.junit.Test)

Example 7 with PmsConfiguration

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));
    }
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration) RendererConfiguration(net.pms.configuration.RendererConfiguration) DebugPacker(net.pms.external.DebugPacker) ExternalListener(net.pms.external.ExternalListener) DeviceConfiguration(net.pms.configuration.DeviceConfiguration) File(java.io.File)

Example 8 with PmsConfiguration

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;
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration) File(java.io.File) PrintWriter(java.io.PrintWriter)

Example 9 with PmsConfiguration

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;
}
Also used : ProcessWrapper(net.pms.io.ProcessWrapper) PmsConfiguration(net.pms.configuration.PmsConfiguration) PipeProcess(net.pms.io.PipeProcess) ArrayList(java.util.ArrayList) ProcessWrapperImpl(net.pms.io.ProcessWrapperImpl)

Example 10 with PmsConfiguration

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;
}
Also used : PmsConfiguration(net.pms.configuration.PmsConfiguration) ArrayList(java.util.ArrayList) ProcessWrapperImpl(net.pms.io.ProcessWrapperImpl)

Aggregations

PmsConfiguration (net.pms.configuration.PmsConfiguration)32 File (java.io.File)7 ProcessWrapperImpl (net.pms.io.ProcessWrapperImpl)7 ArrayList (java.util.ArrayList)6 OutputParams (net.pms.io.OutputParams)5 IOException (java.io.IOException)4 ProcessWrapper (net.pms.io.ProcessWrapper)4 LoggerContext (ch.qos.logback.classic.LoggerContext)3 SyslogAppender (ch.qos.logback.classic.net.SyslogAppender)3 ILoggingEvent (ch.qos.logback.classic.spi.ILoggingEvent)3 Appender (ch.qos.logback.core.Appender)3 ConsoleAppender (ch.qos.logback.core.ConsoleAppender)3 FileAppender (ch.qos.logback.core.FileAppender)3 OutputStreamAppender (ch.qos.logback.core.OutputStreamAppender)3 RendererConfiguration (net.pms.configuration.RendererConfiguration)3 PipeProcess (net.pms.io.PipeProcess)3 ThresholdFilter (ch.qos.logback.classic.filter.ThresholdFilter)2 PrintWriter (java.io.PrintWriter)2 StringTokenizer (java.util.StringTokenizer)2 DLNAMediaAudio (net.pms.dlna.DLNAMediaAudio)2