Issue #374 Replace selected sound (DefineSound tag)

This commit is contained in:
Jindra Petk
2014-03-09 16:42:59 +01:00
parent 34b152f005
commit 218b8553f3
10 changed files with 384 additions and 125 deletions

View File

@@ -235,6 +235,10 @@ public final class SWF implements TreeItem, Timelined {
private Timeline timeline;
public void updateCharacters() {
parseCharacters(new ArrayList<ContainerItem>(tags));
}
private void parseCharacters(List<ContainerItem> list) {
for (ContainerItem t : list) {
if (t instanceof CharacterTag) {
@@ -563,7 +567,7 @@ public final class SWF implements TreeItem, Timelined {
showFrameTag.innerTags = innerTags;
}
}
parseCharacters(new ArrayList<ContainerItem>(tags));
updateCharacters();
assignExportNamesToSymbols();
assignClassesToSymbols();
findFileAttributes();

View File

@@ -308,7 +308,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
return 0;
}
if (stillFrame) {
return 1;
return 0;
}
return timelined.getTimeline().frames.size();
}

View File

@@ -157,6 +157,7 @@ import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -282,6 +283,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
private File tempFile;
private PlayerControls imagePlayControls;
private JPanel repPanel;
private JPanel repPanel2;
private SoundThread soundThread = null;
private class SoundThread implements MediaDisplay {
@@ -422,6 +426,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
private static final String ACTION_SELECT_BKCOLOR = "SELECTCOLOR";
private static final String ACTION_REPLACE_IMAGE = "REPLACEIMAGE";
private static final String ACTION_REPLACE_BINARY = "REPLACEBINARY";
private static final String ACTION_REPLACE_OTHER = "REPLACEOTHER";
private static final String ACTION_EDIT_GENERIC_TAG = "EDITGENERICTAG";
private static final String ACTION_SAVE_GENERIC_TAG = "SAVEGENERICTAG";
private static final String ACTION_CANCEL_GENERIC_TAG = "CANCELGENERICTAG";
@@ -507,6 +512,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
replaceBinarySelectionMenuItem.addActionListener(this);
contextPopupMenu.add(replaceBinarySelectionMenuItem);
final JMenuItem replaceSoundSelectionMenuItem = new JMenuItem(translate("button.replace"));
replaceSoundSelectionMenuItem.setActionCommand(ACTION_REPLACE_OTHER);
replaceSoundSelectionMenuItem.addActionListener(this);
contextPopupMenu.add(replaceSoundSelectionMenuItem);
final JMenuItem closeSelectionMenuItem = new JMenuItem(translate("contextmenu.closeSwf"));
closeSelectionMenuItem.setActionCommand(ACTION_CLOSE_SWF);
closeSelectionMenuItem.addActionListener(this);
@@ -548,6 +558,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
replaceImageSelectionMenuItem.setVisible(false);
replaceBinarySelectionMenuItem.setVisible(false);
replaceSoundSelectionMenuItem.setVisible(false);
closeSelectionMenuItem.setVisible(false);
moveTagMenu.setVisible(false);
expandRecursiveMenuItem.setVisible(false);
@@ -564,6 +575,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
replaceBinarySelectionMenuItem.setVisible(true);
}
if (item instanceof DefineSoundTag) {
replaceSoundSelectionMenuItem.setVisible(true);
}
if (treeNode instanceof SWFNode) {
closeSelectionMenuItem.setVisible(true);
}
@@ -947,6 +962,13 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
}
pan.add(leftComponent, BorderLayout.CENTER);
repPanel = new JPanel(new FlowLayout());
JButton repButton = new JButton(translate("button.replace"), View.getIcon("edit16"));
repButton.addActionListener(this);
repButton.setActionCommand(ACTION_REPLACE_OTHER);
repPanel.add(repButton);
pan.add(repPanel, BorderLayout.SOUTH);
viewerCards.add(pan, FLASH_VIEWER_CARD);
previewSplitPane.setLeftComponent(viewerCards);
@@ -976,9 +998,19 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
prevIntLabel.setHorizontalAlignment(SwingConstants.CENTER);
//prevIntLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
previewPanel.add(prevIntLabel, BorderLayout.NORTH);
repPanel2 = new JPanel(new FlowLayout());
JButton repButton2 = new JButton(translate("button.replace"), View.getIcon("edit16"));
repButton2.addActionListener(this);
repButton2.setActionCommand(ACTION_REPLACE_OTHER);
repPanel2.add(repButton2);
previewPanel.add(repPanel2, BorderLayout.SOUTH);
shapesCard.add(previewPanel, BorderLayout.CENTER);
displayPanel.add(shapesCard, CARDDRAWPREVIEWPANEL);
displayReplace(false);
swfPreviewPanel = new ImagePanel();
displayPanel.add(swfPreviewPanel, CARDSWFPREVIEWPANEL);
@@ -2251,13 +2283,79 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
reload(true);
}
break;
case ACTION_REPLACE_IMAGE: {
case ACTION_REPLACE_BINARY:
case ACTION_REPLACE_IMAGE:
case ACTION_REPLACE_OTHER: {
TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent();
if (treeNode == null) {
return;
}
TreeItem item = treeNode.getItem();
if (item instanceof DefineSoundTag) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase().endsWith(".mp3"))
|| (f.getName().toLowerCase().endsWith(".wav"))
|| (f.isDirectory());
}
@Override
public String getDescription() {
return translate("filter.sounds");
}
});
fc.addChoosableFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase().endsWith(".mp3"))
|| (f.isDirectory());
}
@Override
public String getDescription() {
return translate("filter.sounds.mp3");
}
});
fc.addChoosableFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase().endsWith(".wav"))
|| (f.isDirectory());
}
@Override
public String getDescription() {
return translate("filter.sounds.wav");
}
});
JFrame f = new JFrame();
View.setWindowIcon(f);
int returnVal = fc.showOpenDialog(f);
if (returnVal == JFileChooser.APPROVE_OPTION) {
Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
File selfile = Helper.fixDialogFile(fc.getSelectedFile());
DefineSoundTag ds = (DefineSoundTag) item;
int soundFormat = DefineSoundTag.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN;
if (selfile.getName().toLowerCase().endsWith(".mp3")) {
soundFormat = DefineSoundTag.FORMAT_MP3;
}
boolean ok = false;
try {
ok = ds.setSound(new FileInputStream(selfile), soundFormat);
} catch (IOException ex) {
//ignore
}
if (!ok) {
View.showMessageDialog(null, translate("error.sound.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE);
} else {
reload(true);
}
}
}
if (item instanceof ImageTag) {
ImageTag it = (ImageTag) item;
if (it.importSupported()) {
@@ -2290,12 +2388,13 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
if (it instanceof DefineBitsTag) {
DefineBitsJPEG2Tag jpeg2Tag = new DefineBitsJPEG2Tag(swf, it.getOriginalData(), it.getPos(), it.getCharacterId(), data);
swf.tags.set(swf.tags.indexOf(it), jpeg2Tag);
swf.updateCharacters();
refreshTree();
setTreeItem(jpeg2Tag);
} else {
it.setImage(data);
}
swf.clearImageCache();
SWF.clearImageCache();
} catch (IOException ex) {
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, "Invalid image", ex);
View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE);
@@ -2304,15 +2403,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
}
}
}
}
break;
case ACTION_REPLACE_BINARY: {
TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent();
if (treeNode == null) {
return;
}
TreeItem item = treeNode.getItem();
if (item instanceof DefineBinaryDataTag) {
DefineBinaryDataTag bt = (DefineBinaryDataTag) item;
JFileChooser fc = new JFileChooser();
@@ -2515,8 +2605,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
if (soundThread != null) {
soundThread.pause();
}
imagePlayControls.setMedia(imagePanel);
imagePlayControls.setMedia(previewImagePanel);
stopFlashPlayer();
displayReplace(tagObj instanceof DefineSoundTag);
if (tagObj instanceof ScriptPack) {
final ScriptPack scriptLeaf = (ScriptPack) tagObj;
final List<ABCContainerTag> abcList = scriptLeaf.abc.swf.abcList;
@@ -3320,4 +3411,11 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
}
};
}
public void displayReplace(boolean display) {
repPanel.setVisible(display);
repPanel2.setVisible(display);
}
}

