Passed
Pull Request — master (#262)
by Pascal
02:29
created

MediaExporter::save()   B

Complexity

Conditions 11
Paths 18

Size

Total Lines 41
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 25
nc 18
nop 1
dl 0
loc 41
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
16
/**
17
 * @mixin \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
18
 */
19
class MediaExporter
20
{
21
    use ForwardsCalls,
22
        HandlesAdvancedMedia,
23
        HandlesConcatenation,
24
        HandlesFrames,
25
        HandlesTimelapse,
26
        HasProgressListener;
27
28
    /**
29
     * @var \ProtoneMedia\LaravelFFMpeg\Drivers\PHPFFMpeg
30
     */
31
    protected $driver;
32
33
    /**
34
     * @var \FFMpeg\Format\FormatInterface
35
     */
36
    private $format;
37
38
    /**
39
     * @var string
40
     */
41
    protected $visibility;
42
43
    /**
44
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Disk
45
     */
46
    private $toDisk;
47
48
    public function __construct(PHPFFMpeg $driver)
49
    {
50
        $this->driver = $driver;
51
52
        $this->maps = new Collection;
53
    }
54
55
    protected function getDisk(): Disk
56
    {
57
        if ($this->toDisk) {
58
            return $this->toDisk;
59
        }
60
61
        $media = $this->driver->getMediaCollection();
62
63
        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

63
        return $this->toDisk = $media->/** @scrutinizer ignore-call */ first()->getDisk();
Loading history...
64
    }
65
66
    public function inFormat(FormatInterface $format): self
67
    {
68
        $this->format = $format;
69
70
        return $this;
71
    }
72
73
    public function toDisk($disk)
74
    {
75
        $this->toDisk = Disk::make($disk);
76
77
        return $this;
78
    }
79
80
    public function withVisibility(string $visibility)
81
    {
82
        $this->visibility = $visibility;
83
84
        return $this;
85
    }
86
87
    public function getCommand(string $path = null)
88
    {
89
        $media = $this->prepareSaving($path);
90
91
        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

91
        return $this->driver->/** @scrutinizer ignore-call */ getFinalCommand(
Loading history...
92
            $this->format ?: new NullFormat,
93
            optional($media)->getLocalPath() ?: '/dev/null'
94
        );
95
    }
96
97
    public function dd(string $path = null)
98
    {
99
        dd($this->getCommand($path));
100
    }
101
102
    private function prepareSaving(string $path = null): ?Media
103
    {
104
        $outputMedia = $path ? $this->getDisk()->makeMedia($path) : null;
105
106
        if ($this->concatWithTranscoding && $outputMedia) {
107
            $this->addConcatFilterAndMapping($outputMedia);
108
        }
109
110
        if ($this->maps->isNotEmpty()) {
111
            $this->driver->getPendingComplexFilters()->each->apply($this->driver, $this->maps);
112
113
            $this->maps->map->apply($this->driver->get());
114
115
            return $outputMedia;
116
        }
117
118
        if ($this->format && $this->onProgressCallback) {
119
            $this->applyProgressListenerToFormat($this->format);
120
        }
121
122
        if ($this->timelapseFramerate > 0) {
123
            $this->addTimelapseParametersToFormat();
124
        }
125
126
        return $outputMedia;
127
    }
128
129
    public function save(string $path = null)
130
    {
131
        $outputMedia = $this->prepareSaving($path);
132
133
        if ($this->maps->isNotEmpty()) {
134
            return $this->saveWithMappings();
135
        }
136
137
        try {
138
            if ($this->driver->isConcat() && $outputMedia) {
139
                $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

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

141
                /** @scrutinizer ignore-call */ 
142
                $data = $this->driver->save(
Loading history...
142
                    optional($outputMedia)->getLocalPath(),
143
                    $this->getAccuracy(),
144
                    $this->returnFrameContents
145
                );
146
147
                if ($this->returnFrameContents) {
148
                    return $data;
149
                }
150
            } else {
151
                $this->driver->save(
152
                    $this->format ?: new NullFormat,
153
                    optional($outputMedia)->getLocalPath() ?: '/dev/null'
154
                );
155
            }
156
        } catch (RuntimeException $exception) {
157
            throw EncodingException::decorate($exception);
158
        }
159
160
        if ($outputMedia) {
161
            $outputMedia->copyAllFromTemporaryDirectory($this->visibility);
162
            $outputMedia->setVisibility($this->visibility);
163
        }
164
165
        if ($this->onProgressCallback) {
166
            call_user_func($this->onProgressCallback, 100, 0, 0);
167
        }
168
169
        return $this->getMediaOpener();
170
    }
171
172
    public function getResponse(): array
173
    {
174
        $listener = new StdListener;
175
176
        $this->getFFMpegDriver()->listen($listener);
0 ignored issues
show
Bug introduced by
The method getFFMpegDriver() 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

176
        $this->/** @scrutinizer ignore-call */ 
177
               getFFMpegDriver()->listen($listener);
Loading history...
177
        $this->save();
178
179
        return $listener->get();
180
    }
181
182
    private function saveWithMappings(): MediaOpener
183
    {
184
        if ($this->onProgressCallback) {
185
            $this->applyProgressListenerToFormat($this->maps->last()->getFormat());
186
        }
187
188
        try {
189
            $this->driver->save();
190
        } catch (RuntimeException $exception) {
191
            throw EncodingException::decorate($exception);
192
        }
193
194
        if ($this->onProgressCallback) {
195
            call_user_func($this->onProgressCallback, 100);
196
        }
197
198
        $this->maps->map->getOutputMedia()->each->copyAllFromTemporaryDirectory($this->visibility);
199
200
        return $this->getMediaOpener();
201
    }
202
203
    protected function getMediaOpener(): MediaOpener
204
    {
205
        return new MediaOpener(
206
            $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

206
            $this->driver->getMediaCollection()->/** @scrutinizer ignore-call */ last()->getDisk(),
Loading history...
207
            $this->driver,
208
            $this->driver->getMediaCollection()
209
        );
210
    }
211
212
    /**
213
     * Forwards the call to the driver object and returns the result
214
     * if it's something different than the driver object itself.
215
     */
216
    public function __call($method, $arguments)
217
    {
218
        $result = $this->forwardCallTo($driver = $this->driver, $method, $arguments);
219
220
        return ($result === $driver) ? $this : $result;
221
    }
222
}
223