/* Milenia Grafter Server Copyright (c) 2007-2008 by Milan Toth. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package com.milgra.server; /** StreamWriter class @mail milgra@milgra.com @author Milan Toth @version 20080316 Tasks of Streamwriter - create a file for writing a stream - write incoming chunks into the file **/ import java.io.File; import java.io.IOException; import java.io.FileOutputStream; import java.io.BufferedOutputStream; public class StreamWriter { public int last = 0; public int stamp = 0; public int start = -1; public BufferedOutputStream stream; /** * Creates a streamwriter instance, creates the file based on streamID * @param streamID String */ public StreamWriter ( String idX , boolean appendX ) { // System.out.println( System.currentTimeMillis( ) + " StreamWriter.construct " + idX + " " + appendX ); try { File file; FileOutputStream fileStream; // open file file = new File( Library.STREAMDIR , idX + ".flv"); // if file exists and mode is not append, delete file if ( file.exists( ) && !appendX ) file.delete( ); // if file doesn't exist, create file if ( !file.exists( ) ) file.createNewFile( ); // init io streams fileStream = new FileOutputStream( file , true ); stream = new BufferedOutputStream( fileStream ); if ( file.length( ) == 0 ) { // write flv header stream.write( 0x46 ); // F stream.write( 0x4C ); // L stream.write( 0x56 ); // V stream.write( 0x01 ); // version stream.write( 0x05 ); // type : audio and video stream.write( 0 ); stream.write( 0 ); stream.write( 0 ); stream.write( 0x09 ); // header length, always 9 // flush data stream.flush( ); } else { // !!! get last timestamp } } catch ( IOException exception ) { System.out.println( Library.FILEEX ); exception.printStackTrace( ); } } /** * Adds new rtmp packet to the file * @param packetX RtmpPacket with a chunk */ public void addPacket ( RtmpPacket packetX ) { // System.out.println( System.currentTimeMillis( ) + " StreamWriter.addPacket " + packetX.flvStamp ); try { // if first packet, get start time if ( start == -1 ) start = ( int ) System.currentTimeMillis( ); // calculate stamp from beginning stamp = ( int ) ( System.currentTimeMillis( ) - start ); // add previous chunk size stream.write( last >> 24 ); stream.write( last >> 16 ); stream.write( last >> 8 ); stream.write( last ); // create chunk header stream.write( packetX.bodyType ); // 0x09 video 0x08 audio // body size on three bytes stream.write( packetX.bodySize >> 16 ); stream.write( packetX.bodySize >> 8 ); stream.write( packetX.bodySize ); // body stamp in milliseconds stream.write( stamp >> 16 ); stream.write( stamp >> 8 ); stream.write( stamp ); // timestamp extension stream.write( 0 ); // streamid stream.write( 0 ); stream.write( 0 ); stream.write( 0 ); // add chunk body and flush stream.write( packetX.body ); stream.flush( ); // store chunk size without the chunk size bytes last = packetX.bodySize + 11; } catch ( IOException exception ) { System.out.println( Library.FILEEX ); exception.printStackTrace( ); } } /** * Closes the file */ public void close ( ) { // System.out.println( System.currentTimeMillis( ) + " StreamWriter.closeStream" ); try { stream.flush( ); stream.close( ); } catch ( IOException exception ) { System.out.println( Library.FILEEX ); exception.printStackTrace( ); } } }