🔀 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.
|
All notable changes to `ffmpeg-mappable-media` will be documented in this file.
|
||||||
|
|
||||||
|
## 0.2.0
|
||||||
|
|
||||||
|
- ✨ Support attachments
|
||||||
|
|
||||||
## 0.1.3
|
## 0.1.3
|
||||||
|
|
||||||
- ✨ Support progress listeners
|
- ✨ Support progress listeners
|
||||||
|
|
|
||||||
47
README.md
47
README.md
|
|
@ -98,7 +98,7 @@ use FFMpeg\Format\Video\X264;
|
||||||
MappableMedia::make($ffmpeg)
|
MappableMedia::make($ffmpeg)
|
||||||
->addInput('input.mkv')
|
->addInput('input.mkv')
|
||||||
->map()
|
->map()
|
||||||
->saveAs('output.mk')
|
->saveAs('output.mkv')
|
||||||
->stream()->setCodec(new X264())->saveStream()
|
->stream()->setCodec(new X264())->saveStream()
|
||||||
->saveMap()
|
->saveMap()
|
||||||
->save()
|
->save()
|
||||||
|
|
@ -112,7 +112,7 @@ The `map` and `stream` methods can take an optional callback, allowing you to se
|
||||||
MappableMedia::make($ffmpeg)
|
MappableMedia::make($ffmpeg)
|
||||||
->addInput('input.mkv')
|
->addInput('input.mkv')
|
||||||
->map(function (Map $map) {
|
->map(function (Map $map) {
|
||||||
$map->saveAs('output.mk')
|
$map->saveAs('output.mkv')
|
||||||
->stream(function (Stream $stream) {
|
->stream(function (Stream $stream) {
|
||||||
$stream->copy()->setInput('0:0');
|
$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)
|
MappableMedia::make($ffmpeg)
|
||||||
->addInput('input.mkv')
|
->addInput('input.mkv')
|
||||||
->map()
|
->map()
|
||||||
->saveAs('output.mk')
|
->saveAs('output.mkv')
|
||||||
->stream()->copy()->saveStream()
|
->stream()->copy()->saveStream()
|
||||||
->saveMap()
|
->saveMap()
|
||||||
->on('progress', function (MappableMedia $media, int $percent, int $remaining, int $rate) {
|
->on('progress', function (MappableMedia $media, int $percent, int $remaining, int $rate) {
|
||||||
|
|
@ -138,6 +138,47 @@ MappableMedia::make($ffmpeg)
|
||||||
->save()
|
->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
|
## Future Plans
|
||||||
|
|
||||||
- [ ] Add listeners that return all the stdin/stderr
|
- [ ] 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;
|
protected string $path;
|
||||||
/** @var Stream[] */
|
/** @var Stream[] */
|
||||||
protected array $streams = [];
|
protected array $streams = [];
|
||||||
|
/** @var Attachment[] */
|
||||||
|
protected array $attachments = [];
|
||||||
/** @var AbstractProgressListener[] */
|
/** @var AbstractProgressListener[] */
|
||||||
protected array $listeners = [];
|
protected array $listeners = [];
|
||||||
|
|
||||||
|
|
@ -35,9 +37,8 @@ class Map
|
||||||
return $this;
|
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) {
|
if (!$callback) {
|
||||||
return $stream;
|
return $stream;
|
||||||
}
|
}
|
||||||
|
|
@ -48,8 +49,24 @@ class Map
|
||||||
return $this;
|
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
|
public function saveStream(Stream $stream): static
|
||||||
{
|
{
|
||||||
|
if ($stream instanceof Attachment){
|
||||||
|
$this->attachments[] = $stream;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
$this->streams[] = $stream;
|
$this->streams[] = $stream;
|
||||||
$format = $stream->getCodec();
|
$format = $stream->getCodec();
|
||||||
if ($format instanceof ProgressableInterface) {
|
if ($format instanceof ProgressableInterface) {
|
||||||
|
|
@ -72,7 +89,9 @@ class Map
|
||||||
public function buildCommand(): array
|
public function buildCommand(): array
|
||||||
{
|
{
|
||||||
$commands = [];
|
$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));
|
array_push($commands, ...$stream->buildCommand($idx));
|
||||||
}
|
}
|
||||||
foreach ($this->metadata as $k => $v) {
|
foreach ($this->metadata as $k => $v) {
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,9 @@ class MappableMedia extends AbstractMediaType implements EventEmitterInterface
|
||||||
|
|
||||||
public function getFinalCommand(): string
|
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
|
public function map(callable $callback = null): Map|static
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue