MediaExporter   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 87
dl 0
loc 215
rs 9.44
c 0
b 0
f 0
wmc 37

13 Methods

Rating   Name   Duplication   Size   Complexity  
A inFormat() 0 5 1
A __construct() 0 5 1
A withVisibility() 0 5 1
A toDisk() 0 5 1
A getDisk() 0 9 2
A dd() 0 3 1
A getCommand() 0 7 3
B prepareSaving() 0 25 8
B save() 0 43 11
A __call() 0 5 2
A saveWithMappings() 0 19 4
A getMediaOpener() 0 6 1
A getProcessOutput() 0 7 1
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\Traits\ForwardsCalls;
9
use ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg;
10
use ProtoneMedia\LaravelFFMpeg\FFMpeg\NullFormat;
11
use ProtoneMedia\LaravelFFMpeg\FFMpeg\StdListener;
12
use ProtoneMedia\LaravelFFMpeg\Filesystem\Disk;
13
use ProtoneMedia\LaravelFFMpeg\Filesystem\Media;
14
use ProtoneMedia\LaravelFFMpeg\MediaOpener;
15
use ProtoneMedia\LaravelFFMpeg\Support\ProcessOutput;
16
17
/**
18
 * @mixin \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
19
 */
20
class MediaExporter
21
{
22
    use ForwardsCalls,
23
        HandlesAdvancedMedia,
24
        HandlesConcatenation,
25
        HandlesFrames,
26
        HandlesTimelapse,
27
        HasProgressListener;
28
29
    /**
30
     * @var \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
31
     */
32
    protected $driver;
33
34
    /**
35
     * @var \FFMpeg\Format\FormatInterface
36
     */
37
    private $format;
38
39
    /**
40
     * @var string
41
     */
42
    protected $visibility;
43
44
    /**
45
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Disk
46
     */
47
    private $toDisk;
48
49
    public function __construct(PHPFFMpeg $driver)
50
    {
51
        $this->driver = $driver;
52
53
        $this->maps = new Collection;
54
    }
55
56
    protected function getDisk(): Disk
57
    {
58
        if ($this->toDisk) {
59
            return $this->toDisk;
60
        }
61
62
        $media = $this->driver->getMediaCollection();
63
64
        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

64
        return $this->toDisk = $media->/** @scrutinizer ignore-call */ first()->getDisk();
Loading history...
65
    }
66
67
    public function inFormat(FormatInterface $format): self
68
    {
69
        $this->format = $format;
70
71
        return $this;
72
    }
73
74
    public function toDisk($disk)
75
    {
76
        $this->toDisk = Disk::make($disk);
77
78
        return $this;
79
    }
80
81
    public function withVisibility(string $visibility)
82
    {
83
        $this->visibility = $visibility;
84
85
        return $this;
86
    }
87
88
    /**
89
     * Returns the final command, useful for debugging purposes.
90
     *
91
     * @param string $path
92
     * @return mixed
93
     */
94
    public function getCommand(string $path = null)
95
    {
96
        $media = $this->prepareSaving($path);
97
98
        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

98
        return $this->driver->/** @scrutinizer ignore-call */ getFinalCommand(
Loading history...
99
            $this->format ?: new NullFormat,
100
            optional($media)->getLocalPath() ?: '/dev/null'
101
        );
102
    }
103
104
    /**
105
     * Dump the final command and end the script.
106
     *
107
     * @param string $path
108
     * @return void
109
     */
110
    public function dd(string $path = null)
111
    {
112
        dd($this->getCommand($path));
113
    }
114
115
    private function prepareSaving(string $path = null): ?Media
116
    {
117
        $outputMedia = $path ? $this->getDisk()->makeMedia($path) : null;
118
119
        if ($this->concatWithTranscoding && $outputMedia) {
120
            $this->addConcatFilterAndMapping($outputMedia);
121
        }
122
123
        if ($this->maps->isNotEmpty()) {
124
            $this->driver->getPendingComplexFilters()->each->apply($this->driver, $this->maps);
125
126
            $this->maps->map->apply($this->driver->get());
127
128
            return $outputMedia;
129
        }
130
131
        if ($this->format && $this->onProgressCallback) {
132
            $this->applyProgressListenerToFormat($this->format);
133
        }
134
135
        if ($this->timelapseFramerate > 0) {
136
            $this->addTimelapseParametersToFormat();
137
        }
138
139
        return $outputMedia;
140
    }
141
142
    public function save(string $path = null)
143
    {
144
        $outputMedia = $this->prepareSaving($path);
145
146
        $this->driver->applyBeforeSavingCallbacks();
147
148
        if ($this->maps->isNotEmpty()) {
149
            return $this->saveWithMappings();
150
        }
151
152
        try {
153
            if ($this->driver->isConcat() && $outputMedia) {
154
                $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

154
                $this->driver->/** @scrutinizer ignore-call */ 
155
                               saveFromSameCodecs($outputMedia->getLocalPath());
Loading history...
155
            } elseif ($this->driver->isFrame()) {
156
                $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

156
                /** @scrutinizer ignore-call */ 
157
                $data = $this->driver->save(
Loading history...
157
                    optional($outputMedia)->getLocalPath(),
158
                    $this->getAccuracy(),
159
                    $this->returnFrameContents
160
                );
161
162
                if ($this->returnFrameContents) {
163
                    return $data;
164
                }
165
            } else {
166
                $this->driver->save(
167
                    $this->format ?: new NullFormat,
168
                    optional($outputMedia)->getLocalPath() ?: '/dev/null'
169
                );
170
            }
171
        } catch (RuntimeException $exception) {
172
            throw EncodingException::decorate($exception);
173
        }
174
175
        if ($outputMedia) {
176
            $outputMedia->copyAllFromTemporaryDirectory($this->visibility);
177
            $outputMedia->setVisibility($this->visibility);
178
        }
179
180
        if ($this->onProgressCallback) {
181
            call_user_func($this->onProgressCallback, 100, 0, 0);
182
        }
183
184
        return $this->getMediaOpener();
185
    }
186
187
    public function getProcessOutput(): ProcessOutput
188
    {
189
        return tap(new StdListener, function (StdListener $listener) {
190
            $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

190
            $this->/** @scrutinizer ignore-call */ 
191
                   addListener($listener)->save();
Loading history...
191
            $listener->removeAllListeners();
192
            $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

192
            $this->/** @scrutinizer ignore-call */ 
193
                   removeListener($listener);
Loading history...
193
        })->get();
194
    }
195
196
    private function saveWithMappings(): MediaOpener
197
    {
198
        if ($this->onProgressCallback) {
199
            $this->applyProgressListenerToFormat($this->maps->last()->getFormat());
200
        }
201
202
        try {
203
            $this->driver->save();
204
        } catch (RuntimeException $exception) {
205
            throw EncodingException::decorate($exception);
206
        }
207
208
        if ($this->onProgressCallback) {
209
            call_user_func($this->onProgressCallback, 100);
210
        }
211
212
        $this->maps->map->getOutputMedia()->each->copyAllFromTemporaryDirectory($this->visibility);
213
214
        return $this->getMediaOpener();
215
    }
216
217
    protected function getMediaOpener(): MediaOpener
218
    {
219
        return new MediaOpener(
220
            $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

220
            $this->driver->getMediaCollection()->/** @scrutinizer ignore-call */ last()->getDisk(),
Loading history...
221
            $this->driver,
222
            $this->driver->getMediaCollection()
223
        );
224
    }
225
226
    /**
227
     * Forwards the call to the driver object and returns the result
228
     * if it's something different than the driver object itself.
229
     */
230
    public function __call($method, $arguments)
231
    {
232
        $result = $this->forwardCallTo($driver = $this->driver, $method, $arguments);
233
234
        return ($result === $driver) ? $this : $result;
235
    }
236
}
237