mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-26 22:00:45 +00:00
Added #2132 Show and export streamed sound (SoundStreamHead/SoundStreamBlock) in frame ranges
Fixed #1194 FLA Export - stream sound export
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2023 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.Openable;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundStreamFrameRange implements TreeItem, SoundTag {
|
||||
public int startFrame;
|
||||
public int endFrame;
|
||||
public List<SoundStreamBlockTag> blocks = new ArrayList<>();
|
||||
|
||||
private final SoundStreamHeadTypeTag head;
|
||||
|
||||
public SoundStreamFrameRange(SoundStreamHeadTypeTag head) {
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Openable getOpenable() {
|
||||
return head.getOpenable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundExportFormat getExportFormat() {
|
||||
return head.getExportFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
return false; //??
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundRate() {
|
||||
return head.getSoundRate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundType() {
|
||||
return head.getSoundType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
ByteArrayRange data = block.streamSoundData;
|
||||
if (getSoundFormatId() == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(data.getSubRange(4, data.getLength() - 4));
|
||||
} else {
|
||||
ret.add(data);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoundFormatId() {
|
||||
return head.getSoundFormatId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalSoundSampleCount() {
|
||||
return blocks.size() * head.getSoundSampleCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSoundSize() {
|
||||
return head.getSoundSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterExportFileName() {
|
||||
return head.getCharacterExportFileName() + "_" + (startFrame + 1) + "-" + (endFrame + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SoundStreamBlocks";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundFormat getSoundFormat() {
|
||||
return head.getSoundFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSize(boolean soundSize) {
|
||||
//?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundType(boolean soundType) {
|
||||
//?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundSampleCount(long soundSampleCount) {
|
||||
//?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundCompression(int soundCompression) {
|
||||
//?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoundRate(int soundRate) {
|
||||
//?
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return head.getCharacterId();
|
||||
}
|
||||
|
||||
public SoundStreamHeadTypeTag getHead() {
|
||||
return head;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SoundStreamBlocks (frame " + (startFrame + 1) + " - " + (endFrame + 1) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return head.isReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFlaExportName() {
|
||||
return head.getFlaExportName() + "_" + (startFrame + 1) + "-" + (endFrame + 1);
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ public class Timeline {
|
||||
|
||||
private final Map<ASMSource, Integer> actionFrames = new HashMap<>();
|
||||
|
||||
private final Map<Integer, List<SoundStreamBlockTag>> soundStramBlocks = new LinkedHashMap<>();
|
||||
private final Map<Integer, List<SoundStreamFrameRange>> soundStreamRanges = new LinkedHashMap<>();
|
||||
|
||||
private AS2Package as2RootPackage;
|
||||
|
||||
@@ -174,9 +174,9 @@ public class Timeline {
|
||||
return depthMaxFrame;
|
||||
}
|
||||
|
||||
public List<SoundStreamBlockTag> getSoundStreamBlocks(SoundStreamHeadTypeTag head) {
|
||||
public List<SoundStreamFrameRange> getSoundStreamBlocks(SoundStreamHeadTypeTag head) {
|
||||
ensureInitialized();
|
||||
return soundStramBlocks.get(head.getCharacterId());
|
||||
return soundStreamRanges.get(head.getCharacterId());
|
||||
}
|
||||
|
||||
public Tag getParentTag() {
|
||||
@@ -194,7 +194,7 @@ public class Timeline {
|
||||
asmSources.clear();
|
||||
asmSourceContainers.clear();
|
||||
actionFrames.clear();
|
||||
soundStramBlocks.clear();
|
||||
soundStreamRanges.clear();
|
||||
otherTags.clear();
|
||||
this.id = id;
|
||||
this.swf = swf;
|
||||
@@ -576,13 +576,23 @@ public class Timeline {
|
||||
}
|
||||
|
||||
private void populateSoundStreamBlocks(int containerId, Iterable<Tag> tags) {
|
||||
List<SoundStreamBlockTag> blocks = null;
|
||||
List<SoundStreamFrameRange> ranges = null;
|
||||
SoundStreamFrameRange range = null;
|
||||
final int MIN_NUM_FRAMES_NO_SOUND = 2;
|
||||
int numFramesNoSound = MIN_NUM_FRAMES_NO_SOUND;
|
||||
boolean frameHasSound = false;
|
||||
int frame = 0;
|
||||
SoundStreamHeadTypeTag head = null;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
SoundStreamHeadTypeTag head = (SoundStreamHeadTypeTag) t;
|
||||
head = (SoundStreamHeadTypeTag) t;
|
||||
head.setCharacterId(containerId);
|
||||
blocks = new ArrayList<>();
|
||||
soundStramBlocks.put(containerId, blocks);
|
||||
ranges = new ArrayList<>();
|
||||
range = new SoundStreamFrameRange(head);
|
||||
range.startFrame = -1;
|
||||
range.endFrame = -1;
|
||||
numFramesNoSound = MIN_NUM_FRAMES_NO_SOUND;
|
||||
soundStreamRanges.put(containerId, ranges);
|
||||
continue;
|
||||
}
|
||||
if (t instanceof DefineExternalStreamSound) {
|
||||
@@ -595,14 +605,41 @@ public class Timeline {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
populateSoundStreamBlocks(sprite.getCharacterId(), sprite.getTags());
|
||||
}
|
||||
|
||||
if (t instanceof ShowFrameTag) {
|
||||
frame++;
|
||||
if (frameHasSound) {
|
||||
numFramesNoSound = 0;
|
||||
} else {
|
||||
numFramesNoSound++;
|
||||
}
|
||||
frameHasSound = false;
|
||||
}
|
||||
|
||||
if (blocks == null) {
|
||||
if (ranges == null) {
|
||||
continue;
|
||||
}
|
||||
if (range == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t instanceof SoundStreamBlockTag) {
|
||||
blocks.add((SoundStreamBlockTag) t);
|
||||
}
|
||||
if (t instanceof SoundStreamBlockTag) {
|
||||
if (numFramesNoSound >= MIN_NUM_FRAMES_NO_SOUND && range.endFrame > -1) {
|
||||
ranges.add(range);
|
||||
range = new SoundStreamFrameRange(head);
|
||||
range.startFrame = -1;
|
||||
range.endFrame = -1;
|
||||
}
|
||||
range.blocks.add((SoundStreamBlockTag) t);
|
||||
if (range.startFrame == -1) {
|
||||
range.startFrame = frame;
|
||||
}
|
||||
range.endFrame = frame;
|
||||
frameHasSound = true;
|
||||
}
|
||||
}
|
||||
if (range != null && ranges != null && range.endFrame > -1) {
|
||||
ranges.add(range);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user