Passed
Push — master ( e9f28b...0c9bc9 )
by Sébastien
02:16
created

SeekTime::convertHMSmToSeconds()   B

Complexity

Conditions 9
Paths 4

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 20
nc 4
nop 1
dl 0
loc 32
ccs 18
cts 18
cp 1
crap 9
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\MediaTools\Video;
6
7
use Soluble\MediaTools\Common\Exception\InvalidArgumentException;
8
use Soluble\MediaTools\Video\Adapter\FFMpegCLIValueInterface;
9
10
class SeekTime implements FFMpegCLIValueInterface
11
{
12
    /** @var float */
13
    protected $time;
14
15
    /**
16
     * @param float $seconds seconds and optional milliseconds as decimals
17
     */
18 13
    public function __construct(float $seconds)
19
    {
20 13
        $this->time = $seconds;
21 13
    }
22
23
    /**
24
     * @param string $hmsmTime 'HOURS:MM:SS.MILLISECONDS' like in '01:23:45.678'
25
     *
26
     * @throws InvalidArgumentException
27
     */
28 2
    public static function createFromHMS(string $hmsmTime): self
29
    {
30 2
        return new self(self::convertHMSmToSeconds($hmsmTime));
31
    }
32
33
    /**
34
     * Convert 'HOURS:MM:SS.MILLISECONDS' format to seconds with milli
35
     * Note: FFMpeg refer to this format as 'sexagesimal'.
36
     *
37
     * @param string $hmsmTime 'HOURS:MM:SS.MILLISECONDS' like in '01:23:45.678'
38
     *
39
     * @return float i.e 123.642
40
     *
41
     * @throws InvalidArgumentException
42
     */
43 4
    public static function convertHMSmToSeconds(string $hmsmTime): float
44
    {
45
        [   $secondsWithMilli,
46
            $minutes,
47
            $hours,
48 4
        ] = array_merge(array_reverse(explode(':', $hmsmTime)), [0, 0, 0]);
49
50 4
        if (!is_numeric($secondsWithMilli) || $secondsWithMilli < 0 || $secondsWithMilli >= 60.0) {
51 1
            throw new InvalidArgumentException(sprintf(
52 1
                'Seconds \'%s\' are incorrect in \'%s\'',
53 1
                $secondsWithMilli,
54 1
                $hmsmTime
55
            ));
56
        }
57
58 3
        if (!is_numeric($minutes) || $minutes < 0 || $minutes >= 60.0) {
59 1
            throw new InvalidArgumentException(sprintf(
60 1
                'Minutes \'%s\' are incorrect in \'%s\'',
61 1
                $minutes,
62 1
                $hmsmTime
63
            ));
64
        }
65
66 2
        if (!is_numeric($hours) || $hours < 0) {
67 1
            throw new InvalidArgumentException(sprintf(
68 1
                'Hours \'%s\' are incorrect in \'%s\'',
69 1
                $hours,
70 1
                $hmsmTime
71
            ));
72
        }
73
74 1
        return (float) $secondsWithMilli + ((int) $minutes) * 60 + ((int) $hours) * 3600;
75
    }
76
77
    /**
78
     * @throws InvalidArgumentException
79
     */
80 10
    public static function convertSecondsToHMSs(float $secondsWithMilli): string
81
    {
82 10
        if ($secondsWithMilli < 0) {
83 1
            throw new InvalidArgumentException(sprintf(
84 1
                "Cannot convert negative time to HMSs: \'%s\'",
85 1
                (string) $secondsWithMilli
86
            ));
87
        }
88
89 9
        [$time, $milli] = array_merge(explode('.', (string) $secondsWithMilli), [0, 0]);
90
91 9
        return sprintf(
92 9
            '%d:%02d:%02d.%d',
93 9
            ((int) $time / 3600),
94 9
            ((int) $time % 3600 / 60),
95 9
            ((int) $time % 3600 % 60),
96 9
            $milli
97
        );
98
    }
99
100
    /**
101
     * Return time in seconds with milli.
102
     *
103
     * @return float
104
     */
105 2
    public function getTime(): float
106
    {
107 2
        return $this->time;
108
    }
109
110 8
    public function getFFmpegCLIValue(): string
111
    {
112 8
        return self::convertSecondsToHMSs($this->time);
113
    }
114
}
115