All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcodec.movtool.streaming.tracks.WavTrack Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package org.jcodec.movtool.streaming.tracks;
import java.lang.IllegalStateException;
import java.lang.System;


import org.jcodec.codecs.wav.WavHeader;
import org.jcodec.common.AudioCodecMeta;
import org.jcodec.common.AudioFormat;
import org.jcodec.common.CodecMeta;
import org.jcodec.common.io.IOUtils;
import org.jcodec.common.io.NIOUtils;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.model.Label;
import org.jcodec.movtool.streaming.VirtualPacket;
import org.jcodec.movtool.streaming.VirtualTrack;

import static org.jcodec.common.io.IOUtils.closeQuietly;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * Reads data from a wave file
 * 
 * @author The JCodec project
 * 
 */
public class WavTrack implements VirtualTrack {

    public static final int FRAMES_PER_PKT = 1024;

    private ByteChannelPool pool;
    private WavHeader header;
    private AudioCodecMeta se;
    private int pktDataLen;
    private double pktDuration;

    private long offset;

    private double pts;

    private int frameNo;

    private long size;

    public WavTrack(ByteChannelPool pool, Label[] labels) throws IOException {
        this.pool = pool;

        SeekableByteChannel ch = null;
        try {
            ch = pool.getChannel();
            header = WavHeader.readChannel(ch);
            size = header.dataSize <= 0 ? ch.size() : header.dataSize;
        } finally {
            closeQuietly(ch);
        }

        se = AudioCodecMeta.createAudioCodecMeta3("sowt", ByteBuffer.allocate(0), new AudioFormat(header.fmt.sampleRate,
                header.fmt.bitsPerSample >> 3, header.fmt.numChannels, true, false), true, labels);

        pktDataLen = FRAMES_PER_PKT * header.fmt.numChannels * (header.fmt.bitsPerSample >> 3);
        pktDuration = (double) FRAMES_PER_PKT / header.fmt.sampleRate;

        offset = header.dataOffset;
        pts = 0;
        frameNo = 0;
    }

    @Override
    public VirtualPacket nextPacket() throws IOException {
        if (offset >= size)
            return null;

        WavPacket pkt = new WavPacket(this, frameNo, pts, offset, (int) Math.min(size - offset, pktDataLen));

        offset += pktDataLen;
        frameNo += FRAMES_PER_PKT;
        pts = (double) frameNo / header.fmt.sampleRate;

        return pkt;
    }

    @Override
    public CodecMeta getCodecMeta() {
        return se;
    }

    @Override
    public VirtualEdit[] getEdits() {
        return null;
    }

    @Override
    public int getPreferredTimescale() {
        return header.fmt.sampleRate;
    }

    @Override
    public void close() throws IOException {
        pool.close();
    }

    public static class WavPacket implements VirtualPacket {
        private int frameNo;
        private double pts;
        private long offset;
        private int dataLen;
		private WavTrack track;

        public WavPacket(WavTrack track, int frameNo, double pts, long offset, int dataLen) {
            this.track = track;
			this.frameNo = frameNo;
            this.pts = pts;
            this.offset = offset;
            this.dataLen = dataLen;
        }

        @Override
        public ByteBuffer getData() throws IOException {
            SeekableByteChannel ch = null;
            try {
                ch = track.pool.getChannel();
                ch.setPosition(offset);
                ByteBuffer buffer = ByteBuffer.allocate(dataLen);
                NIOUtils.readFromChannel(ch, buffer);
                buffer.flip();
                return buffer;
            } finally {
                closeQuietly(ch);
            }
        }

        @Override
        public int getDataLen() throws IOException {
            return dataLen;
        }

        @Override
        public double getPts() {
            return pts;
        }

        @Override
        public double getDuration() {
            return track.pktDuration;
        }

        @Override
        public boolean isKeyframe() {
            return true;
        }

        @Override
        public int getFrameNo() {
            return frameNo;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy