Passed
Push — master ( a6a132...f48b58 )
by Pascal
03:05
created

MediaExporter::save()   B

Complexity

Conditions 8
Paths 12

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

136
                /** @scrutinizer ignore-call */ 
137
                $data = $this->driver->save(
Loading history...
137
                    optional($outputMedia)->getLocalPath(),
138
                    $this->getAccuracy(),
139
                    $this->returnFrameContents
140
                );
141
142
                if ($this->returnFrameContents) {
143
                    return $data;
144
                }
145
            } else {
146
                $this->driver->save($this->format, $outputMedia->getLocalPath());
147
            }
148
        } catch (RuntimeException $exception) {
149
            throw EncodingException::decorate($exception);
150
        }
151
152
        $outputMedia->copyAllFromTemporaryDirectory($this->visibility);
153
        $outputMedia->setVisibility($this->visibility);
154
155
        if ($this->onProgressCallback) {
156
            call_user_func($this->onProgressCallback, 100, 0, 0);
157
        }
158
159
        return $this->getMediaOpener();
160
    }
161
162
    private function saveWithMappings(): MediaOpener
163
    {
164
        if ($this->onProgressCallback) {
165
            $this->applyProgressListenerToFormat($this->maps->last()->getFormat());
166
        }
167
168
        try {
169
            $this->driver->save();
170
        } catch (RuntimeException $exception) {
171
            throw EncodingException::decorate($exception);
172
        }
173
174
        if ($this->onProgressCallback) {
175
            call_user_func($this->onProgressCallback, 100);
176
        }
177
178
        $this->maps->map->getOutputMedia()->each->copyAllFromTemporaryDirectory($this->visibility);
179
180
        return $this->getMediaOpener();
181
    }
182
183
    protected function getMediaOpener(): MediaOpener
184
    {
185
        return new MediaOpener(
186
            $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

186
            $this->driver->getMediaCollection()->/** @scrutinizer ignore-call */ last()->getDisk(),
Loading history...
187
            $this->driver,
188
            $this->driver->getMediaCollection()
189
        );
190
    }
191
192
    /**
193
     * Forwards the call to the driver object and returns the result
194
     * if it's something different than the driver object itself.
195
     */
196
    public function __call($method, $arguments)
197
    {
198
        $result = $this->forwardCallTo($driver = $this->driver, $method, $arguments);
199
200
        return ($result === $driver) ? $this : $result;
201
    }
202
}
203