package com.jpexs.decompiler.flash.flv; import java.io.IOException; import java.io.OutputStream; /** * * @author JPEXS */ public class FLVOutputStream extends OutputStream { private OutputStream os; private int bitPos = 0; private int tempByte = 0; private long pos = 0; public FLVOutputStream(OutputStream os) { this.os = os; } public long getPos() { return pos; } /** * Writes byte to the stream * * @param b byte to write * @throws IOException */ @Override public void write(int b) throws IOException { alignByte(); os.write(b); pos++; } private void alignByte() throws IOException { if (bitPos > 0) { bitPos = 0; write(tempByte); tempByte = 0; } } /** * Writes UI8 (Unsigned 8bit integer) value to the stream * * @param val UI8 value to write * @throws IOException */ public void writeUI8(int val) throws IOException { write(val); } /** * Writes UI24 (Unsigned 24bit integer) value to the stream * * @param value UI32 value * @throws IOException */ public void writeUI24(long value) throws IOException { write((int) ((value >> 16) & 0xff)); write((int) ((value >> 8) & 0xff)); write((int) (value & 0xff)); } /** * Writes UI32 (Unsigned 32bit integer) value to the stream * * @param value UI32 value * @throws IOException */ public void writeUI32(long value) throws IOException { write((int) ((value >> 24) & 0xff)); write((int) ((value >> 16) & 0xff)); write((int) ((value >> 8) & 0xff)); write((int) (value & 0xff)); } /** * Writes UI16 (Unsigned 16bit integer) value to the stream * * @param value UI16 value * @throws IOException */ public void writeUI16(int value) throws IOException { write((int) ((value >> 8) & 0xff)); write((int) (value & 0xff)); } /** * Writes UB[nBits] (Unsigned-bit value) value to the stream * * @param nBits Number of bits which represent value * @param value Unsigned value to write * @throws IOException */ public void writeUB(int nBits, long value) throws IOException { for (int bit = 0; bit < nBits; bit++) { int nb = (int) ((value >> (nBits - 1 - bit)) & 1); tempByte += nb * (1 << (7 - bitPos)); bitPos++; if (bitPos == 8) { bitPos = 0; write(tempByte); tempByte = 0; } } } public void writeHeader(boolean audio, boolean video) throws IOException { write("FLV".getBytes()); write(1); //version writeUB(5, 0); //must be 0 writeUB(1, audio ? 1 : 0); //audio present writeUB(1, 0); //reserved writeUB(1, video ? 1 : 0); //video present writeUI32(9); //header size writeUI32(0); } public void writeTag(FLVTAG tag) throws IOException { long posBefore = getPos(); writeUI8(tag.tagType); byte data[] = tag.data.getBytes(); writeUI24(data.length); writeUI24(tag.timeStamp & 0xffffff); writeUI8((int) ((tag.timeStamp >> 24) & 0xff)); writeUI24(0); write(data); long posAfter = getPos(); long size = posAfter - posBefore; writeUI32(size); } }