| 
									
										
										
										
											2022-08-23 15:25:27 -05:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Danjones\FFMpeg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 16:55:43 -05:00
										 |  |  | use FFMpeg\Format\AudioInterface; | 
					
						
							| 
									
										
										
										
											2022-08-23 15:25:27 -05:00
										 |  |  | use FFMpeg\Format\FormatInterface; | 
					
						
							| 
									
										
										
										
											2022-08-23 16:55:43 -05:00
										 |  |  | use FFMpeg\Format\ProgressListener\AbstractProgressListener; | 
					
						
							|  |  |  | use FFMpeg\Format\ProgressableInterface; | 
					
						
							|  |  |  | use FFMpeg\Format\VideoInterface; | 
					
						
							| 
									
										
										
										
											2022-08-23 15:25:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 16:55:43 -05:00
										 |  |  |     // @todo add hlper methods for setting codec
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function getCodec(): FormatInterface | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->codec; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function editCodec(callable $callback): static | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $callback($this->codec); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 15:25:27 -05:00
										 |  |  |     protected function parseCodec(): static | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-08-23 16:55:43 -05:00
										 |  |  |         if ($this->codec instanceof VideoInterface) { | 
					
						
							|  |  |  |             return $this->parseVideo(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($this->codec instanceof AudioInterface) { | 
					
						
							|  |  |  |             return $this->parseAudio(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // @todo add subtitles
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->addFlag('c', 'copy'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function parseAudio(): static | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (null !== ($codec = $format->getAudioCodec())) { | 
					
						
							|  |  |  |             $this->addFlag('c', $codec); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (null !== ($kb = $format->getAudioKiloBitrate())) { | 
					
						
							|  |  |  |             $this->addFlag('b', "{$kb}k"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (null !== ($channels = $format->getAudioChannels())) { | 
					
						
							|  |  |  |             $this->addFlag('ac', $channels); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function parseVideo(): static | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (null !== ($codec = $format->getVideoCodec())) { | 
					
						
							|  |  |  |             $this->addFlag('c', $codec); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (0 !== ($kb = $format->getKiloBitrate())) { | 
					
						
							|  |  |  |             $this->addFlag('b', "{$kb}k"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If the user passed some additional format parameters.
 | 
					
						
							|  |  |  |         if (null !== ($params = $format->getAdditionalParameters())) { | 
					
						
							|  |  |  |             reset($params); | 
					
						
							|  |  |  |             while(null !== key($params)) { | 
					
						
							|  |  |  |                 $key = current($params); | 
					
						
							|  |  |  |                 $value = next($params); | 
					
						
							|  |  |  |                 if (null == key($params)) { | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 $this->addFlag(ltrim($key, '-k'), $value); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-23 15:25:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |