Interface IMediaWriter

  • All Superinterfaces:
    IMediaCoder, IMediaGenerator, IMediaListener, IMediaTool

    public interface IMediaWriter
    extends IMediaCoder, IMediaTool
    An IMediaCoder that encodes and decodes media to an IContainer, and can optionally read data for encoding from other IMediaGenerator objects.

    Here's some pseudo code that shows how to encode an audio file:

     IMediaWriter writer = ToolFactory.makeWriter("output.mp3");
     int sampleRate = 22050;
     int channels = 1;
     writer.addAudioStream(0, 0, sampleRate, channels);
     
     while(haveMoreAudio())
     {
       short[] samples = getSourceSamples();
       writer.encodeAudio(0, samples);
     }
     writer.close();
     

    And here's some pseudo code that shows how to encode a video image every 1 second:

     IMediaWriter writer = ToolFactory.makeWriter("output.mp4");
     writer.addVideoStream(0, 0, sampleRate, channels);
     
     long startTime = System.nanoTime(); 
     while(haveMoreVideo())
     {
       BufferedImage image = getImage();
       writer.encodeAudio(0, image,
        System.nanoTime()-startTime, TimeUnit.NANOSECONDS);
       Thread.sleep(1000);
     }
     writer.close();
     

    An IMediaWriter is a simplified interface to the AVPKit library that opens up a media container, and allows media data to be written into it.

    The IMediaWriter class implements IMediaListener, and so it can be attached to any IMediaGenerator that generates raw media events (e.g. IMediaReader). If will query the input pipe for all of it's streams, and create the right output streams (and mappings) in the new file.

    Calls to encodeAudio(int, IAudioSamples) and encodeVideo(int, IVideoPicture) encode media into packets and write those packets to the specified container.

    If you are generating video from Java BufferedImage but you don't have an IVideoPicture object handy, don't sweat. You can use encodeVideo(int, BufferedImage, long, TimeUnit) for that.

    If you are generating audio from in Java short arrays (16-bit audio) but don't have an IAudioSamples object handy, don't sweat. You can use encodeAudio(int, short[], long, TimeUnit) for that.

    • Method Detail

      • setForceInterleave

        void setForceInterleave​(boolean forceInterleave)
        Set the force interleave option.

        If false the media data will be left in the order in which it is presented to the IMediaWriter.

        If true IMediaWriter will buffer media data in time stamp order, and only write out data when it has at least one same time or later packet from all streams.

        Parameters:
        forceInterleave - true if the IMediaWriter should force interleaving of media data
        See Also:
        willForceInterleave()
      • isSupportedCodecType

        boolean isSupportedCodecType​(ICodec.Type type)
        Test if this IMediaWriter can write streams of this type.
        Parameters:
        type - the type of codec to be tested
        Returns:
        true if codec type is supported type
      • getDefaultTimebase

        IRational getDefaultTimebase()
        Get the default time base we'll use on our encoders if one is not specified by the codec.
        Returns:
        the default time base
      • addAudioStream

        int addAudioStream​(int inputIndex,
                           int streamId,
                           ICodec.ID codecId,
                           int channelCount,
                           int sampleRate)
        Add an audio stream that will later have data encoded with encodeAudio(int, IAudioSamples).

        The time base defaults to getDefaultTimebase() and the audio format defaults to getDefaultSampleFormat().

        Parameters:
        inputIndex - the index that will be passed to encodeAudio(int, IAudioSamples) for this stream
        streamId - a format-dependent id for this stream
        codecId - the codec id to used to encode data, to establish the codec see ICodec
        channelCount - the number of audio channels for the stream
        sampleRate - sample rate in Hz (samples per seconds), common values are 44100, 22050, 11025, etc.
        Returns:
        <0 on failure; otherwise returns the index of the new stream added by the writer.
        Throws:
        java.lang.IllegalArgumentException - if inputIndex < 0, the stream id < 0, the codec is NULL or if the container is already open.
        java.lang.IllegalArgumentException - if width or height are <= 0
        java.lang.UnsupportedOperationException - if the given codec cannot be used for encoding.
        See Also:
        IContainer, IStream, IStreamCoder, ICodec
      • addAudioStream

        int addAudioStream​(int inputIndex,
                           int streamId,
                           ICodec codec,
                           int channelCount,
                           int sampleRate)
        Add an audio stream that will later have data encoded with encodeAudio(int, IAudioSamples).

        The time base defaults to getDefaultTimebase() and the audio format defaults to getDefaultSampleFormat().

        Parameters:
        inputIndex - the index that will be passed to encodeAudio(int, IAudioSamples) for this stream
        streamId - a format-dependent id for this stream
        codec - the codec to used to encode data, to establish the codec see ICodec
        channelCount - the number of audio channels for the stream
        sampleRate - sample rate in Hz (samples per seconds), common values are 44100, 22050, 11025, etc.
        Returns:
        <0 on failure; otherwise returns the index of the new stream added by the writer.
        Throws:
        java.lang.IllegalArgumentException - if inputIndex < 0, the stream id < 0, the codec is NULL or if the container is already open.
        java.lang.IllegalArgumentException - if width or height are <= 0
        See Also:
        IContainer, IStream, IStreamCoder, ICodec
      • addVideoStream

        int addVideoStream​(int inputIndex,
                           int streamId,
                           ICodec.ID codecId,
                           int width,
                           int height)
        Add a video stream that will later have data encoded with encodeVideo(int, IVideoPicture).

        The time base defaults to getDefaultTimebase() and the pixel format defaults to getDefaultPixelType().

        Parameters:
        inputIndex - the index that will be passed to encodeVideo(int, IVideoPicture) for this stream
        streamId - a format-dependent id for this stream
        codecId - the codec to used to encode data, to establish the codec see ICodec
        width - width of video frames
        height - height of video frames
        Returns:
        <0 on failure; otherwise returns the index of the new stream added by the writer.
        Throws:
        java.lang.IllegalArgumentException - if inputIndex < 0, the stream id < 0, the codec is NULL or if the container is already open.
        java.lang.IllegalArgumentException - if width or height are <= 0
        java.lang.UnsupportedOperationException - if the given codec cannot be used for encoding.
        See Also:
        IContainer, IStream, IStreamCoder, ICodec
      • addVideoStream

        int addVideoStream​(int inputIndex,
                           int streamId,
                           ICodec codec,
                           int width,
                           int height)
        Add a video stream that will later have data encoded with encodeVideo(int, IVideoPicture).

        The time base defaults to getDefaultTimebase() and the pixel format defaults to getDefaultPixelType().

        Parameters:
        inputIndex - the index that will be passed to encodeVideo(int, IVideoPicture) for this stream
        streamId - a format-dependent id for this stream
        codec - the codec to used to encode data, to establish the codec see ICodec
        width - width of video frames
        height - height of video frames
        Returns:
        <0 on failure; otherwise returns the index of the new stream added by the writer.
        Throws:
        java.lang.IllegalArgumentException - if inputIndex < 0, the stream id < 0, the codec is NULL or if the container is already open.
        java.lang.IllegalArgumentException - if width or height are <= 0
        See Also:
        IContainer, IStream, IStreamCoder, ICodec
      • addVideoStream

        int addVideoStream​(int inputIndex,
                           int streamId,
                           ICodec codec,
                           IRational frameRate,
                           int width,
                           int height)
        Add a video stream that will later have data encoded with encodeVideo(int, IVideoPicture).

        The time base defaults to getDefaultTimebase() and the pixel format defaults to getDefaultPixelType().

        Parameters:
        inputIndex - the index that will be passed to encodeVideo(int, IVideoPicture) for this stream
        streamId - a format-dependent id for this stream
        codec - the codec to used to encode data, to establish the codec see ICodec
        frameRate - if non null, then this is the frame-rate you will encode video at. Some codecs (e.g. MPEG2 video) require this to be fixed and will effectively ignore timestamps in favor of this. If you do not specify, we'll guess the highest frame-rate that can fit in the output container, and then try to honor the actual timestamps encoded.
        width - width of video frames
        height - height of video frames
        Returns:
        <0 on failure; otherwise returns the index of the new stream added by the writer.
        Throws:
        java.lang.IllegalArgumentException - if inputIndex < 0, the stream id < 0, the codec is NULL or if the container is already open.
        java.lang.IllegalArgumentException - if width or height are <= 0
        See Also:
        IContainer, IStream, IStreamCoder, ICodec
      • encodeAudio

        void encodeAudio​(int streamIndex,
                         short[] samples)
        Encoded audio from samples into the stream with the specified index.

        IMediaWriter will assume that these samples are to played immediately after the last set of samples, or with the earliest time stamp in the container if they are the first samples.

        Parameters:
        streamIndex - The stream index, as returned from addAudioStream(int, int, ICodec, int, int).
        samples - A set of samples to add.
      • encodeAudio

        void encodeAudio​(int streamIndex,
                         short[] samples,
                         long timeStamp,
                         java.util.concurrent.TimeUnit timeUnit)
        Encoded audio from samples into the stream with the specified index.

        If timeUnit is null, IMediaWriter will assume that these samples are to played immediately after the last set of samples, or with the earliest time stamp in the container if they are the first samples.

        Callers must ensure that timeStamp, if timeUnit is non-null, is always monotonically increasing or an runtime exception will be raised.

        Parameters:
        streamIndex - The stream index, as returned from addAudioStream(int, int, ICodec, int, int).
        samples - A set of samples to add.
        timeStamp - The time stamp for this media.
        timeUnit - The units of timeStamp, or null if you want IMediaWriter to assume these samples immediately precede any prior samples.
      • encodeVideo

        void encodeVideo​(int streamIndex,
                         java.awt.image.BufferedImage image,
                         long timeStamp,
                         java.util.concurrent.TimeUnit timeUnit)
        Encodes video from the given picture into the stream with the specified index.

        Callers must ensure that IMediaData.getTimeStamp(), if specified is always monotonically increasing or an RuntimeException will be raised.

        Parameters:
        streamIndex - The stream index, as returned from addVideoStream(int, int, ICodec, int, int).
        image - A BufferedImage to encode
        timeStamp - The time stamp for this image
        timeUnit - The time unit of timeStamp. Cannot be null.
      • flush

        void flush()
        Flushes all encoders and writes their contents.

        Callers should call this when they have finished encoding all audio and video to ensure that any cached data necessary for encoding was written.

      • getOutputStreamIndex

        java.lang.Integer getOutputStreamIndex​(int inputStreamIndex)
        Map an input stream index to an output stream index.
        Parameters:
        inputStreamIndex - the input stream index value
        Returns:
        the associated output stream index or null, if the input stream index has not been mapped to an output index.