200 lines
4.4 KiB
PHP
200 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace Danjones\FFMpeg;
|
|
|
|
use FFMpeg\Format\AudioInterface;
|
|
use FFMpeg\Format\FormatInterface;
|
|
use FFMpeg\Format\ProgressListener\AbstractProgressListener;
|
|
use FFMpeg\Format\ProgressableInterface;
|
|
use FFMpeg\Format\VideoInterface;
|
|
|
|
class Stream
|
|
{
|
|
use Traits\HasMetadata;
|
|
|
|
protected Map $map;
|
|
protected FormatInterface $codec;
|
|
protected string $input = '0:0';
|
|
protected array $flags = [];
|
|
|
|
public function __construct(Map $map)
|
|
{
|
|
$this->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;
|
|
}
|
|
}
|