humble-video-demos/src/main/java/io/humble/video/demos/DecodeAndPlayAudio.java
private static void playSound(String filename) throws InterruptedException, IOException, LineUnavailableException {
    /*
     * Start by creating a container object, in this case a demuxer since
     * we are reading, to get audio data from.
     */
    Demuxer demuxer = Demuxer.make();

    /*
     * Open the demuxer with the filename passed on.
     */
    demuxer.open(filename, null, false, true, null, null);

    /*
     * Query how many streams the call to open found
     */
    int numStreams = demuxer.getNumStreams();

    /*
     * Iterate through the streams to find the first audio stream
     */
    int audioStreamId = -1;
    Decoder audioDecoder = null;
    for(int i = 0; i < numStreams; i++)
    {
      final DemuxerStream stream = demuxer.getStream(i);
      final Decoder decoder = stream.getDecoder();
      if (decoder != null && decoder.getCodecType() == MediaDescriptor.Type.MEDIA_AUDIO) {
        audioStreamId = i;
        audioDecoder = decoder;
        // stop at the first one.
        break;
      }
    }
    if (audioStreamId == -1)
      throw new RuntimeException("could not find audio stream in container: "+filename);

    /*
     * Now we have found the audio stream in this file.  Let's open up our decoder so it can
     * do work.
     */
    audioDecoder.open(null, null);

    /*
     * We allocate a set of samples with the same number of channels as the
     * coder tells us is in this buffer.
     */
    final MediaAudio samples = MediaAudio.make(
        audioDecoder.getFrameSize(),
        audioDecoder.getSampleRate(),
        audioDecoder.getChannels(),
        audioDecoder.getChannelLayout(),
        audioDecoder.getSampleFormat());

    /*
     * A converter object we'll use to convert Humble Audio to a format that
     * Java Audio can actually play. The details are complicated, but essentially
     * this converts any audio format (represented in the samples object) into
     * a default audio format suitable for Java's speaker system (which will
     * be signed 16-bit audio, stereo (2-channels), resampled to 22,050 samples
     * per second).
     */
    
    final MediaAudioConverter converter =
        MediaAudioConverterFactory.createConverter(
            MediaAudioConverterFactory.DEFAULT_JAVA_AUDIO,
            samples);

    /*
     * An AudioFrame is a wrapper for the Java Sound system that abstracts away
     * some stuff. Go read the source code if you want -- it's not very complicated.
     */
    final AudioFrame audioFrame = AudioFrame.make(converter.getJavaFormat());
    if (audioFrame == null)
      throw new LineUnavailableException();

    /* We will use this to cache the raw-audio we pass to and from
     * the java sound system.
     */
    ByteBuffer rawAudio = null;

    /*
     * Now, we start walking through the container looking at each packet. This
     * is a decoding loop, and as you work with Humble you'll write a lot
     * of these.
     * 
     * Notice how in this loop we reuse all of our objects to avoid
     * reallocating them. Each call to Humble resets objects to avoid
     * unnecessary reallocation.
     */
    final MediaPacket packet = MediaPacket.make();
    while(demuxer.read(packet) >= 0) {
      /*
       * Now we have a packet, let's see if it belongs to our audio stream
       */
      if (packet.getStreamIndex() == audioStreamId)
      {
        /*
         * A packet can actually contain multiple sets of samples (or frames of samples
         * in audio-decoding speak).  So, we may need to call decode audio multiple
         * times at different offsets in the packet's data.  We capture that here.
         */
        int offset = 0;
        int bytesRead = 0;
        do {
          bytesRead += audioDecoder.decode(samples, packet, offset);
          if (samples.isComplete()) {
            rawAudio = converter.toJavaAudio(rawAudio, samples);
            audioFrame.play(rawAudio);
          }
          offset += bytesRead;
        } while (offset < packet.getSize());
      }
    }

    // Some audio decoders (especially advanced ones) will cache
    // audio data before they begin decoding, so when you are done you need
    // to flush them. The convention to flush Encoders or Decoders in Humble Video
    // is to keep passing in null until incomplete samples or packets are returned.
    do {
      audioDecoder.decode(samples, null, 0);
      if (samples.isComplete()) {
        rawAudio = converter.toJavaAudio(rawAudio, samples);
        audioFrame.play(rawAudio);
      }
    } while (samples.isComplete());
    
    // It is good practice to close demuxers when you're done to free
    // up file handles. Humble will EVENTUALLY detect if nothing else
    // references this demuxer and close it then, but get in the habit
    // of cleaning up after yourself, and your future girlfriend/boyfriend
    // will appreciate it.
    demuxer.close();
    
    // similar with the demuxer, for the audio playback stuff, clean up after yourself.
    audioFrame.dispose();
  }