View File

@@ -455,3 +455,9 @@ generictag.array.insertend = Insert %item% at the end
#after version 2.0.0
contextmenu.expandAll = Expand all
binaryData.truncateWarning = %count% bytes truncated.
filter.sounds = Supported sound formats (*.wav, *.mp3)
filter.sounds.wav = Wave file format (*.wav)
filter.sounds.mp3 = MP3 compressed format (*.mp3)
error.sound.invalid = Invalid sound.

View File

@@ -453,3 +453,10 @@ generictag.array.insertbefore = Vlo\u017eit %item% p\u0159ed
generictag.array.remove = Odstranit %item%
generictag.array.insertafter = Vlo\u017eit %item% za
generictag.array.insertend = Vlo\u017eit %item% na konec
filter.sounds = Podporovan\u00e9 zvukov\u00e9 form\u00e1ty (*.wav, *.mp3)
filter.sounds.wav = Wave form\u00e1t (*.wav)
filter.sounds.mp3 = MP3 komprimovan\u00fd form\u00e1t (*.mp3)
error.sound.invalid = Neplatn\u00fd zvuk.

View File

@@ -22,10 +22,20 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
import com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
import com.jpexs.helpers.Helper;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
/**
*
@@ -83,6 +93,7 @@ public class DefineSoundTag extends CharacterTag {
sos.writeUB(1, soundType ? 1 : 0);
sos.writeUI32(soundSampleCount);
sos.write(soundData);
} catch (IOException e) {
}
return baos.toByteArray();
@@ -123,4 +134,153 @@ public class DefineSoundTag extends CharacterTag {
}
return "flv";
}
private void loadID3v2(InputStream in) {
int size = -1;
try {
// Read ID3v2 header (10 bytes).
in.mark(10);
size = readID3v2Header(in);
} catch (IOException e) {
} finally {
try {
// Unread ID3v2 header (10 bytes).
in.reset();
} catch (IOException e) {
}
}
// Load ID3v2 tags.
try {
if (size > 0) {
byte[] rawid3v2 = new byte[size];
in.read(rawid3v2, 0, rawid3v2.length);
}
} catch (IOException e) {
}
}
/**
* Parse ID3v2 tag header to find out size of ID3v2 frames.
*
* @param in MP3 InputStream
* @return size of ID3v2 frames + header
* @throws IOException
* @author JavaZOOM
*/
private int readID3v2Header(InputStream in) throws IOException {
byte[] id3header = new byte[4];
int size = -10;
in.read(id3header, 0, 3);
// Look for ID3v2
if ((id3header[0] == 'I') && (id3header[1] == 'D') && (id3header[2] == '3')) {
in.read(id3header, 0, 3);
int majorVersion = id3header[0];
int revision = id3header[1];
in.read(id3header, 0, 4);
size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
}
return (size + 10);
}
public boolean setSound(InputStream is, int newSoundFormat) throws IOException {
int newSoundRate = -1;
boolean newSoundSize = false;
boolean newSoundType = false;
long newSoundSampleCount = -1;
byte newSoundData[];
switch (newSoundFormat) {
case FORMAT_UNCOMPRESSED_LITTLE_ENDIAN:
try (AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(is))) {
AudioFormat fmt = audioIs.getFormat();
newSoundType = fmt.getChannels() == 2;
newSoundSize = fmt.getSampleSizeInBits() == 16;
newSoundSampleCount = audioIs.getFrameLength();
newSoundData = Helper.readStream(audioIs);
newSoundRate = (int) Math.round(fmt.getSampleRate());
switch (newSoundRate) {
case 5512:
newSoundRate = 0;
break;
case 11025:
newSoundRate = 1;
break;
case 22050:
newSoundRate = 2;
break;
case 44100:
newSoundRate = 3;
break;
default:
return false;
}
} catch (UnsupportedAudioFileException ex) {
return false;
}
break;
case FORMAT_MP3:
BufferedInputStream bis = new BufferedInputStream(is);
loadID3v2(bis);
byte mp3data[] = Helper.readStream(bis);
final int ID3_V1_LENTGH = 128;
final int ID3_V1_EXT_LENGTH = 227;
if (mp3data.length > ID3_V1_LENTGH) {
//ID3v1
if (mp3data[mp3data.length - ID3_V1_LENTGH] == 'T' && mp3data[mp3data.length - ID3_V1_LENTGH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_LENTGH + 2] == 'G') {
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_LENTGH);
if (mp3data.length > ID3_V1_EXT_LENGTH) {
//ID3v1 extended
if (mp3data[mp3data.length - ID3_V1_EXT_LENGTH] == 'T' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 1] == 'A' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 2] == 'G' && mp3data[mp3data.length - ID3_V1_EXT_LENGTH + 3] == '+') {
mp3data = Arrays.copyOf(mp3data, mp3data.length - ID3_V1_EXT_LENGTH);
}
}
}
}
MP3SOUNDDATA snd = new MP3SOUNDDATA(new ByteArrayInputStream(mp3data), true);
if (!snd.frames.isEmpty()) {
MP3FRAME fr = snd.frames.get(0);
newSoundRate = fr.getSamplingRate();
switch (newSoundRate) {
case 11025:
newSoundRate = 1;
break;
case 22050:
newSoundRate = 2;
break;
case 44100:
newSoundRate = 3;
break;
default:
return false;
}
newSoundSize = true;
newSoundType = fr.isStereo();
int len = snd.sampleCount();
if (fr.isStereo()) {
len = len / 2;
}
newSoundSampleCount = len;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
sos.writeSI16(0); //Latency - how to calculate it?
sos.write(mp3data);
newSoundData = baos.toByteArray();
break;
default:
return false;
}
if (newSoundData != null) {
this.soundSize = newSoundSize;
this.soundRate = newSoundRate;
this.soundSampleCount = newSoundSampleCount;
this.soundData = newSoundData;
this.soundType = newSoundType;
this.soundFormat = newSoundFormat;
return true;
}
return false;
}
}

