public static boolean isTranscodeRequired(TranscodeProfile profile, AudioStream stream) { // Check audio codec if (getAudioChannelCount(stream.getConfiguration()) > 2) { if (profile.getMchCodecs() == null || !isSupported(profile.getMchCodecs(), stream.getCodec())) { return true; } } else { if (!isSupported(profile.getCodecs(), stream.getCodec())) { return true; } } // Check audio sample rate if (stream.getSampleRate() > profile.getMaxSampleRate()) { return true; } // If direct play is not enabled check stream parameters if (!profile.isDirectPlayEnabled()) { // Check bitrate for audio elements if (profile.getMediaElement().getType() == MediaElementType.AUDIO) { int bitrate = (getAudioChannelCount(stream.getConfiguration()) * AUDIO_QUALITY_MAX_BITRATE[profile.getQuality()]); if (bitrate > 0 && profile.getMediaElement().getBitrate() > bitrate) { return true; } } } return false; }
public static boolean processAudio(TranscodeProfile profile) { // Check variables if (profile.getMediaElement() == null || profile.getCodecs() == null || profile.getQuality() == null) { return false; } // If there are no audio streams to process we are done if (profile.getMediaElement().getAudioStreams() == null) { return true; } // Set audio track if necessary if (profile.getAudioTrack() == null) { if (profile.getMediaElement().getAudioStreams().size() > 0) { profile.setAudioTrack(0); } else { return true; } } // Check a format is specified for video transcode if (profile.getMediaElement().getType() == MediaElementType.VIDEO && profile.getFormat() == null) { return false; } // Process each audio stream List<AudioTranscode> transcodes = new ArrayList<>(); for (AudioStream stream : profile.getMediaElement().getAudioStreams()) { String codec = null; Integer quality = null; Integer sampleRate = null; boolean downmix = false; // Check if transcoding is required boolean transcodeRequired = isTranscodeRequired(profile, stream); // Check the format supports this codec for video or that we can stream this codec for audio if (!transcodeRequired) { if (profile.getFormat() != null) { transcodeRequired = !isSupported(getCodecsForFormat(profile.getFormat()), stream.getCodec()); } else { transcodeRequired = !isSupported(TRANSCODE_AUDIO_CODECS, stream.getCodec()); } } if (!transcodeRequired) { // Work around transcoder bug where flac files have the wrong duration if the stream is // copied codec = "copy"; // Get format if required if (profile.getFormat() == null) { profile.setFormat(getFormatForAudioCodec(stream.getCodec())); } } else { // Test if lossless codecs should be prioritised if (profile.getMediaElement().getType() == MediaElementType.AUDIO && (profile.getQuality() == AudioQuality.LOSSLESS || profile.isDirectPlayEnabled()) && isSupported(LOSSLESS_CODECS, stream.getCodec())) { profile.setCodecs(sortStringList(profile.getCodecs(), LOSSLESS_CODECS)); if (profile.mchCodecs != null) { profile.setMchCodecs(sortStringList(profile.getMchCodecs(), LOSSLESS_CODECS)); } } // Check for multichannel codecs if this is a multichannel stream if (getAudioChannelCount(stream.getConfiguration()) > 2) { // Try to get a suitable multichannel codec if (profile.getMchCodecs() != null) { for (String test : profile.getMchCodecs()) { if (isSupported(TRANSCODE_AUDIO_CODECS, test)) { if (profile.getFormat() != null) { if (isSupported(getCodecsForFormat(profile.getFormat()), test)) { codec = test; break; } } else { codec = test; break; } } } } // If a codec couldn't be found we need to downmix to stereo if (codec == null) { downmix = true; } } // If we still don't have a codec just try anything... if (codec == null) { for (String test : profile.getCodecs()) { if (isSupported(TRANSCODE_AUDIO_CODECS, test)) { if (profile.getFormat() != null) { if (isSupported(getCodecsForFormat(profile.getFormat()), test)) { codec = test; break; } } else { codec = test; break; } } } } // Check audio parameters for codec if (codec != null) { // Sample rate if ((stream.getSampleRate() > profile.getMaxSampleRate()) || (stream.getSampleRate() > getMaxSampleRateForCodec(codec))) { sampleRate = (profile.getMaxSampleRate() > getMaxSampleRateForCodec(codec)) ? getMaxSampleRateForCodec(codec) : profile.getMaxSampleRate(); } // Quality if (profile.getMediaElement().getType() == MediaElementType.AUDIO) { quality = getAudioQualityForCodec(codec, profile.getQuality()); } else if (profile.getMediaElement().getType() == MediaElementType.VIDEO) { quality = getAudioQualityForCodec(codec, VIDEO_QUALITY_AUDIO_QUALITY[profile.getQuality()]); } // Get format if required if (profile.getFormat() == null) { profile.setFormat(getFormatForAudioCodec(codec)); } // Update codec codec = getEncoderForAudioCodec(codec); } } // Add transcode properties to array transcodes.add(new AudioTranscode(codec, quality, sampleRate, downmix)); } // Update profile with audio transcode properties profile.setAudioTranscodes(transcodes.toArray(new AudioTranscode[transcodes.size()])); return true; }