private static void playSound(String filename) throws InterruptedException, IOException, LineUnavailableException {
    /*
     * Start by creating a container object, in this case a demuxer since
     * we are reading, to get audio data from.
     */
    Demuxer demuxer = Demuxer.make();

    /*
     * Open the demuxer with the filename passed on.
     */
    demuxer.open(filename, null, false, true, null, null);

    /*
     * Query how many streams the call to open found
     */
    int numStreams = demuxer.getNumStreams();

    /*
     * Iterate through the streams to find the first audio stream
     */
    int audioStreamId = -1;
    Decoder audioDecoder = null;
    for(int i = 0; i < numStreams; i++)
    {
      final DemuxerStream stream = demuxer.getStream(i);
      final Decoder decoder = stream.getDecoder();
      if (decoder != null && decoder.getCodecType() == MediaDescriptor.Type.MEDIA_AUDIO) {
        audioStreamId = i;
        audioDecoder = decoder;
        // stop at the first one.
        break;
      }
    }
    if (audioStreamId == -1)
      throw new RuntimeException("could not find audio stream in container: "+filename);

    /*
     * Now we have found the audio stream in this file.  Let's open up our decoder so it can
     * do work.
     */
    audioDecoder.open(null, null);

    /*
     * We allocate a set of samples with the same number of channels as the
     * coder tells us is in this buffer.
     */
    final MediaAudio samples = MediaAudio.make(
        audioDecoder.getFrameSize(),
        audioDecoder.getSampleRate(),
        audioDecoder.getChannels(),
        audioDecoder.getChannelLayout(),
        audioDecoder.getSampleFormat());

    /*
     * A converter object we'll use to convert Humble Audio to a format that
     * Java Audio can actually play. The details are complicated, but essentially
     * this converts any audio format (represented in the samples object) into
     * a default audio format suitable for Java's speaker system (which will
     * be signed 16-bit audio, stereo (2-channels), resampled to 22,050 samples
     * per second).
     */
    
    final MediaAudioConverter converter =
        MediaAudioConverterFactory.createConverter(
            MediaAudioConverterFactory.DEFAULT_JAVA_AUDIO,
            samples);

    /*
     * An AudioFrame is a wrapper for the Java Sound system that abstracts away
     * some stuff. Go read the source code if you want -- it's not very complicated.
     */
    final AudioFrame audioFrame = AudioFrame.make(converter.getJavaFormat());
    if (audioFrame == null)
      throw new LineUnavailableException();

    /* We will use this to cache the raw-audio we pass to and from
     * the java sound system.
     */
    ByteBuffer rawAudio = null;

    /*
     * Now, we start walking through the container looking at each packet. This
     * is a decoding loop, and as you work with Humble you'll write a lot
     * of these.
     * 
     * Notice how in this loop we reuse all of our objects to avoid
     * reallocating them. Each call to Humble resets objects to avoid
     * unnecessary reallocation.
     */
    final MediaPacket packet = MediaPacket.make();
    while(demuxer.read(packet) >= 0) {
      /*
       * Now we have a packet, let's see if it belongs to our audio stream
       */
      if (packet.getStreamIndex() == audioStreamId)
      {
        /*
         * A packet can actually contain multiple sets of samples (or frames of samples
         * in audio-decoding speak).  So, we may need to call decode audio multiple
         * times at different offsets in the packet's data.  We capture that here.
         */
        int offset = 0;
        int bytesRead = 0;
        do {
          bytesRead += audioDecoder.decode(samples, packet, offset);
          if (samples.isComplete()) {
            rawAudio = converter.toJavaAudio(rawAudio, samples);
            audioFrame.play(rawAudio);
          }
          offset += bytesRead;
        } while (offset < packet.getSize());
      }
    }

    // Some audio decoders (especially advanced ones) will cache
    // audio data before they begin decoding, so when you are done you need
    // to flush them. The convention to flush Encoders or Decoders in Humble Video
    // is to keep passing in null until incomplete samples or packets are returned.
    do {
      audioDecoder.decode(samples, null, 0);
      if (samples.isComplete()) {
        rawAudio = converter.toJavaAudio(rawAudio, samples);
        audioFrame.play(rawAudio);
      }
    } while (samples.isComplete());
    
    // It is good practice to close demuxers when you're done to free
    // up file handles. Humble will EVENTUALLY detect if nothing else
    // references this demuxer and close it then, but get in the habit
    // of cleaning up after yourself, and your future girlfriend/boyfriend
    // will appreciate it.
    demuxer.close();
    
    // similar with the demuxer, for the audio playback stuff, clean up after yourself.
    audioFrame.dispose();
  }
