map = $map; } public function setInput(string $input): static { $this->input = $input; return $this; } public function addFlag(string $key, string $value): static { $this->flags[$key] = $value; return $this; } public function setCodec(FormatInterface $codec): static { $this->codec = $codec; return $this; } public function video(string $codec, callable $callback = null): static { $this->setCodec(new Format\DefaultVideo($codec)); if ($callback) { return $this->editCodec($callback); } return $this; } public function audio(string $codec, callable $callback = null): static { $this->setCodec(new Format\DefaultAudio($codec)); if ($callback) { return $this->editCodec($callback); } return $this; } public function subtitle(string $codec, callable $callback = null): static { $this->setCodec(new Format\DefaultSubtitle($codec)); if ($callback) { return $this->editCodec($callback); } return $this; } public function copy(): static { return $this->setCodec(new Format\Copy()); } public function getCodec(): FormatInterface { return $this->codec; } public function editCodec(callable $callback): static { $callback($this->codec); return $this; } protected function parseCodec(): static { if ($this->codec instanceof VideoInterface) { $this->parseVideo(); } elseif ($this->codec instanceof AudioInterface) { $this->parseAudio(); } elseif ($this->codec instanceof Format\SubtitleInterface) { $this->parseSubtitle(); } elseif ($this->codec instanceof Format\Copy) { $this->addFlag('c', 'copy'); } $this->parseExtras($this->codec->getExtraParams()); return $this; } protected function parseSubtitle(): static { if (null !== ($codec = $this->codec->getSubtitleCodec())) { $this->addFlag('c', $codec); } return $this; } protected function parseAudio(): static { if (null !== ($codec = $this->codec->getAudioCodec())) { $this->addFlag('c', $codec); } if (null !== ($kb = $this->codec->getAudioKiloBitrate())) { $this->addFlag('b', "{$kb}k"); } if (null !== ($channels = $this->codec->getAudioChannels())) { $this->addFlag('ac', $channels); } return $this; } protected function parseVideo(): static { if (null !== ($codec = $this->codec->getVideoCodec())) { $this->addFlag('c', $codec); } if (0 !== ($kb = $this->codec->getKiloBitrate())) { $this->addFlag('b', "{$kb}k"); } $this->parseExtras($this->codec->getAdditionalParameters()); return $this; } protected function parseExtras (?array $params): void { if (is_null($params)) { return; } reset($params); while(null !== key($params)) { $key = current($params); $value = next($params); if (null == key($params)) { continue; } $this->addFlag(ltrim($key, '-k'), $value); } } public function saveStream(): Map { $this->map->saveStream($this); return $this->map; } public function buildCommand(int $idx = 0): array { $this->parseCodec(); $commands = []; $commands[] = '-map'; $commands[] = $this->input; foreach ($this->flags as $k => $v) { array_push($commands, "-{$k}:{$idx}", $v); } foreach ($this->metadata as $k => $v) { array_push($commands, "-metadata:s:{$idx}", "{$k}={$v}"); } return $commands; } }