mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-21 17:05:41 +00:00
Added GFX - DefineExternalSound and DefineExternalStreamSound playback
This commit is contained in:
@@ -30,6 +30,8 @@ import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalSound;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
@@ -141,7 +143,7 @@ public class SoundExporter {
|
||||
fos.write(data.getRangeData());
|
||||
}
|
||||
} else if ((nativeFormat == SoundExportFormat.FLV && mode.hasFlv()) || mode == SoundExportMode.FLV) {
|
||||
if (st instanceof DefineSoundTag) {
|
||||
if ((st instanceof DefineSoundTag)||(st instanceof DefineExternalSound)||(st instanceof DefineExternalStreamSound)){
|
||||
FLVOutputStream flv = new FLVOutputStream(fos);
|
||||
flv.writeHeader(true, false);
|
||||
List<ByteArrayRange> datas = st.getRawSoundData();
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
@@ -369,7 +370,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (Tag t : getTags()) {
|
||||
if ((t instanceof CharacterIdTag) && !(t instanceof SoundStreamHeadTypeTag)) {
|
||||
if ((t instanceof CharacterIdTag) && !(t instanceof SoundStreamHeadTypeTag) && !(t instanceof DefineExternalStreamSound)) {
|
||||
needed.add(((CharacterIdTag) t).getCharacterId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,11 +171,6 @@ public class SoundStreamHead2Tag extends SoundStreamHeadTypeTag {
|
||||
return streamSoundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return streamSoundCompression;
|
||||
@@ -206,7 +201,7 @@ public class SoundStreamHead2Tag extends SoundStreamHeadTypeTag {
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -176,11 +176,6 @@ public class SoundStreamHeadTag extends SoundStreamHeadTypeTag {
|
||||
virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVirtualCharacterId(int ch) {
|
||||
virtualCharacterId = ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSoundSampleCount() {
|
||||
return streamSoundSampleCount;
|
||||
@@ -216,7 +211,7 @@ public class SoundStreamHeadTag extends SoundStreamHeadTypeTag {
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,35 +16,11 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -61,8 +37,6 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT
|
||||
|
||||
public abstract long getSoundSampleCount();
|
||||
|
||||
public abstract void setVirtualCharacterId(int ch);
|
||||
|
||||
public abstract List<SoundStreamBlockTag> getBlocks();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,16 +19,31 @@ package com.jpexs.decompiler.flash.tags.gfx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineExternalSound extends CharacterTag {
|
||||
public class DefineExternalSound extends CharacterTag implements SoundTag {
|
||||
|
||||
public static final int ID = 1006;
|
||||
|
||||
@@ -84,7 +99,7 @@ public class DefineExternalSound extends CharacterTag {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
public DefineExternalSound(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
exportName = "";
|
||||
@@ -114,4 +129,107 @@ public class DefineExternalSound extends CharacterTag {
|
||||
public void setCharacterId(int characterId) {
|
||||
this.characterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundExportFormat getExportFormat() {
|
||||
return SoundExportFormat.WAV; //?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
switch ((int) sampleRate) {
|
||||
case 5512:
|
||||
return 0;
|
||||
case 11025:
|
||||
return 1;
|
||||
case 22050:
|
||||
return 2;
|
||||
case 44100:
|
||||
return 3;
|
||||
}
|
||||
return -1; //?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return channels == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
Path soundPath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName));
|
||||
if (soundPath == null || !soundPath.toFile().exists()) {
|
||||
ret.add(new ByteArrayRange(new byte[]{}));
|
||||
return ret;
|
||||
}
|
||||
try (FileInputStream fis = new FileInputStream(soundPath.toFile()); AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(fis))) {
|
||||
ret.add(new ByteArrayRange(Helper.readStream(audioIs)));
|
||||
return ret;
|
||||
} catch (IOException | UnsupportedAudioFileException iex) {
|
||||
ret.add(new ByteArrayRange(new byte[]{}));
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return bits == 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSize(boolean soundSize) {
|
||||
if (soundSize) {
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 8;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundType(boolean soundType) {
|
||||
if (soundType) {
|
||||
channels = 2;
|
||||
} else {
|
||||
channels = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSampleCount(long soundSampleCount) {
|
||||
this.sampleCount = soundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundCompression(int soundCompression) {
|
||||
//unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundRate(int soundRate) {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
this.sampleRate = rateMap[soundRate];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,29 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineExternalStreamSound extends Tag {
|
||||
public class DefineExternalStreamSound extends Tag implements CharacterIdTag, SoundTag {
|
||||
|
||||
public static final int ID = 1007;
|
||||
|
||||
@@ -52,6 +67,9 @@ public class DefineExternalStreamSound extends Tag {
|
||||
public String fileName;
|
||||
|
||||
public static final int SOUND_FORMAT_WAV = 0;
|
||||
|
||||
@Internal
|
||||
private int virtualCharacterId = 0;
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
@@ -103,4 +121,127 @@ public class DefineExternalStreamSound extends Tag {
|
||||
lastFrame = sis.readUI32("lastFrame");
|
||||
fileName = sis.readNetString("fileName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundExportFormat getExportFormat() {
|
||||
return SoundExportFormat.WAV; //?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
switch ((int) sampleRate) {
|
||||
case 5512:
|
||||
return 0;
|
||||
case 11025:
|
||||
return 1;
|
||||
case 22050:
|
||||
return 2;
|
||||
case 44100:
|
||||
return 3;
|
||||
}
|
||||
return -1; //?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return channels == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
Path soundPath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName));
|
||||
if (soundPath == null || !soundPath.toFile().exists()) {
|
||||
ret.add(new ByteArrayRange(new byte[]{}));
|
||||
return ret;
|
||||
}
|
||||
try (FileInputStream fis = new FileInputStream(soundPath.toFile()); AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(fis))) {
|
||||
ret.add(new ByteArrayRange(Helper.readStream(audioIs)));
|
||||
return ret;
|
||||
} catch (IOException | UnsupportedAudioFileException iex) {
|
||||
ret.add(new ByteArrayRange(new byte[]{}));
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return bits == 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
return new SoundFormat(getSoundFormatId(), rateMap[getSoundRate()], getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSize(boolean soundSize) {
|
||||
if (soundSize) {
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 8;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundType(boolean soundType) {
|
||||
if (soundType) {
|
||||
channels = 2;
|
||||
} else {
|
||||
channels = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSampleCount(long soundSampleCount) {
|
||||
this.sampleCount = soundSampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundCompression(int soundCompression) {
|
||||
//unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundRate(int soundRate) {
|
||||
final int[] rateMap = {5512, 11025, 22050, 44100};
|
||||
this.sampleRate = rateMap[soundRate];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return this.virtualCharacterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.virtualCharacterId = characterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
return "" + getCharacterId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + (virtualCharacterId > 0 ? " (" + virtualCharacterId + ")" : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
|
||||
import com.jpexs.decompiler.flash.types.BlendMode;
|
||||
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
|
||||
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
|
||||
@@ -565,11 +566,16 @@ public class Timeline {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
SoundStreamHeadTypeTag head = (SoundStreamHeadTypeTag) t;
|
||||
head.setVirtualCharacterId(containerId);
|
||||
head.setCharacterId(containerId);
|
||||
blocks = new ArrayList<>();
|
||||
soundStramBlocks.put(containerId, blocks);
|
||||
continue;
|
||||
}
|
||||
if (t instanceof DefineExternalStreamSound) {
|
||||
DefineExternalStreamSound externalStream = (DefineExternalStreamSound) t;
|
||||
externalStream.setCharacterId(containerId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
|
||||
@@ -1118,7 +1118,7 @@ public class XFLConverter {
|
||||
|
||||
private static HashMap<Integer, CharacterTag> getCharacters(ReadOnlyTagList tags) {
|
||||
HashMap<Integer, CharacterTag> ret = new HashMap<>();
|
||||
int maxId = 0;
|
||||
/*int maxId = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof CharacterTag) {
|
||||
CharacterTag ct = (CharacterTag) t;
|
||||
@@ -1126,12 +1126,12 @@ public class XFLConverter {
|
||||
maxId = ct.getCharacterId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
/*if (t instanceof SoundStreamHeadTypeTag) {
|
||||
SoundStreamHeadTypeTag ssh = (SoundStreamHeadTypeTag) t;
|
||||
ssh.setVirtualCharacterId(++maxId);
|
||||
}
|
||||
ssh.setCharacterId(++maxId);
|
||||
}*/
|
||||
if (t instanceof CharacterTag) {
|
||||
CharacterTag ct = (CharacterTag) t;
|
||||
ret.put(ct.getCharacterId(), ct);
|
||||
|
||||
Reference in New Issue
Block a user