org.jcodec.movtool.streaming.tracks.WavTrack Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcodec Show documentation
Show all versions of jcodec Show documentation
Pure Java implementation of video/audio codecs and formats
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;
}
}
}