FLA export - sounds

This commit is contained in:
Jindra Petk
2013-05-17 23:13:20 +02:00
parent c5753013df
commit 3c83eefc5c
8 changed files with 569 additions and 80 deletions

View File

@@ -608,6 +608,56 @@ public class SWF {
exportSounds(outdir, tags, mp3);
}
public byte[] exportSound(Tag t) throws IOException {
boolean mp3 = true;
ByteArrayOutputStream fos = new ByteArrayOutputStream();
int id = 0;
if (t instanceof DefineSoundTag) {
id = ((DefineSoundTag) t).soundId;
}
if (t instanceof DefineSoundTag) {
DefineSoundTag st = (DefineSoundTag) t;
if ((st.soundFormat == DefineSoundTag.FORMAT_MP3) && mp3) {
fos = new ByteArrayOutputStream();
fos.write(st.soundData);
} else {
fos = new ByteArrayOutputStream();
FLVOutputStream flv = new FLVOutputStream(fos);
flv.writeHeader(true, false);
flv.writeTag(new FLVTAG(0, new AUDIODATA(st.soundFormat, st.soundRate, st.soundSize, st.soundType, st.soundData)));
}
}
if (t instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag shead = (SoundStreamHeadTypeTag) t;
List<SoundStreamBlockTag> blocks = new ArrayList<SoundStreamBlockTag>();
List<Object> objs = new ArrayList<Object>(this.tags);
populateSoundStreamBlocks(objs, t, blocks);
if ((shead.getSoundFormat() == 2) && mp3) {
fos = new ByteArrayOutputStream();
for (int b = 0; b < blocks.size(); b++) {
byte data[] = blocks.get(b).getData(SWF.DEFAULT_VERSION);
fos.write(data, 4, data.length - 4);
}
} else {
fos = new ByteArrayOutputStream();
FLVOutputStream flv = new FLVOutputStream(fos);
flv.writeHeader(true, false);
int ms = (int) (1000.0f / ((float) frameRate));
for (int b = 0; b < blocks.size(); b++) {
byte data[] = blocks.get(b).getData(SWF.DEFAULT_VERSION);
if (shead.getSoundFormat() == 2) { //MP3
data = Arrays.copyOfRange(data, 4, data.length);
}
flv.writeTag(new FLVTAG(ms * b, new AUDIODATA(shead.getSoundFormat(), shead.getSoundRate(), shead.getSoundSize(), shead.getSoundType(), data)));
}
}
}
return fos.toByteArray();
}
public void exportSounds(String outdir, List<Tag> tags, boolean mp3) throws IOException {
if (tags.isEmpty()) {
return;
@@ -623,8 +673,7 @@ public class SWF {
if (t instanceof DefineSoundTag) {
id = ((DefineSoundTag) t).soundId;
}
if (mp3) {
}
if (t instanceof DefineSoundTag) {
DefineSoundTag st = (DefineSoundTag) t;

View File

@@ -207,7 +207,7 @@ public class TagNode {
((DefineButton2Tag) ret.get(i).tag).exportAssetsTags = exportAssetsTags;
}
if (ret.get(i).tag instanceof DoInitActionTag) {
((DoInitActionTag) ret.get(i).tag).exportAssetsTags = exportAssetsTags;
//((DoInitActionTag) ret.get(i).tag).exportAssetsTags = exportAssetsTags;
}
if (ret.get(i).tag instanceof ASMSource) {
ASMSource ass = (ASMSource) ret.get(i).tag;

View File

@@ -94,4 +94,16 @@ public class DefineSoundTag extends CharacterTag {
soundSampleCount = sis.readUI32();
soundData = sis.readBytes(sis.available());
}
public String getExportFormat() {
if (soundFormat == FORMAT_MP3) {
return "mp3";
}
return "flv";
}
public double getkHz() {
double rateMap[] = {5.5, 11, 22, 44};
return rateMap[soundRate];
}
}

View File

@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import static com.jpexs.decompiler.flash.tags.DefineSoundTag.FORMAT_MP3;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -28,7 +30,7 @@ import java.io.OutputStream;
*
* @author JPEXS
*/
public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
public class SoundStreamHead2Tag extends CharacterTag implements SoundStreamHeadTypeTag {
public int playBackSoundRate;
public int playBackSoundSize;
@@ -39,6 +41,30 @@ public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
public int streamSoundType;
public int streamSoundSampleCount;
public int latencySeek;
private int virtualCharacterId = 0;
@Override
public int getCharacterID() {
return virtualCharacterId;
}
@Override
public String getExportFormat() {
if (streamSoundCompression == FORMAT_MP3) {
return "mp3";
}
return "flv";
}
@Override
public long getSoundSampleCount() {
return streamSoundSampleCount;
}
@Override
public void setVirtualCharacterId(int ch) {
virtualCharacterId = ch;
}
/**
* Gets data bytes

View File

@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import static com.jpexs.decompiler.flash.tags.DefineSoundTag.FORMAT_MP3;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -28,7 +30,7 @@ import java.io.OutputStream;
*
* @author JPEXS
*/
public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
public class SoundStreamHeadTag extends CharacterTag implements SoundStreamHeadTypeTag {
public int playBackSoundRate;
public int playBackSoundSize;
@@ -39,6 +41,30 @@ public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
public int streamSoundType;
public int streamSoundSampleCount;
public int latencySeek;
private int virtualCharacterId = 0;
@Override
public String getExportFormat() {
if (streamSoundCompression == FORMAT_MP3) {
return "mp3";
}
return "flv";
}
@Override
public int getCharacterID() {
return virtualCharacterId;
}
@Override
public void setVirtualCharacterId(int ch) {
virtualCharacterId = ch;
}
@Override
public long getSoundSampleCount() {
return streamSoundSampleCount;
}
/**
* Gets data bytes

View File

@@ -13,4 +13,12 @@ public interface SoundStreamHeadTypeTag {
public int getSoundSize();
public int getSoundType();
public long getSoundSampleCount();
public void setVirtualCharacterId(int ch);
public int getCharacterID();
public String getExportFormat();
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2013 JPEXS
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.types.sound;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author JPEXS
*/
public class MP3FRAME {
public int syncWord;
public int mpegVersion;
public int layer;
public boolean protectionBit;
public int bitRate;
public int samplingRate;
public boolean paddingBit;
public int reserved;
public int channelMode;
public int modelExtension;
public boolean copyright;
public boolean original;
public int emphasis;
public MP3FRAME(InputStream is) throws IOException {
SWFInputStream sis = new SWFInputStream(is, SWF.DEFAULT_VERSION);
syncWord = (int) sis.readUB(11);
mpegVersion = (int) sis.readUB(2);
layer = (int) sis.readUB(2);
protectionBit = sis.readUB(1) == 1;
bitRate = (int) sis.readUB(4);
samplingRate = (int) sis.readUB(2);
paddingBit = sis.readUB(1) == 1;
reserved = (int) sis.readUB(1);
channelMode = (int) sis.readUB(2);
modelExtension = (int) sis.readUB(2);
//TODO:read sample data
}
public boolean isMPEG2() {
return mpegVersion == 2;
}
public boolean isMPEG1() {
return mpegVersion == 3;
}
public boolean isLayerI() {
return layer == 3;
}
public boolean isLayerII() {
return layer == 2;
}
public boolean isLayerIII() {
return layer == 1;
}
public int getBitrate() {
int v1_l1_map[] = {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1};
int v1_l2_map[] = {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1};
int v1_l3_map[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1};
int v2_l1_map[] = {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1};
int v2_l2l3_map[] = {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1};
int map[][][] = {
{v1_l1_map, v1_l2_map, v1_l3_map},
{v2_l1_map, v2_l2l3_map, v2_l2l3_map}
};
int layer = 0;
if (isLayerI()) {
layer = 0;
}
if (isLayerII()) {
layer = 1;
}
if (isLayerIII()) {
layer = 2;
}
int mver = 0;
if (isMPEG1()) {
mver = 0;
}
if (isMPEG2()) {
mver = 1;
}
return map[mver][layer][bitRate];
}
}

View File

@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.xfl;
import com.jpexs.decompiler.flash.Main;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.helpers.Highlighting;
import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag;
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
@@ -25,6 +26,7 @@ import com.jpexs.decompiler.flash.tags.DefineButtonCxformTag;
import com.jpexs.decompiler.flash.tags.DefineButtonTag;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFontNameTag;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DefineText2Tag;
import com.jpexs.decompiler.flash.tags.DefineTextTag;
@@ -36,6 +38,9 @@ import com.jpexs.decompiler.flash.tags.FrameLabelTag;
import com.jpexs.decompiler.flash.tags.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.StartSoundTag;
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
@@ -63,6 +68,7 @@ import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.SOUNDENVELOPE;
import com.jpexs.decompiler.flash.types.TEXTRECORD;
import com.jpexs.decompiler.flash.types.filters.BEVELFILTER;
import com.jpexs.decompiler.flash.types.filters.BLURFILTER;
@@ -76,6 +82,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
@@ -586,7 +593,20 @@ public class XFLConverter {
private static HashMap<Integer, CharacterTag> getCharacters(List<Tag> tags) {
HashMap<Integer, CharacterTag> ret = new HashMap<Integer, CharacterTag>();
int maxId = 0;
for (Tag t : tags) {
if (t instanceof CharacterTag) {
CharacterTag ct = (CharacterTag) t;
if (ct.getCharacterID() > maxId) {
maxId = ct.getCharacterID();
}
}
}
for (Tag t : tags) {
if (t instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag ssh = (SoundStreamHeadTypeTag) t;
ssh.setVirtualCharacterId(maxId++);
}
if (t instanceof CharacterTag) {
CharacterTag ct = (CharacterTag) t;
ret.put(ct.getCharacterID(), ct);
@@ -958,7 +978,7 @@ public class XFLConverter {
return new Date().getTime() / 1000;
}
public static String convertLibrary(Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files) {
public static String convertLibrary(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files) {
//TODO: Imported assets
//linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf"
@@ -1122,6 +1142,156 @@ public class XFLConverter {
mediaLinkStr += " quality=\"50\" href=\"" + symbolFile + "\" bitmapDataHRef=\"M " + (media.size() + 1) + " " + getTimestamp() + ".dat\" frameRight=\"" + image.getWidth() + "\" frameBottom=\"" + image.getHeight() + "\"/>\n";
media.add(mediaLinkStr);
} else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) {
int soundFormat = 0;
int soundRate = 0;
int soundType = 0;
int soundSize = 0;
long soundSampleCount = 0;
byte soundData[] = new byte[0];
double rateMap[] = {5.5, 11, 22, 44};
String exportFormat = "flv";
if (symbol instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag sstream = (SoundStreamHeadTypeTag) symbol;
soundFormat = sstream.getSoundFormat();
soundRate = sstream.getSoundRate();
soundType = sstream.getSoundType();
soundSize = sstream.getSoundSize();
soundSampleCount = sstream.getSoundSampleCount();
boolean found = false;
for (Tag t : tags) {
if (found && (t instanceof SoundStreamBlockTag)) {
SoundStreamBlockTag bl = (SoundStreamBlockTag) t;
soundData = bl.getData(SWF.DEFAULT_VERSION);
break;
}
if (t == symbol) {
found = true;
}
}
} else if (symbol instanceof DefineSoundTag) {
DefineSoundTag sound = (DefineSoundTag) symbol;
soundFormat = sound.soundFormat;
soundRate = sound.soundRate;
soundType = sound.soundType;
soundData = sound.soundData;
soundSize = sound.soundSize;
soundSampleCount = sound.soundSampleCount;
}
int format = 0;
int bits = 0;
if ((soundFormat == DefineSoundTag.FORMAT_ADPCM)
|| (soundFormat == DefineSoundTag.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN)
|| (soundFormat == DefineSoundTag.FORMAT_UNCOMPRESSED_NATIVE_ENDIAN)) {
if (soundType == 1) { //stereo
format += 1;
}
switch (soundRate) {
case 0:
format += 2;
break;
case 1:
format += 6;
break;
case 2:
format += 10;
break;
case 3:
format += 14;
break;
}
}
if (soundFormat == DefineSoundTag.FORMAT_SPEEX) {
bits = 18;
}
if (soundFormat == DefineSoundTag.FORMAT_ADPCM) {
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(soundData), SWF.DEFAULT_VERSION);
try {
int adpcmCodeSize = (int) sis.readUB(2);
bits = 2 + adpcmCodeSize;
} catch (IOException ex) {
Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (soundFormat == DefineSoundTag.FORMAT_MP3) {
exportFormat = "mp3";
if (soundType == 0) { //mono
format += 1;
}
format += 4; //quality best
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(soundData), SWF.DEFAULT_VERSION);
try {
sis.readSI16();
MP3FRAME frame = new MP3FRAME(sis);
int bitRate = frame.getBitrate();
switch (bitRate) {
case 8:
bits = 6;
break;
case 16:
bits = 7;
break;
case 20:
bits = 8;
break;
case 24:
bits = 9;
break;
case 32:
bits = 10;
break;
case 48:
bits = 11;
break;
case 56:
bits = 12;
break;
case 64:
bits = 13;
break;
case 80:
bits = 14;
break;
case 112:
bits = 15;
break;
case 128:
bits = 16;
break;
case 160:
bits = 17;
break;
}
} catch (IOException ex) {
Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, null, ex);
}
}
byte data[] = new byte[0];
try {
data = swf.exportSound(symbol);
} catch (IOException ex) {
Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, null, ex);
}
String symbolFile = "sound" + symbol.getCharacterID() + "." + exportFormat;
files.put(symbolFile, data);
String mediaLinkStr = "<DOMSoundItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp() + "\" externalFileSize=\"" + data.length + "\"";
mediaLinkStr += " format=\"";
mediaLinkStr += rateMap[soundRate] + "kHz";
mediaLinkStr += " " + (soundSize == 1 ? "16bit" : "8bit");
mediaLinkStr += " " + (soundType == 1 ? "Stereo" : "Mono");
mediaLinkStr += "\"";
mediaLinkStr += " exportFormat=\"" + format + "\" exportBits=\"" + bits + "\" sampleCount=\"" + soundSampleCount + "\"";
if (characterClasses.containsKey(symbol.getCharacterID())) {
mediaLinkStr += " linkageExportForAS=\"true\" linkageClassName=\"" + characterClasses.get(symbol.getCharacterID()) + "\"";
}
mediaLinkStr += "/>\n";
media.add(mediaLinkStr);
}
//TODO: sound, video...
}
@@ -1161,6 +1331,122 @@ public class XFLConverter {
}
}
private static String convertFrame(HashMap<Integer, CharacterTag> characters, List<Tag> tags, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, String frameName, boolean isAnchor, int duration, String actionScript, String elements) {
String ret = "";
DefineSoundTag sound = null;
if (startSound != null) {
for (Tag t : tags) {
if (t instanceof DefineSoundTag) {
DefineSoundTag s = (DefineSoundTag) t;
if (s.soundId == startSound.soundId) {
sound = s;
break;
}
}
}
}
ret += "<DOMFrame index=\"" + (frame) + "\"";
if (duration > 1) {
ret += " duration=\"" + duration + "\"";
}
if (frameName != null) {
ret += " name=\"" + frameName + "\"";
if (isAnchor) {
ret += " labelType=\"anchor\" bookmark=\"true\"";
} else {
ret += " labelType=\"name\"";
}
isAnchor = false;
frameName = null;
}
ret += " keyMode=\"" + KEY_MODE_NORMAL + "\"";
String soundEnvelopeStr = "";
if (soundStreamHead != null) {
ret += " soundName=\"sound" + soundStreamHead.getCharacterID() + "." + soundStreamHead.getExportFormat() + "\"";
ret += " soundSync=\"stream\"";
soundEnvelopeStr += "<SoundEnvelope>";
soundEnvelopeStr += "<SoundEnvelopePoint level0=\"32768\" level1=\"32768\"/>";
soundEnvelopeStr += "</SoundEnvelope>";
}
if (startSound != null) {
ret += " soundName=\"sound" + sound.soundId + "." + sound.getExportFormat() + "\"";
if (startSound.soundInfo.hasInPoint) {
ret += " inPoint44=\"" + startSound.soundInfo.inPoint + "\"";
}
if (startSound.soundInfo.hasOutPoint) {
ret += " outPoint44=\"" + startSound.soundInfo.outPoint + "\"";
}
if (startSound.soundInfo.hasLoops) {
if (startSound.soundInfo.loopCount == 32767) {
ret += " soundLoopMode=\"loop\"";
}
ret += " soundLoop=\"" + startSound.soundInfo.loopCount + "\"";
}
if (!startSound.soundInfo.syncNoMultiple && !startSound.soundInfo.syncStop) {
//event
} else if (startSound.soundInfo.syncNoMultiple && !startSound.soundInfo.syncStop) {
ret += " soundSync=\"start\"";
}
soundEnvelopeStr += "<SoundEnvelope>";
if (startSound.soundInfo.hasEnvelope) {
for (SOUNDENVELOPE env : startSound.soundInfo.envelopeRecords) {
soundEnvelopeStr += "<SoundEnvelopePoint mark44=\"" + env.pos44 + "\" level0=\"" + env.leftLevel + "\" level1=\"" + env.rightLevel + "\"/>";
}
if (startSound.soundInfo.envelopeRecords.length == 1
&& startSound.soundInfo.envelopeRecords[0].leftLevel == 32768
&& startSound.soundInfo.envelopeRecords[0].pos44 == 0
&& startSound.soundInfo.envelopeRecords[0].rightLevel == 0) {
ret += " soundEffect=\"left channel\"";
} else if (startSound.soundInfo.envelopeRecords.length == 1
&& startSound.soundInfo.envelopeRecords[0].leftLevel == 0
&& startSound.soundInfo.envelopeRecords[0].pos44 == 0
&& startSound.soundInfo.envelopeRecords[0].rightLevel == 32768) {
ret += " soundEffect=\"right channel\"";
} else if (startSound.soundInfo.envelopeRecords.length == 2
&& startSound.soundInfo.envelopeRecords[0].leftLevel == 32768
&& startSound.soundInfo.envelopeRecords[0].pos44 == 0
&& startSound.soundInfo.envelopeRecords[0].rightLevel == 0
&& startSound.soundInfo.envelopeRecords[1].leftLevel == 0
&& startSound.soundInfo.envelopeRecords[1].pos44 == sound.soundSampleCount
&& startSound.soundInfo.envelopeRecords[1].rightLevel == 32768) {
ret += " soundEffect=\"fade left to right\"";
} else if (startSound.soundInfo.envelopeRecords.length == 2
&& startSound.soundInfo.envelopeRecords[0].leftLevel == 0
&& startSound.soundInfo.envelopeRecords[0].pos44 == 0
&& startSound.soundInfo.envelopeRecords[0].rightLevel == 32768
&& startSound.soundInfo.envelopeRecords[1].leftLevel == 32768
&& startSound.soundInfo.envelopeRecords[1].pos44 == sound.soundSampleCount
&& startSound.soundInfo.envelopeRecords[1].rightLevel == 0) {
ret += " soundEffect=\"fade right to left\"";
} else {
ret += " soundEffect=\"custom\"";
}
//TODO: fade in, fade out
} else {
soundEnvelopeStr += "<SoundEnvelopePoint level0=\"32768\" level1=\"32768\"/>";
}
soundEnvelopeStr += "</SoundEnvelope>";
}
ret += ">";
ret += soundEnvelopeStr;
if (!actionScript.equals("")) {
ret += "<ActionScript><script><![CDATA[";
ret += actionScript;
ret += "]]></script></ActionScript>";
}
ret += "<elements>";
ret += elements;
ret += "</elements>";
ret += "</DOMFrame>";
return ret;
}
private static String convertFrames(String initActionScript, String prevStr, String afterStr, List<Integer> oneInstanceShapes, List<Tag> tags, HashMap<Integer, CharacterTag> characters, int depth) {
String ret = "";
prevStr += "<frames>";
@@ -1173,6 +1459,8 @@ public class XFLConverter {
String lastActionScript = "";
String frameName = null;
boolean isAnchor = false;
StartSoundTag startSound = null;
SoundStreamHeadTypeTag soundStreamHead = null;
for (Tag t : tags) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
@@ -1194,75 +1482,68 @@ public class XFLConverter {
}
}
}
if (t instanceof StartSoundTag) {
if (startSound != null) {
lastActionScript = initActionScript + lastActionScript;
initActionScript = "";
ret += convertFrame(characters, tags, soundStreamHead, startSound, frame, frameName, isAnchor, duration, lastActionScript, lastElements);
frame += duration;
duration = 1;
lastElements = elements;
lastActionScript = actionScript;
elements = "";
actionScript = "";
frameName = null;
isAnchor = false;
soundStreamHead = null;
}
startSound = (StartSoundTag) t;
}
if (t instanceof SoundStreamHeadTypeTag) {
if (soundStreamHead != null) {
lastActionScript = initActionScript + lastActionScript;
initActionScript = "";
ret += convertFrame(characters, tags, soundStreamHead, startSound, frame, frameName, isAnchor, duration, lastActionScript, lastElements);
frame += duration;
duration = 1;
lastElements = elements;
lastActionScript = actionScript;
elements = "";
actionScript = "";
frameName = null;
isAnchor = false;
startSound = null;
soundStreamHead = null;
}
soundStreamHead = (SoundStreamHeadTypeTag) t;
}
if (t instanceof DoActionTag) {
actionScript += convertActionScript((DoActionTag) t);
}
if (t instanceof FrameLabelTag) {
FrameLabelTag flt = (FrameLabelTag) t;
if (frameName != null) {
ret += "<DOMFrame index=\"" + (frame) + "\"";
if (duration > 1) {
ret += " duration=\"" + duration + "\"";
}
ret += " name=\"" + frameName + "\"";
if (isAnchor) {
ret += " labelType=\"anchor\" bookmark=\"true\"";
} else {
ret += " labelType=\"name\"";
}
ret += " keyMode=\"" + KEY_MODE_NORMAL + "\">";
lastActionScript = initActionScript + lastActionScript;
initActionScript = "";
if (!lastActionScript.equals("")) {
ret += "<ActionScript><script><![CDATA[";
ret += lastActionScript;
ret += "]]></script></ActionScript>";
}
ret += "<elements>";
ret += lastElements;
ret += "</elements>";
ret += "</DOMFrame>";
ret += convertFrame(characters, tags, soundStreamHead, startSound, frame, frameName, isAnchor, duration, lastActionScript, lastElements);
frame += duration;
duration = 1;
lastElements = elements;
lastActionScript = actionScript;
elements = "";
actionScript = "";
startSound = null;
soundStreamHead = null;
}
frameName = flt.getLabelName();
isAnchor = flt.isNamedAnchor();
}
if (t instanceof ShowFrameTag) {
if (!elements.equals("") || !actionScript.equals("")) {
if (!elements.equals("") || !actionScript.equals("") || soundStreamHead != null || startSound != null) {
if (!lastElements.equals("") || !lastActionScript.equals("")) {
ret += "<DOMFrame index=\"" + (frame) + "\"";
if (duration > 1) {
ret += " duration=\"" + duration + "\"";
}
if (frameName != null) {
ret += " name=\"" + frameName + "\"";
if (isAnchor) {
ret += " labelType=\"anchor\" bookmark=\"true\"";
} else {
ret += " labelType=\"name\"";
}
isAnchor = false;
frameName = null;
}
ret += " keyMode=\"" + KEY_MODE_NORMAL + "\">";
lastActionScript = initActionScript + lastActionScript;
initActionScript = "";
if (!lastActionScript.equals("")) {
ret += "<ActionScript><script><![CDATA[";
ret += lastActionScript;
ret += "]]></script></ActionScript>";
}
ret += "<elements>";
ret += lastElements;
ret += "</elements>";
ret += "</DOMFrame>";
ret += convertFrame(characters, tags, soundStreamHead, startSound, frame, frameName, isAnchor, duration, lastActionScript, lastElements);
}
frame += duration;
duration = 1;
@@ -1270,6 +1551,8 @@ public class XFLConverter {
lastActionScript = actionScript;
elements = "";
actionScript = "";
soundStreamHead = null;
startSound = null;
} else {
duration++;
}
@@ -1277,36 +1560,12 @@ public class XFLConverter {
}
lastActionScript = initActionScript + lastActionScript;
initActionScript = "";
if (!lastElements.equals("") || !lastActionScript.equals("")) {
if (!lastElements.equals("") || !lastActionScript.equals("") || soundStreamHead != null || startSound != null) {
if (frame < 0) {
frame = 0;
duration = 1;
}
ret += "<DOMFrame index=\"" + frame + "\"";
if (frameName != null) {
ret += " name=\"" + frameName + "\"";
if (isAnchor) {
ret += " labelType=\"anchor\" bookmark=\"true\"";
} else {
ret += " labelType=\"name\"";
}
}
if (duration > 1) {
ret += " duration=\"" + duration + "\"";
}
ret += " keyMode=\"" + KEY_MODE_NORMAL + "\">";
if (!lastActionScript.equals("")) {
ret += "<ActionScript><script><![CDATA[";
ret += lastActionScript;
ret += "]]></script></ActionScript>";
}
ret += "<elements>";
ret += lastElements;
ret += "</elements>";
ret += "</DOMFrame>";
frame += duration;
duration = 1;
elements = "";
ret += convertFrame(characters, tags, soundStreamHead, startSound, frame, frameName, isAnchor, duration, lastActionScript, lastElements);
}
afterStr = "</frames>" + afterStr;
@@ -1699,7 +1958,7 @@ public class XFLConverter {
domDocument += " frameRate=\"" + swf.frameRate + "\"";
domDocument += ">";
domDocument += convertLibrary(characterVariables, characterClasses, oneInstaceShapes, backgroundColor, swf.tags, characters, files);
domDocument += convertLibrary(swf, characterVariables, characterClasses, oneInstaceShapes, backgroundColor, swf.tags, characters, files);
domDocument += "<timelines>";
domDocument += convertTimeline("", oneInstaceShapes, backgroundColor, swf.tags, characters, "Scene 1");
domDocument += "</timelines>";