ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
MediaObjectManager.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\MediaObjects;
22 
32 
34 {
38 
39  public function __construct(
40  protected InternalDataService $data,
41  InternalRepoService $repo,
42  protected InternalDomainService $domain,
43  protected \ilMobStakeholder $stakeholder
44  ) {
45  $this->repo = $repo->mediaObject();
46  $this->image_converters = new Images(true);
47  $this->output_options = new ImageOutputOptions();
48  }
49 
50  public function create(
51  int $id,
52  string $title,
53  int $from_mob_id = 0
54  ): void {
55  $this->repo->create(
56  $id,
57  $title,
58  $this->stakeholder,
59  $from_mob_id
60  );
61  }
62 
63  public function addLocalDirectory(int $mob_id, string $dir) : void
64  {
65  $this->repo->addLocalDirectory($mob_id, $dir);
66  }
67 
68  public function addFileFromLegacyUpload(int $mob_id, string $tmp_name, string $target_path = ""): void
69  {
70  $this->repo->addFileFromLegacyUpload($mob_id, $tmp_name, $target_path);
71  }
72 
73  public function addFileFromUpload(
74  int $mob_id,
75  UploadResult $result,
76  string $path = "/"
77  ): void
78  {
79  $this->repo->addFileFromUpload($mob_id, $result, $path);
80  }
81 
82  public function addFileFromLocal(int $mob_id, string $tmp_name, string $path): void
83  {
84  $this->repo->addFileFromLocal($mob_id, $tmp_name, $path);
85  }
86 
87  public function removeLocation(
88  int $mob_id,
89  string $location
90  ): void {
91  $this->repo->removeLocation($mob_id, $location);
92  }
93 
94  public function getLocationStream(
95  int $mob_id,
96  string $location
97  ): ZIPStream {
98  return $this->repo->getLocationStream($mob_id, $location);
99  }
100 
101  public function addStream(
102  int $mob_id,
103  string $location,
104  FileStream $stream
105  ) : void {
106  $this->repo->addStream($mob_id, $location, $stream);
107  }
108 
109  public function getLocalSrc(int $mob_id, string $location): string
110  {
111  $src = $this->repo->getLocalSrc(
112  $mob_id,
113  $location
114  );
115  if ($src === "") { // fallback: old source
116  $path_to_file = \ilObjMediaObject::_getURL($mob_id) . "/" . $location;
117  try {
118  $src = \ilWACSignedPath::signFile($path_to_file);
119  } catch (Exception $e) {
120  }
121  }
122  return $src;
123  }
124 
125  public function hasLocalFile(int $mob_id, string $location) : bool
126  {
127  return $this->repo->hasLocalFile($mob_id, $location);
128  }
129 
130  public function getContainerResource(
131  int $mob_id
132  ): ?StorableResource {
133  return $this->repo->getContainerResource($mob_id);
134  }
135 
136  public function getContainerResourceId(
137  int $mob_id
139  return $this->repo->getContainerResourceId($mob_id);
140  }
141 
142  public function getFilesOfPath(
143  int $mob_id,
144  string $dir_path
145  ): array {
146  return $this->repo->getFilesOfPath($mob_id, $dir_path);
147  }
148 
149  public function getInfoOfEntry(
150  int $mob_id,
151  string $path
152  ) : array
153  {
154  return $this->repo->getInfoOfEntry(
155  $mob_id,
156  $path
157  );
158  }
159 
160  public function deliverEntry(
161  int $mob_id,
162  string $path
163  ) : void
164  {
165  $this->repo->deliverEntry($mob_id, $path);
166  }
167 
168 
169  public function generatePreview(
170  int $mob_id,
171  string $location,
172  bool $local,
173  string $format,
174  int $sec = 1,
175  string $target_location = "mob_vpreview.png"
176  ): void {
177 
178  $is_image = is_int(strpos($format, "image/"));
179  $is_video = in_array($format, ["video/mp4", "video/webm"]);
180 
181  if ($local) {
182  if ($is_image) {
183  $width = $height = \ilObjMediaObject::DEFAULT_PREVIEW_SIZE;
184  $image_quality = 60;
185 
186  // the zip stream is not seekable, which is needed by Imagick
187  // so we create a seekable stream first
188  $tempStream = fopen('php://temp', 'w+');
189  stream_copy_to_stream($this->repo->getLocationStream($mob_id, $location)->detach(), $tempStream);
190  rewind($tempStream);
191  $stream = new Stream($tempStream);
192 
193  $converter = $this->image_converters->resizeToFixedSize(
194  $stream,
195  $width,
196  $height,
197  true,
198  $this->output_options
199  ->withQuality($image_quality)
200  ->withFormat(ImageOutputOptions::FORMAT_PNG)
201  );
202  $this->repo->addStream(
203  $mob_id,
204  $target_location,
205  $converter->getStream()
206  );
207  fclose($tempStream);
208  }
209  if ($is_video) {
210  $zip_uri = $this->repo->getContainerPath($mob_id);
212  $zip_uri,
213  $location,
214  $sec
215  );
216  $png_res = fopen('php://memory', 'r+');
217  fwrite($png_res, $image_str);
218  rewind($png_res);
219  $png_stream = new Stream($png_res);
220  $this->repo->addStream(
221  $mob_id,
222  $target_location,
223  $png_stream
224  );
225  }
226  }
227  }
228 
229  public function addPreviewFromUrl(
230  int $mob_id,
231  string $url,
232  string $target_location
233  ) : void
234  {
235  $str = file_get_contents($url);
236  $res = fopen('php://memory', 'r+');
237  fwrite($res, $str);
238  rewind($res);
239  $stream = new Stream($res);
240  $this->repo->addStream(
241  $mob_id,
242  $target_location,
243  $stream
244  );
245  }
246 
247  public function getSrtFiles(int $mob_id, bool $vtt_only = false): array
248  {
249  $srt_files = [];
250  $valid_suffixes = $vtt_only
251  ? ["vtt"]
252  : ["srt", "vtt"];
253  foreach ($this->getFilesOfPath($mob_id, "/srt") as $i) {
254  $name = explode(".", $i["basename"]);
255  if (in_array($name[1], $valid_suffixes) && substr($name[0], 0, 9) == "subtitle_") {
256  $srt_files[] = [
257  "file" => $i["basename"],
258  "full_path" => $i["path"],
259  "src" => $this->getLocalSrc($mob_id, $i["path"]),
260  "language" => substr($name[0], 9, 2)
261  ];
262  }
263  }
264  return $srt_files;
265  }
266 
267  public function generateMissingVTT(int $mob_id): void
268  {
269  $names = array_map(static function(array $i) {
270  return $i["file"];
271  }, $this->getSrtFiles($mob_id));
272  $missing_vtt = [];
273  foreach ($names as $name) {
274  if (str_ends_with($name, ".srt")) {
275  $vtt = str_replace (".srt", ".vtt", $name);
276  if (!in_array($vtt, $names) && !in_array($vtt, $missing_vtt)) {
277  $missing_vtt[] = $vtt;
278  }
279  }
280  }
281  foreach($missing_vtt as $vtt_name) {
282  $srt_name = str_replace (".vtt", ".srt", $vtt_name);
283  $srt_content = stream_get_contents($this->repo->getLocationStream($mob_id, "srt/" . $srt_name)->detach());
284  $vtt_content = $this->srtToVtt($srt_content);
285  $this->repo->addString($mob_id, "/srt/" . $vtt_name, $vtt_content);
286  }
287  }
288 
289  function srtToVtt(string $srt_text): string
290  {
291  // Remove UTF-8 BOM if present
292  $srt_text = preg_replace('/^\xEF\xBB\xBF/', '', $srt_text);
293 
294  // Normalise line-endings and split cues
295  $srt_text = preg_replace('~\r\n?~', "\n", $srt_text);
296  $blocks = preg_split("/\n{2,}/", trim($srt_text));
297 
298  $vttLines = ['WEBVTT', '']; // header + blank line
299 
300  foreach ($blocks as $block) {
301  $lines = explode("\n", $block);
302 
303  if (count($lines) < 2) {
304  continue; // malformed cue
305  }
306 
307  /* cue number? allow BOM or spaces either side */
308  if (preg_match('/^\s*\d+\s*$/u', $lines[0])) {
309  array_shift($lines); // drop it
310  }
311 
312  /* now $lines[0] *is* the time-code line → , → . */
313  $lines[0] = preg_replace(
314  '/(\d{2}:\d{2}:\d{2}),(\d{3})/',
315  '$1.$2',
316  $lines[0]
317  );
318 
319  $vttLines = array_merge($vttLines, $lines, ['']);
320  }
321 
322  return implode("\n", $vttLines);
323  }}
hasLocalFile(int $mob_id, string $location)
create(int $id, string $title, int $from_mob_id=0)
$res
Definition: ltiservices.php:69
__construct(protected InternalDataService $data, InternalRepoService $repo, protected InternalDomainService $domain, protected \ilMobStakeholder $stakeholder)
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
getLocalSrc(int $mob_id, string $location)
addFileFromUpload(int $mob_id, UploadResult $result, string $path="/")
$url
Definition: shib_logout.php:63
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$path
Definition: ltiservices.php:30
addPreviewFromUrl(int $mob_id, string $url, string $target_location)
static extractPNGFromVideoInZip(string $zip, string $path, int $sec=1)
addFileFromLocal(int $mob_id, string $tmp_name, string $path)
getFilesOfPath(int $mob_id, string $dir_path)
getLocationStream(int $mob_id, string $location)
removeLocation(int $mob_id, string $location)
addFileFromLegacyUpload(int $mob_id, string $tmp_name, string $target_path="")
addLocalDirectory(int $mob_id, string $dir)
getInfoOfEntry(int $mob_id, string $path)
generatePreview(int $mob_id, string $location, bool $local, string $format, int $sec=1, string $target_location="mob_vpreview.png")
getSrtFiles(int $mob_id, bool $vtt_only=false)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:24
static signFile(string $path_to_file)
static _getURL(int $a_mob_id)
get directory for files of media object
addStream(int $mob_id, string $location, FileStream $stream)
deliverEntry(int $mob_id, string $path)
The base interface for all filesystem streams.
Definition: FileStream.php:31