FFProbe::shouldUseCustomProbe()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 19
rs 9.6111
1
<?php
2
3
namespace ProtoneMedia\LaravelFFMpeg\FFMpeg;
4
5
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
6
use FFMpeg\Exception\RuntimeException;
7
use FFMpeg\FFProbe as FFMpegFFProbe;
8
9
class FFProbe extends FFMpegFFProbe
10
{
11
    /**
12
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Media|\ProtoneMedia\LaravelFFMpeg\Filesystem\MediaOnNetwork
13
     */
14
    protected $media;
15
16
    public function setMedia($media): self
17
    {
18
        $this->media = $media;
19
20
        return $this;
21
    }
22
23
    /**
24
     * Create a new instance of this class with the instance of the underlying library.
25
     *
26
     * @param \FFMpeg\FFProbe $probe
27
     * @return self
28
     */
29
    public static function make(FFMpegFFProbe $probe): self
30
    {
31
        if ($probe instanceof FFProbe) {
32
            return $probe;
33
        }
34
35
        return new static($probe->getFFProbeDriver(), $probe->getCache());
36
    }
37
38
    private function shouldUseCustomProbe($pathfile): bool
39
    {
40
        if (!$this->media) {
41
            return false;
42
        }
43
44
        if ($this->media->getLocalPath() !== $pathfile) {
45
            return false;
46
        }
47
48
        if (empty($this->media->getCompiledInputOptions())) {
49
            return false;
50
        }
51
52
        if (!$this->getOptionsTester()->has('-show_streams')) {
53
            throw new RuntimeException('This version of ffprobe is too old and does not support `-show_streams` option, please upgrade');
54
        }
55
56
        return true;
57
    }
58
59
    /**
60
     * Probes the streams contained in a given file.
61
     *
62
     * @param string $pathfile
63
     * @return \FFMpeg\FFProbe\DataMapping\StreamCollection
64
     * @throws \FFMpeg\Exception\InvalidArgumentException
65
     * @throws \FFMpeg\Exception\RuntimeException
66
     */
67
    public function streams($pathfile)
68
    {
69
        if (!$this->shouldUseCustomProbe($pathfile)) {
70
            return parent::streams($pathfile);
71
        }
72
73
        return $this->probeStreams($pathfile, '-show_streams', static::TYPE_STREAMS);
74
    }
75
76
    /**
77
     * Probes the format of a given file.
78
     *
79
     * @param string $pathfile
80
     * @return \FFMpeg\FFProbe\DataMapping\Format A Format object
81
     * @throws \FFMpeg\Exception\InvalidArgumentException
82
     * @throws \FFMpeg\Exception\RuntimeException
83
     */
84
    public function format($pathfile)
85
    {
86
        if (!$this->shouldUseCustomProbe($pathfile)) {
87
            return parent::format($pathfile);
88
        }
89
90
        return $this->probeStreams($pathfile, '-show_format', static::TYPE_FORMAT);
91
    }
92
93
    /**
94
     * This is just copy-paste from FFMpeg\FFProbe...
95
     * It prepends the command with the input options.
96
     */
97
    private function probeStreams($pathfile, $command, $type, $allowJson = true)
98
    {
99
        $commands = array_merge(
100
            $this->media->getCompiledInputOptions(),
101
            [$pathfile, $command]
102
        );
103
104
        $parseIsToDo = false;
105
106
        if ($allowJson && $this->getOptionsTester()->has('-print_format')) {
107
            // allowed in latest PHP-FFmpeg version
108
            $commands[] = '-print_format';
109
            $commands[] = 'json';
110
        } elseif ($allowJson && $this->getOptionsTester()->has('-of')) {
111
            // option has changed in avconv 9
112
            $commands[] = '-of';
113
            $commands[] = 'json';
114
        } else {
115
            $parseIsToDo = true;
116
        }
117
118
        try {
119
            $output = $this->getFFProbeDriver()->command($commands);
120
        } catch (ExecutionFailureException $e) {
121
            throw new RuntimeException(sprintf('Unable to probe %s', $pathfile), $e->getCode(), $e);
122
        }
123
124
        if ($parseIsToDo) {
125
            $data = $this->getParser()->parse($type, $output);
126
        } else {
127
            try {
128
                $data = @json_decode($output, true);
129
130
                if (JSON_ERROR_NONE !== json_last_error()) {
131
                    throw new RuntimeException(sprintf('Unable to parse json %s', $output));
132
                }
133
            } catch (RuntimeException $e) {
134
                return $this->probeStreams($pathfile, $command, $type, false);
135
            }
136
        }
137
138
        return $this->getMapper()->map($type, $data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type array; however, parameter $data of FFMpeg\FFProbe\MapperInterface::map() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

138
        return $this->getMapper()->map($type, /** @scrutinizer ignore-type */ $data);
Loading history...
139
    }
140
}
141