/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under GNU GENERAL PUBLIC LICENSE Version 3. */ package com.ttProject.xuggle.flv.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import javax.sound.sampled.AudioFormat; import org.apache.log4j.Logger; import org.junit.Test; import com.ttProject.media.flv.Tag; import com.ttProject.media.raw.AudioData; import com.ttProject.xuggle.flv.FlvDepacketizer; import com.ttProject.xuggle.flv.FlvPacketizer; import com.ttProject.xuggle.raw.AudioConverter; import com.xuggle.xuggler.IAudioSamples; import com.xuggle.xuggler.ICodec; import com.xuggle.xuggler.IPacket; import com.xuggle.xuggler.IStreamCoder; import com.xuggle.xuggler.IStreamCoder.Direction; /** * エンコードとデコードを複合させるテスト * @author taktod */ public class DecodeEncodeTest { private Logger logger = Logger.getLogger(DecodeEncodeTest.class); private int audioCounter = 0; /** * ラの音のaudioデータをつくって応答する。 * @return */ public AudioData audioData() { // とりあえずラの音で1024サンプル数つくることにする。 int samplingRate = 44100; int tone = 440; int bit = 16; int channels = 2; int samplesNum = 1024; // 1024サンプル + 16bit + 2channels / (byte化) ByteBuffer buffer = ByteBuffer.allocate((int)samplesNum * bit * channels / 8); double rad = tone * 2 * Math.PI / samplingRate; // 各deltaごとの回転数 double max = (1 << (bit - 2)) - 1; // 振幅の大きさ(音の大きさ) buffer.order(ByteOrder.LITTLE_ENDIAN); // xuggleで利用するデータはlittleEndianなのでlittleEndianを使うようにする。 for(int i = 0;i < samplesNum / 8;i ++, audioCounter ++) { short data = (short)(Math.sin(rad * audioCounter) * max); for(int j = 0;j < channels;j ++) { buffer.putShort(data); } } buffer.flip(); return new AudioData(new AudioFormat(44100, bit, channels, true, false), buffer); } @Test public void test() { audioCounter = 0; AudioConverter converter = new AudioConverter(); try { IStreamCoder encoder1 = IStreamCoder.make(Direction.ENCODING, ICodec.ID.CODEC_ID_MP3); encoder1.setSampleRate(44100); encoder1.setChannels(2); encoder1.setBitRate(96000); if(encoder1.open(null, null) < 0) { throw new Exception("変換コーダーが開けませんでした。"); } int index = 0; FlvDepacketizer depacketizer = new FlvDepacketizer(); FlvPacketizer packetizer = new FlvPacketizer(); IStreamCoder decoder = null; while(index < 2000) { index ++; AudioData audioData = audioData(); IAudioSamples samples = converter.makeSamples(audioData); IPacket packet = IPacket.make(); int samplesConsumed = 0; while(samplesConsumed < samples.getNumSamples()) { int retval = encoder1.encodeAudio(packet, samples, samplesConsumed); if(retval < 0) { throw new Exception("変換失敗1"); } samplesConsumed += retval; // ここまででpacketができている。 if(packet.isComplete()) { for(Tag tag : depacketizer.getTag(encoder1, packet)) { logger.info(tag); // ここからこのデータをデコードする IPacket pkt = packetizer.getPacket(tag, null); if(pkt == null) { continue; } if(decoder == null) { decoder = packetizer.createAudioDecoder(); } IAudioSamples as = IAudioSamples.make(1024, decoder.getChannels()); int offset = 0; while(offset < pkt.getSize()) { int bytesDecoded = decoder.decodeAudio(as, pkt, offset); if(bytesDecoded < 0) { throw new Exception("変換失敗2"); } offset += bytesDecoded; if(samples.isComplete()) { logger.info(samples); } } } } // mp3ができあがっているはずなので、デコードに回す } } } catch (Exception e) { e.printStackTrace(); } } }