From b0dd6bc2fdf8266d10c2a4907dfe84c6f24fe17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Tue, 5 Mar 2013 20:04:28 +0100 Subject: [PATCH] exporting sounds fixed movies export --- .../src/com/jpexs/decompiler/flash/Main.java | 20 ++-- trunk/src/com/jpexs/decompiler/flash/SWF.java | 106 ++++++++++++++---- .../jpexs/decompiler/flash/flv/AUDIODATA.java | 62 ++++++++++ .../com/jpexs/decompiler/flash/flv/DATA.java | 10 ++ .../flash/{ => flv}/FLVOutputStream.java | 16 ++- .../jpexs/decompiler/flash/flv/FLVTAG.java | 27 +++++ .../jpexs/decompiler/flash/flv/VIDEODATA.java | 36 ++++++ .../decompiler/flash/gui/ExportDialog.java | 75 +++++++------ .../jpexs/decompiler/flash/gui/MainFrame.java | 50 +++++++-- .../decompiler/flash/gui/graphics/sound16.png | Bin 0 -> 610 bytes .../decompiler/flash/tags/DefineSoundTag.java | 9 +- .../flash/tags/SoundStreamHead2Tag.java | 22 +++- .../flash/tags/SoundStreamHeadTag.java | 22 +++- .../flash/tags/SoundStreamHeadTypeTag.java | 12 ++ 14 files changed, 392 insertions(+), 75 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/flv/AUDIODATA.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/flv/DATA.java rename trunk/src/com/jpexs/decompiler/flash/{ => flv}/FLVOutputStream.java (82%) create mode 100644 trunk/src/com/jpexs/decompiler/flash/flv/FLVTAG.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/flv/VIDEODATA.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound16.png create mode 100644 trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTypeTag.java diff --git a/trunk/src/com/jpexs/decompiler/flash/Main.java b/trunk/src/com/jpexs/decompiler/flash/Main.java index 470f7b782..4459d63cb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/Main.java @@ -80,8 +80,7 @@ public class Main { public static boolean isCommandLineMode() { return commandLineMode; } - - public static final boolean DISPLAY_FILENAME=true; + public static final boolean DISPLAY_FILENAME = true; public static boolean DEBUG_COPY = false; /** * Debug mode = throwing an error when comparing original file and recompiled @@ -411,7 +410,7 @@ public class Main { System.out.println(" ...opens SWF file with the decompiler GUI"); System.out.println(" 3) -proxy (-PXXX)"); System.out.println(" ...auto start proxy in the tray. Optional parameter -P specifies port for proxy. Defaults to 55555. "); - System.out.println(" 4) -export (as|pcode|image|shape|movie) outdirectory infile"); + System.out.println(" 4) -export (as|pcode|image|shape|movie|sound) outdirectory infile"); System.out.println(" ...export infile sources to outdirectory as AsctionScript code (\"as\" argument) or as PCode (\"pcode\" argument), images, shapes or movies"); System.out.println(" 5) -dumpSWF infile"); System.out.println(" ...dumps list of SWF tags to console"); @@ -516,8 +515,10 @@ public class Main { if (!exportFormat.toLowerCase().equals("image")) { if (!exportFormat.toLowerCase().equals("shape")) { if (!exportFormat.toLowerCase().equals("movie")) { - System.err.println("Invalid export format:" + exportFormat); - badArguments(); + if (!exportFormat.toLowerCase().equals("sound")) { + System.err.println("Invalid export format:" + exportFormat); + badArguments(); + } } } } @@ -551,9 +552,12 @@ public class Main { } else if (exportFormat.equals("as") || exportFormat.equals("pcode")) { exportOK = exfile.exportActionScript(outDir.getAbsolutePath(), exportFormat.equals("pcode")); } else if (exportFormat.equals("movie")) { - exfile.exportVideos(outDir.getAbsolutePath()); - exportOK=true; - }else { + exfile.exportMovies(outDir.getAbsolutePath()); + exportOK = true; + } else if (exportFormat.equals("sound")) { + exfile.exportSounds(outDir.getAbsolutePath()); + exportOK = true; + } else { exportOK = false; } } catch (Exception ex) { diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index e9cabf7d6..888129b10 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -16,7 +16,11 @@ */ package com.jpexs.decompiler.flash; +import com.jpexs.decompiler.flash.flv.FLVOutputStream; import SevenZip.Compression.LZMA.Encoder; +import com.jpexs.decompiler.flash.flv.AUDIODATA; +import com.jpexs.decompiler.flash.flv.FLVTAG; +import com.jpexs.decompiler.flash.flv.VIDEODATA; import com.jpexs.decompiler.flash.gui.TagNode; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag; @@ -24,9 +28,14 @@ import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag; import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag; import com.jpexs.decompiler.flash.tags.DefineBitsTag; +import com.jpexs.decompiler.flash.tags.DefineSoundTag; import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; import com.jpexs.decompiler.flash.tags.DoABCTag; import com.jpexs.decompiler.flash.tags.JPEGTablesTag; +import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.VideoFrameTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -35,6 +44,7 @@ import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.RECT; import java.io.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -438,6 +448,28 @@ public class SWF { return false; } + public static void populateSoundStreamBlocks(List tags, Tag head, List output) { + boolean found = false; + for (Object t : tags) { + if (t == head) { + found = true; + continue; + } + if (!found) { + continue; + } + if (t instanceof SoundStreamBlockTag) { + output.add((SoundStreamBlockTag) t); + } + if (t instanceof SoundStreamHeadTypeTag) { + break; + } + if (t instanceof Container) { + populateSoundStreamBlocks(((Container) t).getSubItems(), head, output); + } + } + } + public void populateVideoFrames(int streamId, List tags, HashMap output) { for (Object t : tags) { if (t instanceof VideoFrameTag) { @@ -449,11 +481,61 @@ public class SWF { } } - public void exportVideos(String outdir) throws IOException { - exportVideos(outdir, tags); + public void exportMovies(String outdir) throws IOException { + exportMovies(outdir, tags); } - public void exportVideos(String outdir, List tags) throws IOException { + public void exportSounds(String outdir) throws IOException { + exportSounds(outdir, tags); + } + + public void exportSounds(String outdir, List tags) throws IOException { + if (!(new File(outdir)).exists()) { + (new File(outdir)).mkdirs(); + } + List os = new ArrayList(this.tags); + for (Tag t : tags) { + FileOutputStream fos = null; + try { + int id = 0; + if (t instanceof DefineSoundTag) { + id = ((DefineSoundTag) t).soundId; + } + fos = new FileOutputStream(outdir + File.separator + id + ".flv"); + FLVOutputStream flv = new FLVOutputStream(fos); + flv.writeHeader(true, false); + if (t instanceof DefineSoundTag) { + DefineSoundTag st = (DefineSoundTag) t; + 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 blocks = new ArrayList(); + List objs = new ArrayList(this.tags); + populateSoundStreamBlocks(objs, t, blocks); + 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))); + } + } + } finally { + if (fos != null) { + try { + fos.close(); + } catch (Exception ex) { + //ignore + } + } + } + + } + } + + public void exportMovies(String outdir, List tags) throws IOException { if (!(new File(outdir)).exists()) { (new File(outdir)).mkdirs(); } @@ -471,19 +553,7 @@ public class SWF { flv.writeHeader(false, true); int ms = (int) (1000.0f / ((float) frameRate)); for (int i = 0; i < frames.size(); i++) { - if (i == 1000) { - break; - } - long posBefore = flv.getPos(); - flv.writeUI8(9); //type video VideoFrameTag tag = frames.get(i); - flv.writeUI24(1 + tag.videoData.length); - long timeStamp = i * ms; - long ts1 = timeStamp & 0xffffff; - int ts2 = (int) (timeStamp >> 24); - flv.writeUI24(ts1); - flv.writeUI8(ts2); - flv.writeUI24(0); //streamId int frameType = 0; if (videoStream.codecID == 2) { //H263 SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(tag.videoData), SWF.DEFAULT_VERSION); @@ -512,11 +582,7 @@ public class SWF { break; } } - flv.writeUB(4, frameType); - flv.writeUB(4, videoStream.codecID); - flv.write(tag.videoData); - long posAfter = flv.getPos(); - flv.writeUI32(posAfter - posBefore); + flv.writeTag(new FLVTAG(i * ms, new VIDEODATA(frameType, videoStream.codecID, tag.videoData))); } diff --git a/trunk/src/com/jpexs/decompiler/flash/flv/AUDIODATA.java b/trunk/src/com/jpexs/decompiler/flash/flv/AUDIODATA.java new file mode 100644 index 000000000..1d20a2d66 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/flv/AUDIODATA.java @@ -0,0 +1,62 @@ +package com.jpexs.decompiler.flash.flv; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * + * @author JPEXS + */ +public class AUDIODATA extends DATA{ + public static final int SOUNDFORMAT_UNCOMPRESSED_NE=0; + public static final int SOUNDFORMAT_ADPCM=1; + public static final int SOUNDFORMAT_MP3=2; + public static final int SOUNDFORMAT_UNCOMPRESSED_LE=3; + public static final int SOUNDFORMAT_NELLYMOSER_16=4; + public static final int SOUNDFORMAT_NELLYMOSER_8=5; + public static final int SOUNDFORMAT_NELLYMOSER=6; + public static final int SOUNDFORMAT_SPEEX=11; + + public static final int SOUNDRATE_5K5=0; + public static final int SOUNDRATE_11K=1; + public static final int SOUNDRATE_22K=2; + public static final int SOUNDRATE_44K=3; + + public static final int SOUNDSIZE_8BIT=0; + public static final int SOUNDSIZE_16BIT=1; + + public static final int SOUNDTYPE_MONO=0; + public static final int SOUNDTYPE_STEREO=1; + + public int soundFormat; + public int soundRate; + public int soundSize; + public int soundType; + public byte[] soundData; + + public AUDIODATA(int soundFormat, int soundRate, int soundSize, int soundType, byte[] soundData) { + this.soundFormat = soundFormat; + this.soundRate = soundRate; + this.soundSize = soundSize; + this.soundType = soundType; + this.soundData = soundData; + } + + + + @Override + public byte[] getBytes() { + ByteArrayOutputStream baos=new ByteArrayOutputStream(); + try{ + FLVOutputStream flv=new FLVOutputStream(baos); + flv.writeUB(4, soundFormat); + flv.writeUB(2, soundRate); + flv.writeUB(1, soundSize); + flv.writeUB(1, soundType); + flv.write(soundData); + }catch(IOException ex){ + //ignore + } + return baos.toByteArray(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/flv/DATA.java b/trunk/src/com/jpexs/decompiler/flash/flv/DATA.java new file mode 100644 index 000000000..891fd050e --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/flv/DATA.java @@ -0,0 +1,10 @@ + +package com.jpexs.decompiler.flash.flv; + +/** + * + * @author JPEXS + */ +public abstract class DATA { + public abstract byte[] getBytes(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/FLVOutputStream.java b/trunk/src/com/jpexs/decompiler/flash/flv/FLVOutputStream.java similarity index 82% rename from trunk/src/com/jpexs/decompiler/flash/FLVOutputStream.java rename to trunk/src/com/jpexs/decompiler/flash/flv/FLVOutputStream.java index cb01207e4..4e97c7331 100644 --- a/trunk/src/com/jpexs/decompiler/flash/FLVOutputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/flv/FLVOutputStream.java @@ -1,4 +1,4 @@ -package com.jpexs.decompiler.flash; +package com.jpexs.decompiler.flash.flv; import java.io.IOException; import java.io.OutputStream; @@ -120,4 +120,18 @@ public class FLVOutputStream extends OutputStream { writeUI32(9); //header size writeUI32(0); } + + public void writeTag(FLVTAG tag) throws IOException { + long posBefore=getPos(); + writeUI8(tag.tagType); + byte data[]=tag.data.getBytes(); + writeUI24(data.length); + writeUI24(tag.timeStamp&0xffffff); + writeUI8((int)((tag.timeStamp>>24) & 0xff)); + writeUI24(0); + write(data); + long posAfter=getPos(); + long size=posAfter-posBefore; + writeUI32(size); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/flv/FLVTAG.java b/trunk/src/com/jpexs/decompiler/flash/flv/FLVTAG.java new file mode 100644 index 000000000..a3b4bc05d --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/flv/FLVTAG.java @@ -0,0 +1,27 @@ +package com.jpexs.decompiler.flash.flv; + +/** + * + * @author JPEXS + */ +public class FLVTAG { + public int tagType; + public long timeStamp; + public DATA data; + + public static final int DATATYPE_VIDEO=9; + public static final int DATATYPE_AUDIO=8; + public static final int DATATYPE_SCRIPT_DATA=18; + + public FLVTAG(long timeStamp, VIDEODATA data) { + this.tagType = DATATYPE_VIDEO; + this.timeStamp = timeStamp; + this.data = data; + } + + public FLVTAG(long timeStamp, AUDIODATA data) { + this.tagType = DATATYPE_AUDIO; + this.timeStamp = timeStamp; + this.data = data; + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/flv/VIDEODATA.java b/trunk/src/com/jpexs/decompiler/flash/flv/VIDEODATA.java new file mode 100644 index 000000000..9c24850da --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/flv/VIDEODATA.java @@ -0,0 +1,36 @@ +package com.jpexs.decompiler.flash.flv; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * + * @author JPEXS + */ +public class VIDEODATA extends DATA{ + public int frameType; + public int codecId; + public byte[] videoData; + + public VIDEODATA(int frameType, int codecId, byte[] videoData) { + this.frameType = frameType; + this.codecId = codecId; + this.videoData = videoData; + } + + + + @Override + public byte[] getBytes() { + ByteArrayOutputStream baos=new ByteArrayOutputStream(); + try{ + FLVOutputStream flv=new FLVOutputStream(baos); + flv.writeUB(4, frameType); + flv.writeUB(4, codecId); + flv.write(videoData); + }catch(IOException ex){ + //ignore + } + return baos.toByteArray(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/ExportDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/ExportDialog.java index e147d998a..54ea56eaf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/ExportDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/ExportDialog.java @@ -16,11 +16,31 @@ import javax.swing.JLabel; */ public class ExportDialog extends JDialog { - JComboBox images; - JComboBox shapes; - JComboBox actionScript; - JComboBox movies; boolean cancelled = false; + String options[][] = { + {"SVG"}, + {"PNG/JPEG"}, + {"FLV (No audio)"}, + {"FLV (Audio only)"}, + {"AS", "PCODE"} + }; + String optionNames[] = { + "Shapes", + "Images", + "Movies", + "Sounds", + "ActionScript" + }; + public static final int OPTION_SHAPES = 0; + public static final int OPTION_IMAGES = 1; + public static final int OPTION_MOVIES = 2; + public static final int OPTION_SOUNDS = 3; + public static final int OPTION_ACTIONSCRIPT = 4; + private JComboBox combos[]; + + public int getOption(int index) { + return combos[index].getSelectedIndex(); + } public ExportDialog() { setTitle("Export..."); @@ -30,27 +50,23 @@ public class ExportDialog extends JDialog { cancelled = true; } }); - setSize(200, 200); + setLayout(null); - JLabel shapesLabel = new JLabel("Shapes"); - shapesLabel.setBounds(10, 10, 60, 25); - shapes = new JComboBox(new String[]{"SVG"}); - shapes.setBounds(75, 10, 95, 25); - JLabel imagesLabel = new JLabel("Images"); - imagesLabel.setBounds(10, 35, 60, 25); - images = new JComboBox(new String[]{"PNG/JPEG"}); - images.setBounds(75, 35, 95, 25); + Container cnt = getContentPane(); + combos = new JComboBox[optionNames.length]; + int top = 10; + for (int i = 0; i < optionNames.length; i++) { + JLabel lab = new JLabel(optionNames[i]); + lab.setBounds(10, top, 60, 25); + cnt.add(lab); + combos[i] = new JComboBox(options[i]); + combos[i].setBounds(75, top, 105, 25); + cnt.add(combos[i]); + top += 25; + } + top += 10; - JLabel moviesLabel = new JLabel("Movies"); - moviesLabel.setBounds(10, 60, 60, 25); - movies = new JComboBox(new String[]{"FLV (No audio)"}); - movies.setBounds(75, 60, 95, 25); - - JLabel actionScriptLabel = new JLabel("ActionScript"); - actionScriptLabel.setBounds(10, 85, 60, 25); - actionScript = new JComboBox(new String[]{"AS", "PCODE"}); - actionScript.setBounds(75, 85, 95, 25); JButton okButton = new JButton("OK"); okButton.addActionListener(new ActionListener() { @@ -59,7 +75,7 @@ public class ExportDialog extends JDialog { setVisible(false); } }); - okButton.setBounds(20, 120, 75, 25); + okButton.setBounds(25, top, 75, 25); JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(new ActionListener() { @@ -69,18 +85,11 @@ public class ExportDialog extends JDialog { setVisible(false); } }); - cancelButton.setBounds(95, 120, 75, 25); - Container cnt = getContentPane(); - cnt.add(shapes); - cnt.add(shapesLabel); - cnt.add(images); - cnt.add(imagesLabel); - cnt.add(movies); - cnt.add(moviesLabel); - cnt.add(actionScript); - cnt.add(actionScriptLabel); + cancelButton.setBounds(100, top, 75, 25); + cnt.add(okButton); cnt.add(cancelButton); + setSize(210, top + 70); View.centerScreen(this); View.setWindowIcon(this); getRootPane().setDefaultButton(okButton); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index e4233e7ea..5fe589ad4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -49,6 +49,7 @@ import com.jpexs.decompiler.flash.tags.DefineShape2Tag; import com.jpexs.decompiler.flash.tags.DefineShape3Tag; import com.jpexs.decompiler.flash.tags.DefineShape4Tag; import com.jpexs.decompiler.flash.tags.DefineShapeTag; +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; @@ -64,6 +65,10 @@ import com.jpexs.decompiler.flash.tags.PlaceObjectTag; 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.SoundStreamHead2Tag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; +import com.jpexs.decompiler.flash.tags.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.AloneTag; @@ -810,6 +815,10 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if (t instanceof DefineVideoStreamTag) { return "movie"; } + + if ((t instanceof DefineSoundTag) || (t instanceof SoundStreamHeadTag) || (t instanceof SoundStreamHead2Tag)) { + return "sound"; + } return "folder"; } @@ -894,8 +903,20 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi List fonts = getTagNodesWithType(list, "font", parent, true); List texts = getTagNodesWithType(list, "text", parent, true); List movies = getTagNodesWithType(list, "movie", parent, true); + List sounds = getTagNodesWithType(list, "sound", parent, true); List actionScript = new ArrayList(); + for (int i = 0; i < sounds.size(); i++) { + if (sounds.get(i).tag instanceof SoundStreamHeadTypeTag) { + List blocks = new ArrayList(); + SWF.populateSoundStreamBlocks(list, (Tag) sounds.get(i).tag, blocks); + if (blocks.isEmpty()) { + sounds.remove(i); + i--; + } + } + } + for (TagNode n : sprites) { n.subItems = getTagNodesWithType(new ArrayList(((DefineSpriteTag) n.tag).subTags), "frame", n.tag, true); } @@ -929,6 +950,10 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi TagNode moviesNode = new TagNode("movies"); moviesNode.subItems.addAll(movies); + TagNode soundsNode = new TagNode("sounds"); + soundsNode.subItems.addAll(sounds); + + TagNode fontsNode = new TagNode("fonts"); fontsNode.subItems.addAll(fonts); @@ -969,6 +994,9 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if (!moviesNode.subItems.isEmpty()) { ret.add(moviesNode); } + if (!soundsNode.subItems.isEmpty()) { + ret.add(soundsNode); + } if (!buttonsNode.subItems.isEmpty()) { ret.add(buttonsNode); } @@ -1059,10 +1087,8 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi Main.startWork("Exporting..."); final String selFile = chooser.getSelectedFile().getAbsolutePath(); Configuration.setConfig("lastExportDir", chooser.getSelectedFile().getParentFile().getAbsolutePath()); - final boolean isPcode = export.actionScript.getSelectedIndex() == 1; //e.getActionCommand().startsWith("EXPORTPCODE"); + final boolean isPcode = export.getOption(ExportDialog.OPTION_ACTIONSCRIPT) == 1; final boolean onlySel = e.getActionCommand().endsWith("SEL"); - //final boolean images = e.getActionCommand().startsWith("EXPORTIMAGES"); - //final boolean shapes = e.getActionCommand().startsWith("EXPORTSHAPES"); (new Thread() { @Override public void run() { @@ -1081,6 +1107,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi List images = new ArrayList(); List shapes = new ArrayList(); List movies = new ArrayList(); + List sounds = new ArrayList(); List actionNodes = new ArrayList(); for (Object d : sel) { if (d instanceof TagNode) { @@ -1097,6 +1124,9 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if ("movie".equals(getTagType(n.tag))) { movies.add((Tag) n.tag); } + if ("sound".equals(getTagType(n.tag))) { + sounds.add((Tag) n.tag); + } } if (d instanceof TreeElement) { if (((TreeElement) d).isLeaf()) { @@ -1106,7 +1136,8 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } SWF.exportImages(selFile + File.separator + "images", images, jtt); SWF.exportShapes(selFile + File.separator + "shapes", shapes); - swf.exportVideos(selFile + File.separator + "movies", movies); + swf.exportMovies(selFile + File.separator + "movies", movies); + swf.exportSounds(selFile + File.separator + "sounds", sounds); if (abcPanel != null) { for (int i = 0; i < tlsList.size(); i++) { TreeLeafScript tls = tlsList.get(i); @@ -1124,10 +1155,11 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } } } else { - Main.swf.exportImages(selFile + File.separator + "images"); - Main.swf.exportShapes(selFile + File.separator + "shapes"); - swf.exportVideos(selFile + File.separator + "movies"); - Main.swf.exportActionScript(selFile, isPcode); + swf.exportImages(selFile + File.separator + "images"); + swf.exportShapes(selFile + File.separator + "shapes"); + swf.exportMovies(selFile + File.separator + "movies"); + swf.exportSounds(selFile + File.separator + "sounds"); + swf.exportActionScript(selFile, isPcode); } } catch (Exception ignored) { ignored.printStackTrace(); @@ -1419,6 +1451,8 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } if (tagObj instanceof DefineVideoStreamTag) { showCard(CARDEMPTYPANEL); + } else if ((tagObj instanceof DefineSoundTag) || (tagObj instanceof SoundStreamHeadTag) || (tagObj instanceof SoundStreamHead2Tag)) { + showCard(CARDEMPTYPANEL); } else if (tagObj instanceof ASMSource) { showCard(CARDACTIONSCRIPTPANEL); actionPanel.setSource((ASMSource) tagObj); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound16.png b/trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound16.png new file mode 100644 index 0000000000000000000000000000000000000000..6056d234a9818d248987389d4a621e5c83ce0851 GIT binary patch literal 610 zcmV-o0-gPdP)FDRfPcVFW5d%9V=z{?A#;oriL5xO+n6O2X~nf!lQuE^VWXpgu83qI(qCF{ zS}dqc=wWy-JjhR6YYDxINHb)T^nMSh)vA20R`F7)lzCSCZF94My}d73T>N+m zpyXWPL`#FF;s+j3t(LL2R!6+EP98p9G9EaJe<5S)o@#CPu0JyV*YBbiNC<>y{C`3_2 zFc^fUC0P=`0GC2D0rmxry!i<{eh#|t2UjSV*w|QyY37m5W)KQZKoA6m%^;bK|K7sb zq~^Y!1U(%y>Cs5W^^bz?JUQeR7IK)M&$43OYdMwDJVcVBtSjl_Ar8Hmr2)a$eK-tv zNC4d)(7D`Piq~gVUR7m2k$BH5O6=$i%I6Kpa_sVNy!&j)9UKPT@*VWNNNm+UIUciF wPJ00!a`S;oH}3WS@hUTDnx*^y9@F3E2OYGed{u8eJ^%m!07*qoM6N<$f+a~A3jhEB literal 0 HcmV?d00001 diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java index ab85b697d..3350b3131 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSoundTag.java @@ -42,7 +42,8 @@ public class DefineSoundTag extends CharacterTag { public static final int FORMAT_NELLYMOSER = 6; public static final int FORMAT_SPEEX = 11; public int soundRate; - public boolean soundType;//true=stereo + public int soundSize; + public int soundType; public long soundSampleCount; public byte soundData[]; @@ -66,7 +67,8 @@ public class DefineSoundTag extends CharacterTag { sos.writeUI16(soundId); sos.writeUB(4, soundFormat); sos.writeUB(2, soundRate); - sos.writeUB(1, soundType ? 1 : 0); + sos.writeUB(1, soundSize); + sos.writeUB(1, soundType); sos.writeUI32(soundSampleCount); sos.write(soundData); } catch (IOException e) { @@ -87,7 +89,8 @@ public class DefineSoundTag extends CharacterTag { soundId = sis.readUI16(); soundFormat = (int) sis.readUB(4); soundRate = (int) sis.readUB(2); - soundType = sis.readUB(1) == 1; + soundSize = (int) sis.readUB(1); + soundType = (int) sis.readUB(1); soundSampleCount = sis.readUI32(); soundData = sis.readBytes(sis.available()); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java index e2553323c..872d30229 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java @@ -28,7 +28,7 @@ import java.io.OutputStream; * * @author JPEXS */ -public class SoundStreamHead2Tag extends Tag { +public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag{ public int playBackSoundRate; public int playBackSoundSize; @@ -92,4 +92,24 @@ public class SoundStreamHead2Tag extends Tag { latencySeek = sis.readSI16(); } } + + @Override + public int getSoundFormat() { + return streamSoundCompression; + } + + @Override + public int getSoundRate() { + return streamSoundRate; + } + + @Override + public int getSoundSize() { + return streamSoundSize; + } + + @Override + public int getSoundType() { + return streamSoundType; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java index 2c2060ede..b6eccda7c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java @@ -28,7 +28,7 @@ import java.io.OutputStream; * * @author JPEXS */ -public class SoundStreamHeadTag extends Tag { +public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag{ public int playBackSoundRate; public int playBackSoundSize; @@ -92,4 +92,24 @@ public class SoundStreamHeadTag extends Tag { latencySeek = sis.readSI16(); } } + + @Override + public int getSoundFormat() { + return streamSoundCompression; + } + + @Override + public int getSoundRate() { + return streamSoundRate; + } + + @Override + public int getSoundSize() { + return streamSoundSize; + } + + @Override + public int getSoundType() { + return streamSoundType; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTypeTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTypeTag.java new file mode 100644 index 000000000..26a80d6ff --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTypeTag.java @@ -0,0 +1,12 @@ +package com.jpexs.decompiler.flash.tags; + +/** + * + * @author JPEXS + */ +public interface SoundStreamHeadTypeTag { + public int getSoundFormat(); + public int getSoundRate(); + public int getSoundSize(); + public int getSoundType(); +}