Skip to content

Commit 1323e47

Browse files
authored
Merge pull request #201 from pascalbaljetmedia/v7-loops
Improved support for loops
2 parents 152a80a + 7398613 commit 1323e47

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
All Notable changes to `pbmedia/laravel-ffmpeg` will be documented in this file
44

5+
## 7.0.4 - 2020-06-03
6+
7+
### Added
8+
9+
- Added an `each` method to the `MediaOpener`
10+
11+
### Deprecated
12+
13+
- Nothing
14+
15+
### Fixed
16+
17+
- Nothing
18+
19+
### Removed
20+
21+
- Nothing
22+
523
## 7.0.3 - 2020-06-01
624

725
### Added

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,28 @@ $contents = FFMpeg::open('video.mp4')
232232
->getFrameContents();
233233
```
234234

235+
### Multiple exports using loops
236+
237+
Chaining multiple conversions works because the `save` method of the `MediaExporter` returns a fresh instance of the `MediaOpener`. You can use this to loop through items, for example, to exports multiple frames from one video:
238+
239+
```php
240+
$mediaOpener = FFMpeg::open('video.mp4');
241+
242+
foreach ([5, 15, 25] as $key => $seconds) {
243+
$mediaOpener = $mediaOpener->getFrameFromSeconds($seconds)
244+
->export()
245+
->save("thumb_{$key}.png");
246+
}
247+
```
248+
249+
The `MediaOpener` comes with an `each` method as well. The example above could be refactored like this:
250+
251+
```php
252+
FFMpeg::open('video.mp4')->each([5, 15, 25], function ($ffmpeg, $seconds, $key) {
253+
$ffmpeg->getFrameFromSeconds($seconds)->export()->save("thumb_{$key}.png");
254+
});
255+
```
256+
235257
### Create a timelapse
236258

237259
You can create a timelapse from a sequence of images by using the `asTimelapseWithFramerate` method on the exporter

src/MediaOpener.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use FFMpeg\Media\AbstractMediaType;
77
use Illuminate\Contracts\Filesystem\Filesystem;
88
use Illuminate\Support\Arr;
9+
use Illuminate\Support\Collection;
910
use Illuminate\Support\Traits\ForwardsCalls;
1011
use ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg;
1112
use ProtoneMedia\LaravelFFMpeg\Exporters\HLSExporter;
@@ -56,6 +57,15 @@ public function __construct($disk = null, PHPFFMpeg $driver = null, MediaCollect
5657
$this->collection = $mediaCollection ?: new MediaCollection;
5758
}
5859

60+
public function clone(): self
61+
{
62+
return new MediaOpener(
63+
$this->disk,
64+
$this->driver,
65+
$this->collection
66+
);
67+
}
68+
5969
/**
6070
* Set the disk to open files from.
6171
*/
@@ -156,6 +166,15 @@ public function cleanupTemporaryFiles(): self
156166
return $this;
157167
}
158168

169+
public function each($items, callable $callback): self
170+
{
171+
Collection::make($items)->each(function ($item, $key) use ($callback) {
172+
return $callback($this->clone(), $item, $key);
173+
});
174+
175+
return $this;
176+
}
177+
159178
/**
160179
* Returns the Media object from the driver.
161180
*/

tests/ExportTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,21 @@ public function it_can_chain_multiple_exports()
127127
$this->assertTrue(Storage::disk('local')->has('new_video2.mp4'));
128128
}
129129

130+
/** @test */
131+
public function it_can_chain_multiple_exports_using_the_each_method()
132+
{
133+
$this->fakeLocalVideoFile();
134+
135+
(new MediaOpener)
136+
->open('video.mp4')
137+
->each(['new_video1.mp4', 'new_video2.mp4'], function ($ffmpeg, $filename) {
138+
$ffmpeg->export()->inFormat($this->x264())->save($filename);
139+
});
140+
141+
$this->assertTrue(Storage::disk('local')->has('new_video1.mp4'));
142+
$this->assertTrue(Storage::disk('local')->has('new_video2.mp4'));
143+
}
144+
130145
/** @test */
131146
public function it_can_export_a_with_a_single_filter()
132147
{

tests/FrameTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Support\Facades\Storage;
66
use ProtoneMedia\LaravelFFMpeg\MediaOpener;
7+
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg;
78

89
class FrameTest extends TestCase
910
{
@@ -23,6 +24,7 @@ public function it_can_only_export_a_frame_from_a_video_file()
2324

2425
$this->fail('Should have thrown an exception');
2526
}
27+
2628
/** @test */
2729
public function it_can_export_a_frame_using_seconds()
2830
{
@@ -38,6 +40,38 @@ public function it_can_export_a_frame_using_seconds()
3840
$this->assertTrue(Storage::disk('local')->has('thumb.png'));
3941
}
4042

43+
/** @test */
44+
public function it_can_loop_through_the_exporter()
45+
{
46+
$this->fakeLocalVideoFile();
47+
48+
$ffmpeg = FFMpeg::open('video.mp4');
49+
50+
foreach ([1,2,3] as $key => $frame) {
51+
$ffmpeg = $ffmpeg->getFrameFromSeconds($frame)
52+
->export()
53+
->save("thumb_{$key}.png");
54+
}
55+
56+
$this->assertTrue(Storage::disk('local')->has('thumb_0.png'));
57+
$this->assertTrue(Storage::disk('local')->has('thumb_1.png'));
58+
$this->assertTrue(Storage::disk('local')->has('thumb_2.png'));
59+
}
60+
61+
/** @test */
62+
public function it_can_loop_through_the_exporter_with_the_foreach_method()
63+
{
64+
$this->fakeLocalVideoFile();
65+
66+
FFMpeg::open('video.mp4')->each([1, 2, 3], function ($ffmpeg, $timestamp, $key) {
67+
$ffmpeg->getFrameFromSeconds($timestamp)->export()->save("thumb_{$timestamp}.png");
68+
});
69+
70+
$this->assertTrue(Storage::disk('local')->has('thumb_1.png'));
71+
$this->assertTrue(Storage::disk('local')->has('thumb_2.png'));
72+
$this->assertTrue(Storage::disk('local')->has('thumb_3.png'));
73+
}
74+
4175
/** @test */
4276
public function it_can_export_a_frame_as_base64()
4377
{

0 commit comments

Comments
 (0)