🔀 Merge branch 'release/0.2.0' into stable
Some checks failed
Check & fix styling / php-cs-fixer (push) Has been cancelled
Tests / P8 - prefer-lowest - ubuntu-latest (push) Has been cancelled
Tests / P8 - prefer-stable - ubuntu-latest (push) Has been cancelled
Tests / P8 - prefer-lowest - windows-latest (push) Has been cancelled
Tests / P8 - prefer-stable - windows-latest (push) Has been cancelled
Some checks failed
Check & fix styling / php-cs-fixer (push) Has been cancelled
Tests / P8 - prefer-lowest - ubuntu-latest (push) Has been cancelled
Tests / P8 - prefer-stable - ubuntu-latest (push) Has been cancelled
Tests / P8 - prefer-lowest - windows-latest (push) Has been cancelled
Tests / P8 - prefer-stable - windows-latest (push) Has been cancelled
This commit is contained in:
commit
42c112c942
5 changed files with 119 additions and 7 deletions
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
All notable changes to `ffmpeg-mappable-media` will be documented in this file.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- ✨ Support attachments
|
||||
|
||||
## 0.1.3
|
||||
|
||||
- ✨ Support progress listeners
|
||||
|
|
|
|||
47
README.md
47
README.md
|
|
@ -98,7 +98,7 @@ use FFMpeg\Format\Video\X264;
|
|||
MappableMedia::make($ffmpeg)
|
||||
->addInput('input.mkv')
|
||||
->map()
|
||||
->saveAs('output.mk')
|
||||
->saveAs('output.mkv')
|
||||
->stream()->setCodec(new X264())->saveStream()
|
||||
->saveMap()
|
||||
->save()
|
||||
|
|
@ -112,7 +112,7 @@ The `map` and `stream` methods can take an optional callback, allowing you to se
|
|||
MappableMedia::make($ffmpeg)
|
||||
->addInput('input.mkv')
|
||||
->map(function (Map $map) {
|
||||
$map->saveAs('output.mk')
|
||||
$map->saveAs('output.mkv')
|
||||
->stream(function (Stream $stream) {
|
||||
$stream->copy()->setInput('0:0');
|
||||
});
|
||||
|
|
@ -129,7 +129,7 @@ It is possible to set a listener on the individual streams, using the Format cla
|
|||
MappableMedia::make($ffmpeg)
|
||||
->addInput('input.mkv')
|
||||
->map()
|
||||
->saveAs('output.mk')
|
||||
->saveAs('output.mkv')
|
||||
->stream()->copy()->saveStream()
|
||||
->saveMap()
|
||||
->on('progress', function (MappableMedia $media, int $percent, int $remaining, int $rate) {
|
||||
|
|
@ -138,6 +138,47 @@ MappableMedia::make($ffmpeg)
|
|||
->save()
|
||||
```
|
||||
|
||||
### Attachments
|
||||
|
||||
Some formats (mkv, for example) support arbitrary data attachments. These can be used as cover art, fonts for subtitles, or any arbitrary data.
|
||||
|
||||
FFMpeg does support attachments as an additional input. This works well for images, but can be finicky for other file types. Because of this, FFMpeg also supports an `-attach` flag which can be used to explicitly attach a new stream.
|
||||
|
||||
Due to the way FFMpeg handles `-attach` differently than `-i`, these need to be added as streams to a specific map, rather than the whole media. Here are a few examples.
|
||||
|
||||
```php
|
||||
MappableMedia::make($ffmpeg)
|
||||
->addInput('input.mkv')
|
||||
->map()
|
||||
->saveAs('output.mkv')
|
||||
->stream()->copy()->saveStream()
|
||||
->attach('image.jpg')
|
||||
->mime('image/jpeg')
|
||||
->addMetadata('filename', 'cover.jpg')
|
||||
->saveAttachment()
|
||||
->saveMap()
|
||||
->save();
|
||||
```
|
||||
|
||||
In this example, we added cover art to the file. Notice the use of the `mime` method to specify the mime-type. **This must always be done**. Note that we also specified a different filename so that the media player would recognize it as cover art. If you don't specify a filename, the original will be used.
|
||||
|
||||
```php
|
||||
MappableMedia::make($ffmpeg)
|
||||
->addInput('input.mkv')
|
||||
->addInput('subs.ass')
|
||||
->map()
|
||||
->saveAs('output.mkv')
|
||||
->stream()->copy()->saveStream()
|
||||
->stream()->setInput('1:0')->copy()->saveStream()
|
||||
->attach(verdana.ttf')
|
||||
->mime('application/x-truetype-font')
|
||||
->saveAttachment()
|
||||
->saveMap()
|
||||
->save();
|
||||
```
|
||||
|
||||
In this example, we've added a font, which is likely referenced in the subtitle file, `subs.ass`.
|
||||
|
||||
## Future Plans
|
||||
|
||||
- [ ] Add listeners that return all the stdin/stderr
|
||||
|
|
|
|||
46
src/Attachment.php
Normal file
46
src/Attachment.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Danjones\FFMpeg;
|
||||
|
||||
use FFMpeg\Format\FormatInterface;
|
||||
|
||||
class Attachment extends Stream
|
||||
{
|
||||
protected string $input = '';
|
||||
|
||||
public function __construct(Map $map, string $file = '')
|
||||
{
|
||||
$this->map = $map;
|
||||
$this->input = $file;
|
||||
// Shouldn't be necessary, but just in case
|
||||
$this->codec = new Format\Copy();
|
||||
}
|
||||
|
||||
public function mime(string $mime): static
|
||||
{
|
||||
return $this->addMetadata('mimetype', $mime);
|
||||
}
|
||||
|
||||
public function setCodec(FormatInterface $codec): static
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function parseCodec(): static
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function saveAttachment(): Map
|
||||
{
|
||||
return $this->saveStream();;
|
||||
}
|
||||
|
||||
public function buildCommand(int $idx = 0): array
|
||||
{
|
||||
$commands = parent::buildCommand($idx);
|
||||
$commands[0] = '-attach';
|
||||
|
||||
return $commands;
|
||||
}
|
||||
}
|
||||
25
src/Map.php
25
src/Map.php
|
|
@ -13,6 +13,8 @@ class Map
|
|||
protected string $path;
|
||||
/** @var Stream[] */
|
||||
protected array $streams = [];
|
||||
/** @var Attachment[] */
|
||||
protected array $attachments = [];
|
||||
/** @var AbstractProgressListener[] */
|
||||
protected array $listeners = [];
|
||||
|
||||
|
|
@ -35,9 +37,8 @@ class Map
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function stream(callable $callback = null): Stream|static
|
||||
protected function doStream(Stream $stream, callable $callback = null): Stream|static
|
||||
{
|
||||
$stream = new Stream($this);
|
||||
if (!$callback) {
|
||||
return $stream;
|
||||
}
|
||||
|
|
@ -48,8 +49,24 @@ class Map
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function stream(callable $callback = null): Stream|static
|
||||
{
|
||||
return $this->doStream(new Stream($this), $callback);
|
||||
}
|
||||
|
||||
public function attach(string $file = '', callable $callback = null): Attachment|static
|
||||
{
|
||||
return $this->doStream(new Attachment($this, $file), $callback);
|
||||
}
|
||||
|
||||
public function saveStream(Stream $stream): static
|
||||
{
|
||||
if ($stream instanceof Attachment){
|
||||
$this->attachments[] = $stream;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->streams[] = $stream;
|
||||
$format = $stream->getCodec();
|
||||
if ($format instanceof ProgressableInterface) {
|
||||
|
|
@ -72,7 +89,9 @@ class Map
|
|||
public function buildCommand(): array
|
||||
{
|
||||
$commands = [];
|
||||
foreach ($this->streams as $idx => $stream) {
|
||||
$streams = $this->streams;
|
||||
array_push($streams, ...$this->attachments);
|
||||
foreach ($streams as $idx => $stream) {
|
||||
array_push($commands, ...$stream->buildCommand($idx));
|
||||
}
|
||||
foreach ($this->metadata as $k => $v) {
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@ class MappableMedia extends AbstractMediaType implements EventEmitterInterface
|
|||
|
||||
public function getFinalCommand(): string
|
||||
{
|
||||
return implode(' ', $this->buildCommand());
|
||||
$proc = $this->driver->getProcessBuilderFactory()->create($this->buildCommand());
|
||||
|
||||
return $proc->getCommandLine();
|
||||
}
|
||||
|
||||
public function map(callable $callback = null): Map|static
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue