swf2ass/src/SWFProcessor.php

91 lines
2.9 KiB
PHP

<?php
namespace swf2ass;
class SWFProcessor extends SWFTreeProcessor {
const BACKGROUND_OBJECT_ID = 0;
const BACKGROUND_OBJECT_DEPTH = 0;
private FillStyleRecord $background;
private float $frameRate;
private $audio = null;
private Rectangle $viewPort;
public function __construct(\DOMElement $root) {
parent::__construct(0, $root);
$this->background = new FillStyleRecord(new Color(255, 255, 255));
$rect = $root->getElementsByTagName("size")->item(0)->getElementsByTagName("Rectangle")->item(0);
if ($rect instanceof \DOMElement and $rect->nodeName === "Rectangle") {
$this->viewPort = Rectangle::fromXML($rect);
} else {
throw new \Exception("Could not find viewport");
}
$this->frameRate = $root->getAttribute("framerate");
}
public function getFrameRate(): float {
return $this->frameRate;
}
public function getViewPort(): Rectangle {
return $this->viewPort;
}
public function getAudio() {
return $this->audio;
}
protected function process(): ?string {
$node = $this->current();
if ($node === null) {
return null;
}
switch ($node->nodeName) {
case "SetBackgroundColor":
//TODO: implement Gradient
$this->background = new FillStyleRecord(Color::fromXML($node->getElementsByTagName("color")->item(0)->getElementsByTagName("Color")->item(0)));
return $node->nodeName;
case "SoundStreamHead":
case "SoundStreamHead2":
$this->audio = (object)["node" => $node, "start" => null, "content" => [],];
return $node->nodeName;
case "DefineSound":
$this->audio = (object)["node" => $node, "start" => $this->getFrame(), "content" => []];
return $node->nodeName;
case "SoundStreamBlock":
if ($this->audio !== null) {
if ($this->audio->start === null) {
$this->audio->start = $this->getFrame();
}
//$audio .= substr($data, 2);
$this->audio->content[] = [$this->getFrame(), base64_decode(trim($node->textContent))];
}
return $node->nodeName;
}
return parent::process();
}
public function nextFrameOutput(): ?FrameInformation {
$actions = $actions ?? new ActionList();
$frame = $this->nextFrame($actions);
if ($frame === null) {
return null;
}
//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);
}
}