Passed
Pull Request — master (#262)
by Pascal
03:00
created

MediaExporter::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 5
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\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
    public function getCommand(string $path = null)
89
    {
90
        $media = $this->prepareSaving($path);
91
92
        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

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

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

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

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

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