protected void prepareVideo( IVideoResampler[] iVideoResamplers, IVideoPicture[] inputIVideoPictures, IVideoPicture[] outputIVideoPictures, IStreamCoder inputIStreamCoder, IStreamCoder[] outputIStreamCoders, IContainer outputIContainer, IStream[] outputIStreams, ICodec.Type inputICodecType, String outputURL, int index) throws Exception { ICodec iCodec = getVideoEncodingICodec(inputICodecType, outputURL); if (iCodec == null) { throw new RuntimeException( "Unable to determine " + inputICodecType + " encoder for " + outputURL); } IStream outputIStream = outputIContainer.addNewStream(iCodec); outputIStreams[index] = outputIStream; IStreamCoder outputIStreamCoder = outputIStream.getStreamCoder(); outputIStreamCoders[index] = outputIStreamCoder; int bitRate = inputIStreamCoder.getBitRate(); if (_log.isInfoEnabled()) { _log.info("Original video bitrate " + bitRate); } bitRate = getVideoBitRate(bitRate); if (_log.isInfoEnabled()) { _log.info("Modified video bitrate " + bitRate); } outputIStreamCoder.setBitRate(bitRate); IRational iRational = inputIStreamCoder.getFrameRate(); if (_log.isInfoEnabled()) { _log.info( "Original frame rate " + iRational.getNumerator() + "/" + iRational.getDenominator()); } iRational = getVideoFrameRate(iRational); if (_log.isInfoEnabled()) { _log.info( "Modified frame rate " + iRational.getNumerator() + "/" + iRational.getDenominator()); } outputIStreamCoder.setFrameRate(iRational); if (inputIStreamCoder.getHeight() <= 0) { throw new RuntimeException("Unable to determine height for " + _inputURL); } if (_height == 0) { _height = inputIStreamCoder.getHeight(); } outputIStreamCoder.setHeight(_height); outputIStreamCoder.setPixelType(Type.YUV420P); outputIStreamCoder.setTimeBase( IRational.make(iRational.getDenominator(), iRational.getNumerator())); if (inputIStreamCoder.getWidth() <= 0) { throw new RuntimeException("Unable to determine width for " + _inputURL); } if (_width == 0) { _width = inputIStreamCoder.getWidth(); } outputIStreamCoder.setWidth(_width); iVideoResamplers[index] = createIVideoResampler(inputIStreamCoder, outputIStreamCoder, _height, _width); inputIVideoPictures[index] = IVideoPicture.make( inputIStreamCoder.getPixelType(), inputIStreamCoder.getWidth(), inputIStreamCoder.getHeight()); outputIVideoPictures[index] = IVideoPicture.make( outputIStreamCoder.getPixelType(), outputIStreamCoder.getWidth(), outputIStreamCoder.getHeight()); ICodec.ID iCodecID = iCodec.getID(); if (iCodecID.equals(ICodec.ID.CODEC_ID_H264)) { Configuration.configure(_ffpresetProperties, outputIStreamCoder); } }
protected void prepareVideo( IVideoResampler[] iVideoResamplers, IVideoPicture[] inputIVideoPictures, IVideoPicture[] outputIVideoPictures, IStreamCoder inputIStreamCoder, IStreamCoder[] outputIStreamCoders, IContainer outputIContainer, IStream[] outputIStreams, ICodec.Type inputICodecType, String outputURL, int index) throws Exception { IStream outputIStream = outputIContainer.addNewStream(index); outputIStreams[index] = outputIStream; IStreamCoder outputIStreamCoder = outputIStream.getStreamCoder(); outputIStreamCoders[index] = outputIStreamCoder; int bitRate = inputIStreamCoder.getBitRate(); if (_log.isInfoEnabled()) { _log.info("Original video bitrate " + bitRate); } if (bitRate == 0) { bitRate = GetterUtil.getInteger(_videoBitRateMap.get(_outputVideoFormat), _VIDEO_BIT_RATE_DEFAULT); } else if (bitRate > _VIDEO_BIT_RATE_MAX) { bitRate = _VIDEO_BIT_RATE_MAX; } if (_log.isInfoEnabled()) { _log.info("Modified video bitrate " + bitRate); } outputIStreamCoder.setBitRate(bitRate); ICodec iCodec = ICodec.guessEncodingCodec(null, null, outputURL, null, inputICodecType); if (_outputVideoFormat.equals("mp4")) { iCodec = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264); } if (iCodec == null) { throw new RuntimeException( "Unable to determine " + inputICodecType + " encoder for " + outputURL); } outputIStreamCoder.setCodec(iCodec); IRational iRational = inputIStreamCoder.getFrameRate(); if (_log.isInfoEnabled()) { _log.info( "Original frame rate " + iRational.getNumerator() + "/" + iRational.getDenominator()); } if (_videoFrameRateMap.containsKey(_outputVideoFormat)) { iRational = _videoFrameRateMap.get(_outputVideoFormat); } if (_log.isInfoEnabled()) { _log.info( "Modified frame rate " + iRational.getNumerator() + "/" + iRational.getDenominator()); } outputIStreamCoder.setFrameRate(iRational); if (inputIStreamCoder.getHeight() <= 0) { throw new RuntimeException("Unable to determine height for " + _inputURL); } outputIStreamCoder.setHeight(_height); outputIStreamCoder.setPixelType(Type.YUV420P); outputIStreamCoder.setTimeBase( IRational.make(iRational.getDenominator(), iRational.getNumerator())); if (inputIStreamCoder.getWidth() <= 0) { throw new RuntimeException("Unable to determine width for " + _inputURL); } outputIStreamCoder.setWidth(_width); iVideoResamplers[index] = createIVideoResampler(inputIStreamCoder, outputIStreamCoder, _height, _width); inputIVideoPictures[index] = IVideoPicture.make( inputIStreamCoder.getPixelType(), inputIStreamCoder.getWidth(), inputIStreamCoder.getHeight()); outputIVideoPictures[index] = IVideoPicture.make( outputIStreamCoder.getPixelType(), outputIStreamCoder.getWidth(), outputIStreamCoder.getHeight()); ICodec.ID iCodecID = iCodec.getID(); if (iCodecID.equals(ICodec.ID.CODEC_ID_H264)) { Configuration.configure(_ffpresetProperties, outputIStreamCoder); } }
/** * The playSong method is responsible for opening a Xuggler container to play song at provided * location. * * @param songURL The location of the song to play (local file path or url) */ public void playSong(String songURL) { IContainer container = IContainer.make(); IContainerFormat format = IContainerFormat.make(); // Stream format must currently be mp3 format.setInputFormat("mp3"); // int s = container.setInputBufferLength(6270); // // if(s < 0){ // logger.warn("Input buffer was not set to desired length"); // } // Probe size value must be >50 for some reason. Native libraries throw an exception if it's // <50. Measured in bytes. if (container.setProperty("probesize", 50) < 0) { logger.warn("Probe size not set for input container."); } if (container.setProperty("analyzeduration", 1) < 0) { logger.warn("Analyze duration not changed for input container."); } container.setFlag(IContainer.Flags.FLAG_NONBLOCK, true); if (container.open(songURL, Type.READ, format, true, false) < 0) { throw new IllegalArgumentException("stream not found"); } int numStreams = container.getNumStreams(); // long streamRec = System.currentTimeMillis(); logger.info("Number of Audio streams detected {}", numStreams); IPacket packet = IPacket.make(); IStream stream = null; IStreamCoder audioCoder = null; Map<Integer, IStreamCoder> knownStreams = new HashMap<Integer, IStreamCoder>(); long previousValue = 0; while (container.readNextPacket(packet) >= 0 && alive) { if (packet.isComplete()) { if (knownStreams.get(packet.getStreamIndex()) == null) { container.queryStreamMetaData(); // This method tends to take awhile when reading a stream stream = container.getStream(packet.getStreamIndex()); knownStreams.put(packet.getStreamIndex(), stream.getStreamCoder()); audioCoder = knownStreams.get(packet.getStreamIndex()); audioCoder.setTimeBase(stream.getTimeBase()); } if (!audioCoder.isOpen()) { if (audioCoder.open(null, null) < 0) { throw new RuntimeException("could not open audio decoder for container"); } openSound(audioCoder); // System.out.println("Opening sound " + (System.currentTimeMillis() - streamRec)); } // System.err.println(audioCoder.getNumDroppedFrames()); int offset = 0; IAudioSamples samples = IAudioSamples.make(1024, audioCoder.getChannels()); while (offset < packet.getSize() && alive) { // Wait until the state is playing while (state != PlayBack_State.PLAYING) { if (state == PlayBack_State.TEARDOWN) { break; } else { try { synchronized (LOCK_OBJECT) { // mLine.drain(); mLine.flush(); mLine.stop(); LOCK_OBJECT.wait(); mLine.start(); } } catch (InterruptedException e) { logger.error("", e); } } } int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset); if (bytesDecoded < 0) { logger.warn("Error occurred decoding audio"); break; // throw new RuntimeException("got error decoding audio"); } offset += bytesDecoded; if (samples.isComplete() && alive) { playJavaSound(samples); } // Send the time stamp to the GUI for updating the progress bar long newValue = (long) (packet.getTimeStamp() * packet.getTimeBase().getValue()); // Update GUI every second that the stream is playing if (newValue > previousValue) { callback.notifyGUISongProgress(newValue); callback.isStreaming(true); previousValue = newValue; if (newValue == streamInfo.getSongDuration()) { alive = false; } } } } } closeJavaSound(); if (audioCoder != null) { audioCoder.close(); audioCoder = null; } if (container != null) { container.close(); container = null; } }