Completed
Push — master ( 183763...e3ef43 )
by Pascal
01:26
created

getSegmentedProgressCallback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace Pbmedia\LaravelFFMpeg;
4
5
use FFMpeg\Format\VideoInterface;
6
use Pbmedia\LaravelFFMpeg\SegmentedExporter;
7
8
class HLSPlaylistExporter extends MediaExporter
9
{
10
    protected $segmentedExporters = [];
11
12
    protected $playlistPath;
13
14
    protected $segmentLength = 10;
15
16
    protected $saveMethod = 'savePlaylist';
17
18
    protected $progressCallback;
19
20
    public function addFormat(VideoInterface $format, callable $callback = null): MediaExporter
21
    {
22
        $segmentedExporter = $this->getSegmentedExporterFromFormat($format);
23
24
        if ($callback) {
25
            $callback($segmentedExporter->getMedia());
26
        }
27
28
        $this->segmentedExporters[] = $segmentedExporter;
29
30
        return $this;
31
    }
32
33
    public function getFormatsSorted(): array
34
    {
35
        return array_map(function ($exporter) {
36
            return $exporter->getFormat();
37
        }, $this->getSegmentedExportersSorted());
38
    }
39
40
    public function getSegmentedExportersSorted(): array
41
    {
42
        usort($this->segmentedExporters, function ($exportedA, $exportedB) {
43
            return $exportedA->getFormat()->getKiloBitrate() <=> $exportedB->getFormat()->getKiloBitrate();
44
        });
45
46
        return $this->segmentedExporters;
47
    }
48
49
    public function setPlaylistPath(string $playlistPath): MediaExporter
50
    {
51
        $this->playlistPath = $playlistPath;
52
53
        return $this;
54
    }
55
56
    public function setSegmentLength(int $segmentLength): MediaExporter
57
    {
58
        $this->segmentLength = $segmentLength;
59
60
        foreach ($this->segmentedExporters as $segmentedExporter) {
61
            $segmentedExporter->setSegmentLength($segmentLength);
62
        }
63
64
        return $this;
65
    }
66
67
    protected function getSegmentedExporterFromFormat(VideoInterface $format): SegmentedExporter
68
    {
69
        $media = clone $this->media;
70
71
        return (new SegmentedExporter($media))
72
            ->inFormat($format);
73
    }
74
75
    public function getSegmentedExporters(): array
76
    {
77
        return $this->segmentedExporters;
78
    }
79
80
    public function onProgress(callable $callback)
81
    {
82
        $this->progressCallback = $callback;
83
84
        return $this;
85
    }
86
87
    private function getSegmentedProgressCallback($key): callable
88
    {
89
        return function ($video, $format, $percentage) use ($key) {
90
            $previousCompletedSegments = $key / count($this->segmentedExporters) * 100;
91
92
            call_user_func($this->progressCallback,
93
                $previousCompletedSegments + ($percentage / count($this->segmentedExporters))
94
            );
95
        };
96
    }
97
98
    public function prepareSegmentedExporters()
99
    {
100
        foreach ($this->segmentedExporters as $key => $segmentedExporter) {
101
            if ($this->progressCallback) {
102
                $segmentedExporter->getFormat()->on('progress', $this->getSegmentedProgressCallback($key));
103
            }
104
105
            $segmentedExporter->setSegmentLength($this->segmentLength);
106
        }
107
108
        return $this;
109
    }
110
111
    protected function exportStreams()
112
    {
113
        $this->prepareSegmentedExporters();
114
115
        foreach ($this->segmentedExporters as $key => $segmentedExporter) {
116
            $segmentedExporter->saveStream($this->playlistPath);
117
        }
118
    }
119
120
    protected function getMasterPlaylistContents(): string
121
    {
122
        $lines = ['#EXTM3U'];
123
124
        foreach ($this->getSegmentedExportersSorted() as $segmentedExporter) {
125
            $bitrate = $segmentedExporter->getFormat()->getKiloBitrate() * 1000;
126
127
            $lines[] = '#EXT-X-STREAM-INF:BANDWIDTH=' . $bitrate;
128
            $lines[] = $segmentedExporter->getPlaylistFilename();
129
        }
130
131
        return implode(PHP_EOL, $lines);
132
    }
133
134
    public function savePlaylist(string $playlistPath): MediaExporter
135
    {
136
        $this->setPlaylistPath($playlistPath);
137
        $this->exportStreams();
138
139
        file_put_contents(
140
            $playlistPath,
141
            $this->getMasterPlaylistContents()
142
        );
143
144
        return $this;
145
    }
146
}
147