getFFMpegDriver(), $ffmpeg->getFFProbe()); } public function filters() { return $this->filters; } public function addInput(string $path): static { if (empty($this->inputs)) { $this->pathfile = $path; } $this->inputs[] = $path; return $this; } /** * @return string[] */ public function getInitialParameters(): array { return $this->initialParameters; } /** * @param string[] $initialParameters */ public function setInitialParameters(array $initialParameters): static { $this->initialParameters = $initialParameters; return $this; } /** * @return string[] */ public function getAdditionalParameters(): array { return $this->additionalParameters; } /** * @param string[] $additionalParameters */ public function setAdditionalParameters(array $additionalParameters): static { $this->additionalParameters = $additionalParameters; return $this; } /** * @return string[] */ public function getInputs(): array { return $this->inputs; } public function getInputsCount(): int { return count($this->inputs); } public function getFinalCommand(): string { return implode(' ', $this->buildCommand()); } public function map(callable $callback = null): Map|static { $map = new Map($this); if (!$callback) { return $map; } $callback($map); $this->saveMap($map); return $this; } public function saveMap(Map $map): static { $this->maps[] = $map; return $this; } /** * Select the streams for output. * * @param string[] $outs output labels of the -filter_complex part * @param FormatInterface $format format of the output file * @param string $outputFilename output filename * @param bool $forceDisableAudio * @param bool $forceDisableVideo * * @return $this * @todo Redo all of this. * @see https://ffmpeg.org/ffmpeg.html#Manual-stream-selection */ private function map2( array $outs, FormatInterface $format, $outputFilename, $forceDisableAudio = false, $forceDisableVideo = false ) { $commands = []; foreach ($outs as $label) { $commands[] = '-map'; $commands[] = $label; } // Apply format params. $commands = array_merge( $commands, $this->applyFormatParams($format, $forceDisableAudio, $forceDisableVideo) ); // Set output file. $commands[] = $outputFilename; // Create a listener. if ($format instanceof ProgressableInterface) { $listener = $format->createProgressListener($this, $this->ffprobe, 1, 1, 0); $this->listeners = array_merge($this->listeners, $listener); } $this->mapCommands = array_merge($this->mapCommands, $commands); return $this; } /** * Apply added filters and execute ffmpeg command. * * @throws RuntimeException */ public function save(): void { $command = $this->buildCommand(); try { $this->driver->command($command, false, $this->listeners); } catch (ExecutionFailureException $e) { throw new RuntimeException('Encoding failed', $e->getCode(), $e); } } /** * @param bool $forceDisableAudio * @param bool $forceDisableVideo * * @return array * @todo Redo it all */ protected function applyFormatParams( FormatInterface $format, $forceDisableAudio = false, $forceDisableVideo = false ) { // Set format params. $commands = []; if (!$forceDisableVideo && $format instanceof VideoInterface) { if (null !== $format->getVideoCodec()) { $commands[] = '-vcodec'; $commands[] = $format->getVideoCodec(); } // If the user passed some additional format parameters. if (null !== $format->getAdditionalParameters()) { $commands = array_merge($commands, $format->getAdditionalParameters()); } } if (!$forceDisableAudio && $format instanceof AudioInterface) { if (null !== $format->getAudioCodec()) { $commands[] = '-acodec'; $commands[] = $format->getAudioCodec(); } if (null !== $format->getAudioKiloBitrate()) { $commands[] = '-b:a'; $commands[] = $format->getAudioKiloBitrate().'k'; } if (null !== $format->getAudioChannels()) { $commands[] = '-ac'; $commands[] = $format->getAudioChannels(); } } // If the user passed some extra parameters. if ($format->getExtraParams()) { $commands = array_merge($commands, $format->getExtraParams()); } return $commands; } /** * @return array */ protected function buildCommand() { $globalOptions = ['threads', 'filter_threads', 'filter_complex_threads']; return array_merge( ['-y'], $this->buildConfiguredGlobalOptions($globalOptions), $this->getInitialParameters(), $this->buildInputsPart($this->inputs), $this->buildMaps($this->maps), $this->getAdditionalParameters() ); } /** * @param string[] $optionNames * * @return array */ protected function buildConfiguredGlobalOptions($optionNames) { $commands = []; foreach ($optionNames as $optionName) { if (!$this->driver->getConfiguration()->has('ffmpeg.'.$optionName)) { continue; } $commands[] = '-'.$optionName; $commands[] = $this->driver->getConfiguration()->get('ffmpeg.'.$optionName); } return $commands; } /** * Build inputs part of the ffmpeg command. * * @param string[] $inputs */ protected function buildInputsPart(array $inputs): array { $commands = []; foreach ($inputs as $input) { $commands[] = '-i'; $commands[] = $input; } return $commands; } /** * @param Map[] $maps */ protected function buildMaps(array $maps): array { $commands = []; foreach($maps as $map) { array_push($commands, ...$map->buildCommand()); } return $commands; } }