private static void playSound ( String filename ) throws InterruptedException , IOException , LineUnavailableException { /*
     * Start by creating a container object, in this case a demuxer since
     * we are reading, to get audio data from.
     */ Demuxer demuxer = Demuxer . make ( ) ; /*
     * Open the demuxer with the filename passed on.
     */ demuxer . open ( filename , null , false , true , null , null ) ; /*
     * Query how many streams the call to open found
     */ int numStreams = demuxer . getNumStreams ( ) ; /*
     * Iterate through the streams to find the first audio stream
     */ int audioStreamId = - 1 ; Decoder audioDecoder = null ; for ( int i = 0 ; i < numStreams ; i ++ ) { final DemuxerStream stream = demuxer . getStream ( i ) ; final Decoder decoder = stream . getDecoder ( ) ; if ( decoder != null && decoder . getCodecType ( ) == MediaDescriptor . Type . MEDIA_AUDIO ) { audioStreamId = i ; audioDecoder = decoder ; // stop at the first one. break ; } } if ( audioStreamId == - 1 ) throw new RuntimeException ( "could not find audio stream in container: " + filename ) ; /*
     * Now we have found the audio stream in this file.  Let's open up our decoder so it can
     * do work.
     */ audioDecoder . open ( null , null ) ; /*
     * We allocate a set of samples with the same number of channels as the
     * coder tells us is in this buffer.
     */ final MediaAudio samples = MediaAudio . make ( audioDecoder . getFrameSize ( ) , audioDecoder . getSampleRate ( ) , audioDecoder . getChannels ( ) , audioDecoder . getChannelLayout ( ) , audioDecoder . getSampleFormat ( ) ) ; /*
     * A converter object we'll use to convert Humble Audio to a format that
     * Java Audio can actually play. The details are complicated, but essentially
     * this converts any audio format (represented in the samples object) into
     * a default audio format suitable for Java's speaker system (which will
     * be signed 16-bit audio, stereo (2-channels), resampled to 22,050 samples
     * per second).
     */ final MediaAudioConverter converter = MediaAudioConverterFactory . createConverter ( MediaAudioConverterFactory . DEFAULT_JAVA_AUDIO , samples ) ; /*
     * An AudioFrame is a wrapper for the Java Sound system that abstracts away
     * some stuff. Go read the source code if you want -- it's not very complicated.
     */ final AudioFrame audioFrame = AudioFrame . make ( converter . getJavaFormat ( ) ) ; if ( audioFrame == null ) throw new LineUnavailableException ( ) ; /* We will use this to cache the raw-audio we pass to and from
     * the java sound system.
     */ ByteBuffer rawAudio = null ; /*
     * Now, we start walking through the container looking at each packet. This
     * is a decoding loop, and as you work with Humble you'll write a lot
     * of these.
     * 
     * Notice how in this loop we reuse all of our objects to avoid
     * reallocating them. Each call to Humble resets objects to avoid
     * unnecessary reallocation.
     */ final MediaPacket packet = MediaPacket . make ( ) ; while ( demuxer . read ( packet ) >= 0 ) { /*
       * Now we have a packet, let's see if it belongs to our audio stream
       */ if ( packet . getStreamIndex ( ) == audioStreamId ) { /*
         * A packet can actually contain multiple sets of samples (or frames of samples
         * in audio-decoding speak).  So, we may need to call decode audio multiple
         * times at different offsets in the packet's data.  We capture that here.
         */ int offset = 0 ; int bytesRead = 0 ; do { bytesRead += audioDecoder . decode ( samples , packet , offset ) ; if ( samples . isComplete ( ) ) { rawAudio = converter . toJavaAudio ( rawAudio , samples ) ; audioFrame . play ( rawAudio ) ; } offset += bytesRead ; } while ( offset < packet . getSize ( ) ) ; } } // Some audio decoders (especially advanced ones) will cache // audio data before they begin decoding, so when you are done you need // to flush them. The convention to flush Encoders or Decoders in Humble Video // is to keep passing in null until incomplete samples or packets are returned. do { audioDecoder . decode ( samples , null , 0 ) ; if ( samples . isComplete ( ) ) { rawAudio = converter . toJavaAudio ( rawAudio , samples ) ; audioFrame . play ( rawAudio ) ; } } while ( samples . isComplete ( ) ) ; // It is good practice to close demuxers when you're done to free // up file handles. Humble will EVENTUALLY detect if nothing else // references this demuxer and close it then, but get in the habit // of cleaning up after yourself, and your future girlfriend/boyfriend // will appreciate it. demuxer . close ( ) ; // similar with the demuxer, for the audio playback stuff, clean up after yourself. audioFrame . dispose ( ) ; }
Opens a file, and plays the audio from it on the speakers.
@param filename The file or URL to play.
@throws LineUnavailableException
Opens a file and plays the audio from it on the speakers .