mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 10:05:00 +00:00
internal sound playing refactoring
diplay sound icon ffdec:format code, organize imports
This commit is contained in:
@@ -117,7 +117,6 @@ import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.decompiler.flash.xfl.FLAVersion;
|
||||
import com.jpexs.decompiler.flash.xfl.XFLConverter;
|
||||
@@ -133,9 +132,7 @@ import com.jpexs.helpers.ProgressListener;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
@@ -2352,12 +2349,12 @@ public final class SWF implements TreeItem, Timelined {
|
||||
drawable.toImage(dframe, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans);
|
||||
//if(stateUnderCursor == layer){
|
||||
/* if(true){
|
||||
Graphics2D gg = (Graphics2D)img.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.red);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
|
||||
}*/
|
||||
Graphics2D gg = (Graphics2D)img.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.red);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
|
||||
}*/
|
||||
} else if (drawable instanceof FontTag) {
|
||||
// only DefineFont tags
|
||||
FontTag fontTag = (FontTag) drawable;
|
||||
@@ -2470,9 +2467,7 @@ public final class SWF implements TreeItem, Timelined {
|
||||
g.setComposite(AlphaComposite.Dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
g.setTransform(AffineTransform.getScaleInstance(1, 1));
|
||||
}
|
||||
|
||||
|
||||
@@ -102,12 +102,11 @@ public class Matrix {
|
||||
public Point transform(Point point) {
|
||||
return transform(point.x, point.y);
|
||||
}
|
||||
|
||||
|
||||
public java.awt.Point transform(java.awt.Point point) {
|
||||
Point p= transform(point.x, point.y);
|
||||
return new java.awt.Point((int)p.x,(int)p.y);
|
||||
Point p = transform(point.x, point.y);
|
||||
return new java.awt.Point((int) p.x, (int) p.y);
|
||||
}
|
||||
|
||||
|
||||
public ExportRectangle transform(ExportRectangle rect) {
|
||||
double minX = Double.MAX_VALUE;
|
||||
|
||||
@@ -40,8 +40,6 @@ import java.awt.Cursor;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
@@ -63,8 +61,8 @@ import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JLabel;
|
||||
@@ -95,9 +93,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
private Rectangle rect = null;
|
||||
private List<DepthState> dss;
|
||||
private List<Shape> outlines;
|
||||
|
||||
|
||||
public void setImg(SerializableImage img,List<DepthState> dss, List<Shape> outlines) {
|
||||
public void setImg(SerializableImage img, List<DepthState> dss, List<Shape> outlines) {
|
||||
this.img = img;
|
||||
this.dss = dss;
|
||||
this.outlines = outlines;
|
||||
@@ -105,22 +102,22 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
repaint();
|
||||
}
|
||||
|
||||
public List<DepthState> getObjectsUnderPoint(Point p){
|
||||
List<DepthState> ret=new ArrayList<>();
|
||||
for(int i=0;i<outlines.size();i++){
|
||||
if(outlines.get(i).contains(p)){
|
||||
public List<DepthState> getObjectsUnderPoint(Point p) {
|
||||
List<DepthState> ret = new ArrayList<>();
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
if (outlines.get(i).contains(p)) {
|
||||
ret.add(dss.get(i));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public Rectangle getRect() {
|
||||
return rect;
|
||||
}
|
||||
|
||||
public Point toImagePoint(Point p){
|
||||
return new Point((p.x-rect.x)*img.getWidth()/rect.width,(p.y-rect.y)*img.getHeight()/rect.height);
|
||||
|
||||
public Point toImagePoint(Point p) {
|
||||
return new Point((p.x - rect.x) * img.getWidth() / rect.width, (p.y - rect.y) * img.getHeight() / rect.height);
|
||||
}
|
||||
|
||||
private void calcRect() {
|
||||
@@ -162,7 +159,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
if (img != null) {
|
||||
calcRect();
|
||||
g2d.setComposite(AlphaComposite.SrcOver);
|
||||
g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, 0, 0, img.getWidth(), img.getHeight(), null);
|
||||
g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0, 0, img.getWidth(), img.getHeight(), null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -210,24 +207,24 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
int width = rect.getWidth();
|
||||
double scale = 1.0;
|
||||
/*if (width > swf.displayRect.getWidth()) {
|
||||
scale = (double) swf.displayRect.getWidth() / (double) width;
|
||||
}*/
|
||||
scale = (double) swf.displayRect.getWidth() / (double) width;
|
||||
}*/
|
||||
Matrix m = new Matrix();
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
m.scale(scale);
|
||||
Point p=e.getPoint();
|
||||
Point p = e.getPoint();
|
||||
p = iconPanel.toImagePoint(p);
|
||||
int x = p.x;
|
||||
int x = p.x;
|
||||
int y = p.y;
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
objs=iconPanel.getObjectsUnderPoint(p);
|
||||
objs = iconPanel.getObjectsUnderPoint(p);
|
||||
String ret = "";
|
||||
|
||||
ret += " [" + x + "," + y + "] : ";
|
||||
|
||||
boolean first = true;
|
||||
for (int i=0;i<objs.size();i++) {
|
||||
DepthState ds=objs.get(i);
|
||||
for (int i = 0; i < objs.size(); i++) {
|
||||
DepthState ds = objs.get(i);
|
||||
if (!first) {
|
||||
ret += ", ";
|
||||
}
|
||||
@@ -349,7 +346,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
timelined = null;
|
||||
loaded = true;
|
||||
try {
|
||||
iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))),new ArrayList<DepthState>(),new ArrayList<Shape>());
|
||||
iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))), new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
@@ -372,7 +369,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
loaded = true;
|
||||
|
||||
if (drawable.getTimeline().frames.isEmpty()) {
|
||||
iconPanel.setImg(null, new ArrayList<DepthState>(),new ArrayList<Shape>());
|
||||
iconPanel.setImg(null, new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
return;
|
||||
}
|
||||
frame = 0;
|
||||
@@ -387,7 +384,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
timelined = null;
|
||||
loaded = true;
|
||||
stillFrame = true;
|
||||
iconPanel.setImg(image,new ArrayList<DepthState>(),new ArrayList<Shape>());
|
||||
iconPanel.setImg(image, new ArrayList<DepthState>(), new ArrayList<Shape>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -449,50 +446,50 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
int height = rect.getHeight();
|
||||
double scale = 1.0;
|
||||
/*if (width > swf.displayRect.getWidth() || height > swf.displayRect.getHeight()) {
|
||||
//scale = (double) swf.displayRect.getWidth() / (double) width;
|
||||
//width = swf.displayRect.getWidth();
|
||||
//scale = (double) swf.displayRect.getWidth() / (double) width;
|
||||
//width = swf.displayRect.getWidth();
|
||||
|
||||
int w1 = width;
|
||||
int h1 = height;
|
||||
int w2 = swf.displayRect.getWidth();
|
||||
int h2 = swf.displayRect.getHeight();
|
||||
int w1 = width;
|
||||
int h1 = height;
|
||||
int w2 = swf.displayRect.getWidth();
|
||||
int h2 = swf.displayRect.getHeight();
|
||||
|
||||
int w;
|
||||
int h = h1 * w2 / w1;
|
||||
if (h > h2) {
|
||||
w = w1 * h2 / h1;
|
||||
h = h2;
|
||||
} else {
|
||||
w = w2;
|
||||
}
|
||||
scale = (double) w / (double) width;
|
||||
int w;
|
||||
int h = h1 * w2 / w1;
|
||||
if (h > h2) {
|
||||
w = w1 * h2 / h1;
|
||||
h = h2;
|
||||
} else {
|
||||
w = w2;
|
||||
}
|
||||
scale = (double) w / (double) width;
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
}*/
|
||||
width = w;
|
||||
height = h;
|
||||
}*/
|
||||
SerializableImage image = new SerializableImage((int) (width / SWF.unitDivisor) + 1,
|
||||
(int) (height / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
|
||||
image.fillTransparent();
|
||||
Matrix m = new Matrix();
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
/*m.translate(-rect.getWidth(), -rect.getHeight());
|
||||
m.scale(scale);
|
||||
m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/
|
||||
m.scale(scale);
|
||||
m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/
|
||||
drawable.getTimeline().toImage(frame, frame, stateUnderCursor, mouseButton, image, m, new ColorTransform());
|
||||
|
||||
Graphics2D gg = (Graphics2D)image.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.green);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
List<DepthState> dss=new ArrayList<>();
|
||||
List<Shape> os=new ArrayList<>();
|
||||
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
|
||||
Graphics2D gg = (Graphics2D) image.getGraphics();
|
||||
gg.setStroke(new BasicStroke(3));
|
||||
gg.setPaint(Color.green);
|
||||
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
List<DepthState> dss = new ArrayList<>();
|
||||
List<Shape> os = new ArrayList<>();
|
||||
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
|
||||
|
||||
//gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
|
||||
for(Shape s:os){
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(s));
|
||||
gg.draw(SHAPERECORD.twipToPixelShape(s));
|
||||
}*/
|
||||
|
||||
|
||||
img = image;
|
||||
} else if (drawable instanceof FontTag) {
|
||||
// only DefineFont tags
|
||||
@@ -517,34 +514,40 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
|
||||
CharacterTag c = swf.characters.get(sndId);
|
||||
if (c instanceof SoundTag) {
|
||||
SoundTag st = (SoundTag) c;
|
||||
final SoundTagPlayer sp = new SoundTagPlayer(st, 1);
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.add(sp);
|
||||
}
|
||||
sp.addListener(new PlayerListener() {
|
||||
final SoundTagPlayer sp;
|
||||
try {
|
||||
sp = new SoundTagPlayer(st, 1);
|
||||
|
||||
@Override
|
||||
public void playingFinished() {
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.remove(sp);
|
||||
}
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.add(sp);
|
||||
}
|
||||
});
|
||||
sp.play();
|
||||
sp.addListener(new PlayerListener() {
|
||||
|
||||
@Override
|
||||
public void playingFinished() {
|
||||
synchronized (ImagePanel.class) {
|
||||
soundPlayers.remove(sp);
|
||||
}
|
||||
}
|
||||
});
|
||||
sp.play();
|
||||
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, "Error during playing sound", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Matrix m = new Matrix();
|
||||
RECT rect= timelined.getTimeline().displayRect;
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
m.scale(1);
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
List<Shape> outlines=new ArrayList<>();
|
||||
timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines);
|
||||
for(int i=0;i<outlines.size();i++){
|
||||
outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i)));
|
||||
}
|
||||
iconPanel.setImg(new SerializableImage(img),objs,outlines);
|
||||
RECT rect = timelined.getTimeline().displayRect;
|
||||
m.translate(-rect.Xmin, -rect.Ymin);
|
||||
m.scale(1);
|
||||
List<DepthState> objs = new ArrayList<>();
|
||||
List<Shape> outlines = new ArrayList<>();
|
||||
timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines);
|
||||
for (int i = 0; i < outlines.size(); i++) {
|
||||
outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i)));
|
||||
}
|
||||
iconPanel.setImg(new SerializableImage(img), objs, outlines);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
||||
@@ -154,7 +154,6 @@ import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.BufferedOutputStream;
|
||||
@@ -176,6 +175,8 @@ import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
@@ -2705,11 +2706,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
previewImagePanel.setTimelined(timelined, swf, fn.getFrame() - 1);
|
||||
} else if (((tagObj instanceof SoundTag) && mainMenu.isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) {
|
||||
showCard(CARDDRAWPREVIEWPANEL);
|
||||
previewImagePanel.setImage(new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB));
|
||||
|
||||
soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE);
|
||||
imagePlayControls.setMedia(soundThread);
|
||||
soundThread.play();
|
||||
previewImagePanel.setImage(new SerializableImage(View.loadImage("sound32")));
|
||||
try {
|
||||
soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE);
|
||||
imagePlayControls.setMedia(soundThread);
|
||||
soundThread.play();
|
||||
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
} else if (((tagObj instanceof FrameNodeItem) && ((FrameNodeItem) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag) || (tagObj instanceof SoundStreamHeadTypeTag)) {
|
||||
((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD);
|
||||
|
||||
@@ -18,13 +18,17 @@ package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.helpers.sound.SoundPlayer;
|
||||
import com.jpexs.helpers.sound.WavPlayer;
|
||||
import com.jpexs.helpers.SoundPlayer;
|
||||
import java.awt.Color;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,9 +40,7 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
|
||||
private Thread thr;
|
||||
private int actualPos = 0;
|
||||
private boolean playing = false;
|
||||
private SoundTag tag;
|
||||
private byte data[];
|
||||
private List<PlayerListener> listeners = new ArrayList<>();
|
||||
|
||||
public void addListener(PlayerListener l) {
|
||||
@@ -55,39 +57,39 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int FRAME_DIVISOR = 1024;
|
||||
private static final int FRAME_DIVISOR = 8000;
|
||||
|
||||
private int loops;
|
||||
private boolean paused = true;
|
||||
private Object myLock = new Object();
|
||||
private final Object playLock = new Object();
|
||||
|
||||
public SoundTagPlayer(SoundTag tag, int loops) {
|
||||
public SoundTagPlayer(SoundTag tag, int loops) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
|
||||
this.tag = tag;
|
||||
this.loops = loops;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(tag.getRawSoundData());
|
||||
tag.getSoundFormat().createWav(bais, baos);
|
||||
this.data = baos.toByteArray();
|
||||
player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getCurrentFrame() {
|
||||
if (player == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!playing) {
|
||||
if (!isPlaying()) {
|
||||
return actualPos;
|
||||
}
|
||||
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
synchronized (playLock) {
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
}
|
||||
return actualPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getTotalFrames() {
|
||||
//System.out.println("getTotalFrames");
|
||||
if (player == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = (int) (player.samplesCount() / FRAME_DIVISOR);
|
||||
|
||||
//System.out.println("/getTotalFrames");
|
||||
@@ -96,39 +98,70 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
|
||||
@Override
|
||||
public synchronized void pause() {
|
||||
if (!playing) {
|
||||
if (!isPlaying()) {
|
||||
paused = true;
|
||||
return;
|
||||
}
|
||||
playing = false;
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
player.stop();
|
||||
|
||||
synchronized (playLock) {
|
||||
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
|
||||
paused = true;
|
||||
player.stop();
|
||||
try {
|
||||
playLock.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void play(boolean async) {
|
||||
if (player != null) {
|
||||
player.stop();
|
||||
}
|
||||
|
||||
player = new WavPlayer(new ByteArrayInputStream(data));
|
||||
final int startPos = actualPos * FRAME_DIVISOR;
|
||||
synchronized (playLock) {
|
||||
if (!paused) {
|
||||
paused = true;
|
||||
player.stop();
|
||||
try {
|
||||
playLock.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
Runnable r = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
player.skip(startPos);
|
||||
player.play();
|
||||
fireFinished();
|
||||
if (loops > 0) {
|
||||
loops--;
|
||||
int startPos = 0;
|
||||
synchronized (playLock) {
|
||||
startPos = actualPos * FRAME_DIVISOR;
|
||||
paused = false;
|
||||
}
|
||||
if (playing && loops > 0) {
|
||||
player.setPosition(startPos);
|
||||
player.play();
|
||||
|
||||
boolean playAgain = false;
|
||||
synchronized (playLock) {
|
||||
playAgain = !paused;
|
||||
paused = true;
|
||||
if (loops > 0) {
|
||||
loops--;
|
||||
}
|
||||
}
|
||||
if (playAgain && loops > 0) {
|
||||
gotoFrame(0);
|
||||
play();
|
||||
run();
|
||||
return;
|
||||
} else {
|
||||
fireFinished();
|
||||
}
|
||||
synchronized (playLock) {
|
||||
playLock.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
playing = true;
|
||||
if (async) {
|
||||
thr = new Thread(r);
|
||||
thr.start();
|
||||
@@ -145,21 +178,20 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
|
||||
@Override
|
||||
public void rewind() {
|
||||
actualPos = 0;
|
||||
gotoFrame(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return playing;
|
||||
return player.isPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void gotoFrame(int frame) {
|
||||
if (playing) {
|
||||
playing = false;
|
||||
player.stop();
|
||||
pause();
|
||||
synchronized (playLock) {
|
||||
actualPos = frame;
|
||||
}
|
||||
actualPos = frame;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.TexturePaint;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
@@ -222,9 +221,13 @@ public class View {
|
||||
* @param name Name of the image
|
||||
* @return loaded Image
|
||||
*/
|
||||
public static Image loadImage(String name) {
|
||||
public static BufferedImage loadImage(String name) {
|
||||
java.net.URL imageURL = View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + name + ".png");
|
||||
return Toolkit.getDefaultToolkit().createImage(imageURL);
|
||||
try {
|
||||
return ImageIO.read(imageURL);
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound32.png
Normal file
BIN
trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -86,9 +86,9 @@ public class PlayerControls extends JPanel implements ActionListener {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
int frame = (int) Math.floor(e.getX() * t.display.getTotalFrames() / (double) progress.getWidth());
|
||||
boolean p = paused;
|
||||
boolean p = t.display.isPlaying();
|
||||
t.display.gotoFrame(frame);
|
||||
if (!p) {
|
||||
if (p) {
|
||||
t.display.play();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,20 +16,12 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.exporters.Matrix;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import java.awt.Point;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
|
||||
@@ -206,8 +206,8 @@ public class Timeline {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void getObjectsOutlines(int frame, int ratio,DepthState stateUnderCursor, int mouseButton, Matrix transformation,List<DepthState> objs,List<Shape> outlines){
|
||||
|
||||
public void getObjectsOutlines(int frame, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List<DepthState> objs, List<Shape> outlines) {
|
||||
Frame fr = this.frames.get(frame);
|
||||
Stack<Clip> clips = new Stack<>();
|
||||
for (int d = this.getMaxDepth(); d >= 0; d--) {
|
||||
@@ -234,8 +234,8 @@ public class Timeline {
|
||||
m = m.preConcatenate(transformation);
|
||||
|
||||
int dframe = 0;
|
||||
if(c instanceof Timelined){
|
||||
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
|
||||
if (c instanceof Timelined) {
|
||||
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
|
||||
if (c instanceof ButtonTag) {
|
||||
ButtonTag bt = (ButtonTag) c;
|
||||
dframe = ButtonTag.FRAME_UP;
|
||||
@@ -249,7 +249,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m);
|
||||
|
||||
|
||||
Area addArea = new Area(cshape);
|
||||
if (currentClip != null) {
|
||||
Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight()));
|
||||
@@ -261,10 +261,10 @@ public class Timeline {
|
||||
clips.push(clip);
|
||||
} else {
|
||||
objs.add(ds);
|
||||
outlines.add(addArea);
|
||||
outlines.add(addArea);
|
||||
}
|
||||
if(c instanceof Timelined){
|
||||
((Timelined)c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
|
||||
if (c instanceof Timelined) {
|
||||
((Timelined) c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,8 +298,8 @@ public class Timeline {
|
||||
m = m.preConcatenate(transformation);
|
||||
|
||||
int dframe = 0;
|
||||
if(c instanceof Timelined){
|
||||
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
|
||||
if (c instanceof Timelined) {
|
||||
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
|
||||
if (c instanceof ButtonTag) {
|
||||
ButtonTag bt = (ButtonTag) c;
|
||||
dframe = ButtonTag.FRAME_UP;
|
||||
@@ -313,7 +313,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m);
|
||||
|
||||
|
||||
Area addArea = new Area(cshape);
|
||||
if (currentClip != null) {
|
||||
Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight()));
|
||||
|
||||
@@ -14,13 +14,11 @@
|
||||
* 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.helpers.sound;
|
||||
package com.jpexs.helpers;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.sound.sampled.Line;
|
||||
@@ -33,51 +31,29 @@ import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class WavPlayer extends SoundPlayer {
|
||||
public class SoundPlayer {
|
||||
|
||||
private Clip clip;
|
||||
private boolean complete = false;
|
||||
private long startPos = 0;
|
||||
|
||||
public WavPlayer(InputStream is) {
|
||||
super(is);
|
||||
try {
|
||||
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
|
||||
} catch (LineUnavailableException ex) {
|
||||
Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
if (clip == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is)));
|
||||
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
|
||||
Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, "Error opening", ex);
|
||||
clip = null;
|
||||
}
|
||||
public SoundPlayer(InputStream is) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
|
||||
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
|
||||
clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long samplesCount() {
|
||||
return clip.getMicrosecondLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
if (clip == null) {
|
||||
return;
|
||||
}
|
||||
clip.setMicrosecondPosition(startPos);//startPos);
|
||||
final WavPlayer t = this;
|
||||
|
||||
final SoundPlayer t = this;
|
||||
clip.addLineListener(new LineListener() {
|
||||
|
||||
@Override
|
||||
public void update(LineEvent event) {
|
||||
if (event.getType() == LineEvent.Type.STOP) {
|
||||
complete = true;
|
||||
startPos = 0;
|
||||
clip.close();
|
||||
//clip.close();
|
||||
|
||||
synchronized (t) {
|
||||
t.notifyAll();
|
||||
}
|
||||
@@ -94,29 +70,31 @@ public class WavPlayer extends SoundPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSamplePosition() {
|
||||
return clip.getMicrosecondPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip(long frames) {
|
||||
startPos = getSamplePosition() + frames;
|
||||
public void setPosition(long frames) {
|
||||
clip.setMicrosecondPosition(frames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
clip.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return !complete;
|
||||
return clip.isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrameRate() {
|
||||
return 1000000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (clip != null) {
|
||||
clip.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 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.helpers.sound;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javazoom.jl.decoder.Bitstream;
|
||||
import javazoom.jl.decoder.Decoder;
|
||||
import javazoom.jl.decoder.Header;
|
||||
import javazoom.jl.decoder.JavaLayerException;
|
||||
import javazoom.jl.decoder.SampleBuffer;
|
||||
import javazoom.jl.player.AudioDevice;
|
||||
import javazoom.jl.player.FactoryRegistry;
|
||||
|
||||
public class MP3Player extends SoundPlayer {
|
||||
|
||||
private Bitstream bitstream;
|
||||
|
||||
private Decoder decoder;
|
||||
|
||||
private AudioDevice audio;
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
private boolean complete = false;
|
||||
|
||||
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);
|
||||
this.sampleCount = sampleCount;
|
||||
this.frameRate = frameRate;
|
||||
}
|
||||
|
||||
private MP3Player(InputStream stream, AudioDevice device) throws JavaLayerException {
|
||||
super(stream);
|
||||
bitstream = new Bitstream(stream);
|
||||
decoder = new Decoder();
|
||||
|
||||
if (device != null) {
|
||||
audio = device;
|
||||
} else {
|
||||
FactoryRegistry r = FactoryRegistry.systemRegistry();
|
||||
audio = r.createAudioDevice();
|
||||
}
|
||||
audio.open(decoder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
try {
|
||||
play(Integer.MAX_VALUE);
|
||||
} catch (JavaLayerException ex) {
|
||||
Logger.getLogger(MP3Player.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean play(int frames) throws JavaLayerException {
|
||||
if (complete) {
|
||||
return false;
|
||||
}
|
||||
boolean ret = true;
|
||||
|
||||
while (frames-- > 0 && ret) {
|
||||
ret = decodeFrame();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
// last frame, ensure all data flushed to the audio device.
|
||||
AudioDevice out = audio;
|
||||
if (out != null) {
|
||||
out.flush();
|
||||
synchronized (this) {
|
||||
complete = (!closed);
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void skip(long samples) {
|
||||
if (complete) {
|
||||
return;
|
||||
}
|
||||
long endPosition = positionSamples + samples;
|
||||
if (samples == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
Header h = bitstream.readFrame();
|
||||
if (h == null) {
|
||||
complete = true;
|
||||
return;
|
||||
}
|
||||
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
|
||||
positionSamples += output.getBufferLength();
|
||||
positionFrames++;
|
||||
bitstream.closeFrame();
|
||||
if (positionSamples >= endPosition) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ingore
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void stop() {
|
||||
AudioDevice out = audio;
|
||||
if (out != null) {
|
||||
closed = true;
|
||||
audio = null;
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isPlaying() {
|
||||
return !complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSamplePosition() {
|
||||
return positionSamples;
|
||||
}
|
||||
|
||||
private boolean decodeFrame() throws JavaLayerException {
|
||||
try {
|
||||
AudioDevice out = audio;
|
||||
if (out == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Header h = bitstream.readFrame();
|
||||
if (h == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
|
||||
positionSamples += output.getBufferLength();
|
||||
positionFrames++;
|
||||
|
||||
synchronized (this) {
|
||||
out = audio;
|
||||
if (out != null) {
|
||||
out.write(output.getBuffer(), 0, output.getBufferLength());
|
||||
}
|
||||
}
|
||||
|
||||
bitstream.closeFrame();
|
||||
} catch (RuntimeException ex) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long samplesCount() {
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,10 +20,10 @@ import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
Reference in New Issue
Block a user