⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavdocumentfactory.java

📁 java解析flash。对于flash在java上应用非常有帮助。比如解析flash到服务器端
💻 JAVA
字号:
/*
 * JSwiff is an open source Java API for Macromedia Flash file generation
 * and manipulation
 *
 * Copyright (C) 2004-2008 Ralf Terdic (contact@jswiff.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package com.jswiff.hl.factories;

import com.jswiff.SWFDocument;
import com.jswiff.SWFWriter;
import com.jswiff.io.InputBitStream;
import com.jswiff.swfrecords.SoundInfo;
import com.jswiff.swfrecords.tags.DefineSound;
import com.jswiff.swfrecords.tags.ShowFrame;
import com.jswiff.swfrecords.tags.SoundStreamHead2;
import com.jswiff.swfrecords.tags.StartSound;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;


/**
 * Creates a document including an uncompressed wav sound file.
 *
 * @author <a href="mailto:ralf@terdic.de">Ralf Terdic</a>
 */
public class WAVDocumentFactory {
  private static final int WAVE_FORMAT_DESCRIPTOR   = 0x45564157;
  private static final int RIFF_CHUNK_DESCRIPTOR    = 0x46464952;
  private static final int FMT_SUBCHUNK_DESCRIPTOR  = 0x20746d66;
  private static final int DATA_SUBCHUNK_DESCRIPTOR = 0x61746164;
  private InputBitStream wavBitStream;
  private byte[] soundData;
  private SWFDocument doc;
  private int sampleCount;
  private int sampleSize;
  private int channelCount;
  private int samplingRate;
  private boolean is16BitSample;

  /**
   * <p>
   * Creates a new WAVDocumentFactory instance. The passed AudioInputStream is
   * converted to a linear PCM WAV (so you may be able to use other formats
   * like .au). Sample rates of 5512, 11025, 22050 and 44100 Hz are supported.
   * </p>
   * 
   * <p>
   * Note: you can use the following to get an AudioInputStream:
   * </p>
   * <code> AudioInputStream audioInputStream =
   * AudioSystem.getAudioInputStream((bufferedInputStream)); </code>
   *
   * @param audioInputStream audio input stream
   *
   * @throws IOException if something went wrong while reading from the audio
   *         stream
   */
  public WAVDocumentFactory(AudioInputStream audioInputStream)
    throws IOException {
    audioInputStream = AudioSystem.getAudioInputStream(
        AudioFormat.Encoding.PCM_SIGNED, audioInputStream);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, baos);
    byte[] buffer = baos.toByteArray();
    wavBitStream = new InputBitStream(new ByteArrayInputStream(buffer));
  }

  /**
   * Creates a new WAVDocumentFactory instance. Sample rates of 5512, 11025,
   * 22050 and 44100 kHz are supported.
   *
   * @param wavStream WAV input stream
   */
  public WAVDocumentFactory(InputStream wavStream) {
    wavBitStream = new InputBitStream(wavStream);
  }

  /**
   * Returns the created document.
   *
   * @return SWF doc
   *
   * @throws IOException if an error occured during parsing the wav stream
   */
  public SWFDocument getDocument() throws IOException {
    initDocument();
    return doc;
  }

  /**
   * Changes the sampling rate of an audio input stream.
   *
   * @param audioInputStream source stream
   * @param sampleRate new sampling rate
   *
   * @return altered stream
   */
  public static AudioInputStream convertSampleRate(
    AudioInputStream audioInputStream, float sampleRate) {
    AudioFormat sourceFormat = audioInputStream.getFormat();
    AudioFormat targetFormat = new AudioFormat(
        sourceFormat.getEncoding(), sampleRate,
        sourceFormat.getSampleSizeInBits(), sourceFormat.getChannels(),
        sourceFormat.getFrameSize(), sampleRate, sourceFormat.isBigEndian());
    return AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
  }

  /**
   * Main method for quick tests, pass input file (wav) and output file (swf).
   *
   * @param args wav, swf files
   *
   * @throws IOException if an I/O error occured
   * @throws UnsupportedAudioFileException
   */
  public static void main(String[] args)
    throws IOException, UnsupportedAudioFileException {
    String wavFileName                 = args[0];
    String swfFileName                 = args[1];
    WAVDocumentFactory documentFactory;
    if (wavFileName.toLowerCase().endsWith("wav")) {
      documentFactory = new WAVDocumentFactory(
          new FileInputStream(wavFileName));
    } else {
      documentFactory = new WAVDocumentFactory(
          AudioSystem.getAudioInputStream(
            new BufferedInputStream(new FileInputStream(wavFileName), 1024)));
    }

    SWFDocument document = documentFactory.getDocument();
    SWFWriter writer     = new SWFWriter(
        document, new FileOutputStream(swfFileName));
    writer.write();
  }

  private byte getSamplingRateCode() throws IOException {
    switch (samplingRate) {
      case 5512:
        return 0;
      case 11025:
        return 1;
      case 22050:
        return 2;
      case 44100:
        return 3;
      default:
        throw new IOException("Unsupported sampling rate: " + samplingRate);
    }
  }

  private void initDocument() throws IOException {
    doc = new SWFDocument();
    doc.setCompressed(true);
    readData();
    doc.addTag(
      new SoundStreamHead2(
        SoundStreamHead2.FORMAT_UNCOMPRESSED, getSamplingRateCode(),
        is16BitSample, (channelCount == 2), 0));
    int soundId = doc.getNewCharacterId();
    doc.addTag(
      new DefineSound(
        soundId, DefineSound.FORMAT_UNCOMPRESSED, getSamplingRateCode(),
        is16BitSample, (channelCount == 2), sampleCount, soundData));
    doc.addTag(new StartSound(soundId, new SoundInfo()));
    doc.addTag(new ShowFrame());
  }

  private void readData() throws IOException {
    if (wavBitStream.readUI32() != RIFF_CHUNK_DESCRIPTOR) {
      throw new IOException(
        "Illegal WAV format, RIFF chunk descriptor missing!");
    }
    wavBitStream.readUI32(); // chunk size
    if (wavBitStream.readUI32() != WAVE_FORMAT_DESCRIPTOR) {
      throw new IOException(
        "Illegal WAV format, WAVE format descriptor missing!");
    }
    boolean dataSubchunkFound = false;
    while (!dataSubchunkFound) {
      long subchunkID     = wavBitStream.readUI32();
      long subchunkSize   = wavBitStream.readUI32();
      byte[] subchunkData = wavBitStream.readBytes((int) subchunkSize);
      if (subchunkID == FMT_SUBCHUNK_DESCRIPTOR) {
        readFMTSubchunk(subchunkData);
      } else if (subchunkID == DATA_SUBCHUNK_DESCRIPTOR) {
        soundData           = subchunkData;
        sampleCount         = (int) ((subchunkSize * 8) / (sampleSize * channelCount));
        dataSubchunkFound   = true;
      }
    }
  }

  private void readFMTSubchunk(byte[] subchunkData) throws IOException {
    InputBitStream fmtBitStream = new InputBitStream(subchunkData);
    int format                  = fmtBitStream.readUI16();
    if (format != 1) {
      throw new IOException(
        "Compressed WAV found, only linear quantization (PCM) supported!");
    }
    channelCount   = fmtBitStream.readUI16();
    samplingRate   = (int) fmtBitStream.readUI32();
    fmtBitStream.readUI32(); // byte rate
    fmtBitStream.readUI16(); // block align
    sampleSize      = fmtBitStream.readUI16();
    is16BitSample   = (sampleSize == 16); // || (chunkFormat != 1)
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -