Passed
Pull Request — master (#341)
by Pascal
12:13
created

MediaExporter::getUuid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ProtoneMedia\LaravelFFMpeg\Exporters;
4
5
use FFMpeg\Exception\RuntimeException;
6
use FFMpeg\Format\FormatInterface;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
use Illuminate\Support\Traits\ForwardsCalls;
10
use ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg;
11
use ProtoneMedia\LaravelFFMpeg\FFMpeg\NullFormat;
12
use ProtoneMedia\LaravelFFMpeg\FFMpeg\StdListener;
13
use ProtoneMedia\LaravelFFMpeg\Filesystem\Disk;
14
use ProtoneMedia\LaravelFFMpeg\Filesystem\Media;
15
use ProtoneMedia\LaravelFFMpeg\MediaOpener;
16
use ProtoneMedia\LaravelFFMpeg\Support\ProcessOutput;
17
18
/**
19
 * @mixin \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
20
 */
21
class MediaExporter
22
{
23
    use ForwardsCalls,
24
        HandlesAdvancedMedia,
25
        HandlesConcatenation,
26
        HandlesFrames,
27
        HandlesTimelapse,
28
        HasProgressListener;
29
30
    /**
31
     * @var \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
32
     */
33
    protected $driver;
34
35
    /**
36
     * @var \FFMpeg\Format\FormatInterface
37
     */
38
    private $format;
39
40
    /**
41
     * @var string
42
     */
43
    protected $visibility;
44
45
    /**
46
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Disk
47
     */
48
    private $toDisk;
49
50
    /**
51
     * @var string
52
     */
53
    private $uuid;
54
55
    public function __construct(PHPFFMpeg $driver)
56
    {
57
        $this->driver = $driver;
58
59
        $this->maps = new Collection;
60
        $this->uuid = (string) Str::uuid();
61
    }
62
63
    protected function getDisk(): Disk
64
    {
65
        if ($this->toDisk) {
66
            return $this->toDisk;
67
        }
68
69
        $media = $this->driver->getMediaCollection();
70
71
        return $this->toDisk = $media->first()->getDisk();
0 ignored issues
show
Bug introduced by
The method first() does not exist on ProtoneMedia\LaravelFFMp...esystem\MediaCollection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
        return $this->toDisk = $media->/** @scrutinizer ignore-call */ first()->getDisk();
Loading history...
72
    }
73
74
    public function getUuid(): string
75
    {
76
        return $this->uuid;
77
    }
78
79
    public function inFormat(FormatInterface $format): self
80
    {
81
        $this->format = $format;
82
83
        return $this;
84
    }
85
86
    public function toDisk($disk)
87
    {
88
        $this->toDisk = Disk::make($disk);
89
90
        return $this;
91
    }
92
93
    public function withVisibility(string $visibility)
94
    {
95
        $this->visibility = $visibility;
96
97
        return $this;
98
    }
99
100
    /**
101
     * Returns the final command, useful for debugging purposes.
102
     *
103
     * @param string $path
104
     * @return mixed
105
     */
106
    public function getCommand(string $path = null)
107
    {
108
        $media = $this->prepareSaving($path);
109
110
        return $this->driver->getFinalCommand(
0 ignored issues
show
Bug introduced by
The method getFinalCommand() does not exist on ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
        return $this->driver->/** @scrutinizer ignore-call */ getFinalCommand(
Loading history...
111
            $this->format ?: new NullFormat,
112
            optional($media)->getLocalPath() ?: '/dev/null'
113
        );
114
    }
115
116
    /**
117
     * Dump the final command and end the script.
118
     *
119
     * @param string $path
120
     * @return void
121
     */
122
    public function dd(string $path = null)
123
    {
124
        dd($this->getCommand($path));
125
    }
126
127
    private function prepareSaving(string $path = null): ?Media
128
    {
129
        $outputMedia = $path ? $this->getDisk()->makeMedia($path) : null;
130
131
        if ($this->concatWithTranscoding && $outputMedia) {
132
            $this->addConcatFilterAndMapping($outputMedia);
133
        }
134
135
        if ($this->maps->isNotEmpty()) {
136
            $this->driver->getPendingComplexFilters()->each->apply($this->driver, $this->maps);
137
138
            $this->maps->map->apply($this->driver->get());
139
140
            return $outputMedia;
141
        }
142
143
        if ($this->format && $this->onProgressCallback) {
144
            $this->applyProgressListenerToFormat($this->format);
145
        }
146
147
        if ($this->timelapseFramerate > 0) {
148
            $this->addTimelapseParametersToFormat();
149
        }
150
151
        return $outputMedia;
152
    }
153
154
    public function save(string $path = null)
155
    {
156
        $outputMedia = $this->prepareSaving($path);
157
158
        $this->driver->applyBeforeSavingCallbacks();
159
160
        if ($this->maps->isNotEmpty()) {
161
            return $this->saveWithMappings();
162
        }
163
164
        try {
165
            if ($this->driver->isConcat() && $outputMedia) {
166
                $this->driver->saveFromSameCodecs($outputMedia->getLocalPath());
0 ignored issues
show
Bug introduced by
The method saveFromSameCodecs() does not exist on ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
                $this->driver->/** @scrutinizer ignore-call */ 
167
                               saveFromSameCodecs($outputMedia->getLocalPath());
Loading history...
167
            } elseif ($this->driver->isFrame()) {
168
                $data = $this->driver->save(
0 ignored issues
show
Bug introduced by
The method save() does not exist on ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

168
                /** @scrutinizer ignore-call */ 
169
                $data = $this->driver->save(
Loading history...
169
                    optional($outputMedia)->getLocalPath(),
170
                    $this->getAccuracy(),
171
                    $this->returnFrameContents
172
                );
173
174
                if ($this->returnFrameContents) {
175
                    return $data;
176
                }
177
            } else {
178
                $this->driver->save(
179
                    $this->format ?: new NullFormat,
180
                    optional($outputMedia)->getLocalPath() ?: '/dev/null'
181
                );
182
            }
183
        } catch (RuntimeException $exception) {
184
            throw EncodingException::decorate($exception);
185
        }
186
187
        if ($outputMedia) {
188
            $outputMedia->copyAllFromTemporaryDirectory($this->visibility);
189
            $outputMedia->setVisibility($this->visibility);
190
        }
191
192
        if ($this->onProgressCallback) {
193
            call_user_func($this->onProgressCallback, 100, 0, 0);
194
        }
195
196
        return $this->getMediaOpener();
197
    }
198
199
    public function getProcessOutput(): ProcessOutput
200
    {
201
        return tap(new StdListener, function (StdListener $listener) {
202
            $this->addListener($listener)->save();
0 ignored issues
show
Bug introduced by
The method addListener() does not exist on ProtoneMedia\LaravelFFMpeg\Exporters\MediaExporter. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

202
            $this->/** @scrutinizer ignore-call */ 
203
                   addListener($listener)->save();
Loading history...
203
            $listener->removeAllListeners();
204
            $this->removeListener($listener);
0 ignored issues
show
Bug introduced by
The method removeListener() does not exist on ProtoneMedia\LaravelFFMpeg\Exporters\MediaExporter. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

204
            $this->/** @scrutinizer ignore-call */ 
205
                   removeListener($listener);
Loading history...
205
        })->get();
206
    }
207
208
    private function saveWithMappings(): MediaOpener
209
    {
210
        if ($this->onProgressCallback) {
211
            $this->applyProgressListenerToFormat($this->maps->last()->getFormat());
212
        }
213
214
        try {
215
            $this->driver->save();
216
        } catch (RuntimeException $exception) {
217
            throw EncodingException::decorate($exception);
218
        }
219
220
        if ($this->onProgressCallback) {
221
            call_user_func($this->onProgressCallback, 100);
222
        }
223
224
        $this->maps->map->getOutputMedia()->each->copyAllFromTemporaryDirectory($this->visibility);
225
226
        return $this->getMediaOpener();
227
    }
228
229
    protected function getMediaOpener(): MediaOpener
230
    {
231
        return new MediaOpener(
232
            $this->driver->getMediaCollection()->last()->getDisk(),
0 ignored issues
show
Bug introduced by
The method last() does not exist on ProtoneMedia\LaravelFFMp...esystem\MediaCollection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

232
            $this->driver->getMediaCollection()->/** @scrutinizer ignore-call */ last()->getDisk(),
Loading history...
233
            $this->driver,
234
            $this->driver->getMediaCollection()
235
        );
236
    }
237
238
    /**
239
     * Forwards the call to the driver object and returns the result
240
     * if it's something different than the driver object itself.
241
     */
242
    public function __call($method, $arguments)
243
    {
244
        $result = $this->forwardCallTo($driver = $this->driver, $method, $arguments);
245
246
        return ($result === $driver) ? $this : $result;
247
    }
248
}
249