117 lines
3.5 KiB
PHP
117 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace swf2ass;
|
|
|
|
|
|
use swf\SWF;
|
|
use swf2ass\actions\ActionList;
|
|
|
|
class SWFProcessor extends SWFTreeProcessor {
|
|
const BACKGROUND_OBJECT_ID = 0;
|
|
const BACKGROUND_OBJECT_DEPTH = 0;
|
|
|
|
|
|
private FillStyleRecord $background;
|
|
|
|
private float $frameRate;
|
|
|
|
private ?AudioStream $audio = null;
|
|
|
|
private Rectangle $viewPort;
|
|
|
|
private SWF $swf;
|
|
|
|
private int $expectedFrameCount;
|
|
|
|
public function __construct(SWF $swf) {
|
|
$this->swf = $swf;
|
|
parent::__construct(0, null);
|
|
|
|
$this->background = new FillStyleRecord(new Color(255, 255, 255));
|
|
|
|
$this->viewPort = Rectangle::fromArray($this->swf->header["frameSize"]);
|
|
|
|
$this->frameRate = $this->swf->header["frameRate"];
|
|
$this->expectedFrameCount = $this->swf->header["frameCount"];
|
|
}
|
|
|
|
public function getExpectedFrameCount() : int {
|
|
return $this->expectedFrameCount;
|
|
}
|
|
|
|
protected function current(): ?array {
|
|
return isset($this->swf->tags[$this->index]) ? $this->swf->parseTag($this->swf->tags[$this->index]) : null;
|
|
}
|
|
|
|
|
|
public function getFrameRate(): float {
|
|
return $this->frameRate;
|
|
}
|
|
|
|
public function getViewPort(): Rectangle {
|
|
return $this->viewPort;
|
|
}
|
|
|
|
public function getAudio() : ?AudioStream {
|
|
return $this->audio;
|
|
}
|
|
|
|
protected function process(ActionList $actionList): ?string {
|
|
$node = $this->current();
|
|
if ($node === null) {
|
|
return null;
|
|
}
|
|
|
|
switch ($node["tagType"]) {
|
|
case "SetBackgroundColor":
|
|
//TODO: implement Gradient
|
|
$this->background = new FillStyleRecord(Color::fromArray($node["backgroundColor"]));
|
|
return $node["tagType"];
|
|
case "SoundStreamHead":
|
|
case "SoundStreamHead2":
|
|
if($this->loops > 0){
|
|
break;
|
|
}
|
|
$this->audio = AudioStream::fromSoundStreamHeadTag($node);
|
|
return $node["tagType"];
|
|
case "DefineSound":
|
|
if($this->loops > 0){
|
|
break;
|
|
}
|
|
$this->audio = new AudioStream(0, 0, 0, 0);
|
|
$this->audio->setStartFrame($this->getFrame());
|
|
//TODO $this->audio = (object)["node" => $node, "start" => $this->getFrame(), "content" => []];
|
|
return $node["tagType"];
|
|
case "SoundStreamBlock":
|
|
if($this->loops > 0){
|
|
break;
|
|
}
|
|
if($this->audio !== null){
|
|
if($this->audio->getStartFrame() === null){
|
|
$this->audio->setStartFrame($this->getFrame());
|
|
}
|
|
$this->audio->addStreamBlock($node);
|
|
}
|
|
return $node["tagType"];
|
|
}
|
|
|
|
return parent::process($actionList);
|
|
}
|
|
|
|
public function nextFrameOutput(): ?FrameInformation {
|
|
$frame = $this->nextFrame();
|
|
|
|
if ($frame === null) {
|
|
return null;
|
|
}
|
|
|
|
if(!$this->isPlaying() and ($this->audio === null or $this->audio->getStartFrame() === null) or $this->getFrame() === 1){ //Force play till finding audio, or first frame is 0
|
|
$this->playing = true;
|
|
}
|
|
|
|
//TODO: actions?
|
|
|
|
$frame->addChild(self::BACKGROUND_OBJECT_DEPTH, new ViewFrame(self::BACKGROUND_OBJECT_ID, new DrawPathList([DrawPath::fill($this->background, new Shape($this->getViewPort()->draw()))])));
|
|
return new FrameInformation($this->frame - 1, $this->frameRate, $frame);
|
|
}
|
|
} |