View File

@@ -16,14 +16,15 @@
*/
package com.jpexs.decompiler.flash.types.sound;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.DecoderException;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.SampleBuffer;
/**
*
@@ -31,113 +32,75 @@ import java.util.logging.Logger;
*/
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 byte[] sampleData;
private Header h;
private SampleBuffer samples;
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);
private MP3FRAME() {
int size = getSampleDataSize();
int sizeBytes = (int) Math.ceil((double) size / 8.0);
sampleData = sis.readBytes(sizeBytes);
}
public byte[] getData() {
public static MP3FRAME readFrame(Bitstream bitstream, Decoder decoder) throws IOException {
MP3FRAME ret = new MP3FRAME();
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
sos.writeUB(11, syncWord);
sos.writeUB(1, mpegVersion);
sos.writeUB(2, layer);
sos.writeUB(1, protectionBit ? 1 : 0);
sos.writeUB(4, bitRate);
sos.writeUB(2, samplingRate);
sos.writeUB(1, paddingBit ? 1 : 0);
sos.writeUB(1, reserved);
sos.writeUB(2, channelMode);
sos.writeUB(2, modelExtension);
sos.write(sampleData);
return baos.toByteArray();
} catch (IOException ex) {
ret.h = bitstream.readFrame();
if (ret.h == null) {
return null;
}
} catch (BitstreamException ex) {
Logger.getLogger(MP3FRAME.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private int getSampleDataSize() {
return (((isMPEG1() ? 144 : 72) * bitRate) / samplingRate) + (paddingBit ? 1 : 0) - 4;
}
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;
try {
ret.samples = (SampleBuffer) decoder.decodeFrame(ret.h, bitstream);
} catch (DecoderException ex) {
Logger.getLogger(MP3FRAME.class.getName()).log(Level.SEVERE, null, ex);
}
if (isLayerII()) {
layer = 1;
bitstream.closeFrame();
return ret;
}
public boolean isStereo() {
return h.mode() != Header.SINGLE_CHANNEL;
}
public SampleBuffer getSamples() {
return samples;
}
public int getSamplingRate() {
switch (h.sample_frequency()) {
case Header.THIRTYTWO:
if (h.version() == Header.MPEG1) {
return 32000;
} else if (h.version() == Header.MPEG2_LSF) {
return 16000;
} else // SZD
{
return 8000;
}
case Header.FOURTYFOUR_POINT_ONE:
if (h.version() == Header.MPEG1) {
return 44100;
} else if (h.version() == Header.MPEG2_LSF) {
return 22050;
} else // SZD
{
return 11025;
}
case Header.FOURTYEIGHT:
if (h.version() == Header.MPEG1) {
return 48000;
} else if (h.version() == Header.MPEG2_LSF) {
return 24000;
} else // SZD
{
return 12000;
}
default:
return 0;
}
if (isLayerIII()) {
layer = 2;
}
int mver = 0;
if (isMPEG1()) {
mver = 0;
}
if (isMPEG2()) {
mver = 1;
}
return map[mver][layer][bitRate];
}
public int getBitRate() {
return h.bitrate();
}
}

View File

@@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.Decoder;
/**
*
@@ -32,12 +34,25 @@ public class MP3SOUNDDATA {
public int seekSamples;
public List<MP3FRAME> frames;
public MP3SOUNDDATA(InputStream is) throws IOException {
public MP3SOUNDDATA(InputStream is, boolean raw) throws IOException {
SWFInputStream sis = new SWFInputStream(is, SWF.DEFAULT_VERSION);
seekSamples = sis.readUI16();
if (!raw) {
seekSamples = sis.readSI16();
}
frames = new ArrayList<>();
while (sis.available() > 0) {
frames.add(new MP3FRAME(sis));
MP3FRAME f;
Decoder decoder = new Decoder();
Bitstream bitstream = new Bitstream(is);
while ((f = MP3FRAME.readFrame(bitstream, decoder)) != null) {
frames.add(f);
}
}
public int sampleCount() {
int r = 0;
for (MP3FRAME f : frames) {
r += f.getSamples().getBufferLength();
}
return r;
}
}

View File

@@ -91,6 +91,7 @@ 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 com.jpexs.decompiler.flash.types.sound.MP3SOUNDDATA;
import com.jpexs.decompiler.graph.ExportMode;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
@@ -1441,9 +1442,11 @@ public class XFLConverter {
format += 4; //quality best
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(soundData), swf.version);
try {
sis.readSI16();
MP3FRAME frame = new MP3FRAME(sis);
int bitRate = frame.getBitrate();
MP3SOUNDDATA s = new MP3SOUNDDATA(sis, false);
//sis.readSI16();
//MP3FRAME frame = new MP3FRAME(sis);
MP3FRAME frame = s.frames.get(0);
int bitRate = frame.getBitRate();
switch (bitRate) {
case 8:

View File

@@ -46,6 +46,7 @@ public class MP3Player extends SoundPlayer {
private int positionSamples = 0;
private long sampleCount;
private int frameRate;
private int positionFrames = 0;
public MP3Player(InputStream stream, long sampleCount, int frameRate) throws JavaLayerException {
this(stream, null);
@@ -118,6 +119,7 @@ public class MP3Player extends SoundPlayer {
}
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
positionSamples += output.getBufferLength();
positionFrames++;
bitstream.closeFrame();
if (positionSamples >= endPosition) {
break;
@@ -163,6 +165,7 @@ public class MP3Player extends SoundPlayer {
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
positionSamples += output.getBufferLength();
positionFrames++;
synchronized (this) {
out = audio;