Basic support for HLS added

This commit is contained in:
Michael 2024-09-14 13:12:05 +00:00
parent 32f8b652ad
commit 072123af8f
23 changed files with 128365 additions and 13 deletions

View file

@ -51,6 +51,7 @@ class PostMedia extends BaseEntity
const TYPE_PLAIN = 19; const TYPE_PLAIN = 19;
const TYPE_ACTIVITY = 20; const TYPE_ACTIVITY = 20;
const TYPE_ACCOUNT = 21; const TYPE_ACCOUNT = 21;
const TYPE_HLS = 22;
const TYPE_DOCUMENT = 128; const TYPE_DOCUMENT = 128;
/** @var int */ /** @var int */

View file

@ -153,7 +153,7 @@ class PostMedia extends BaseRepository
} }
if ( if (
in_array($PostMedia->type, [Entity\PostMedia::TYPE_AUDIO, Entity\PostMedia::TYPE_IMAGE]) || in_array($PostMedia->type, [Entity\PostMedia::TYPE_AUDIO, Entity\PostMedia::TYPE_IMAGE, Entity\PostMedia::TYPE_HLS]) ||
in_array($PostMedia->mimetype->type, ['audio', 'image']) in_array($PostMedia->mimetype->type, ['audio', 'image'])
) { ) {
$attachments['visual'][] = $PostMedia; $attachments['visual'][] = $PostMedia;

View file

@ -3687,7 +3687,7 @@ class Item
continue; continue;
} }
if ($PostMedia->mimetype->type == 'video') { if (($PostMedia->mimetype->type == 'video') || ($PostMedia->type == Post\Media::HLS)) {
if (($PostMedia->height ?? 0) > ($PostMedia->width ?? 0)) { if (($PostMedia->height ?? 0) > ($PostMedia->width ?? 0)) {
$height = min(DI::config()->get('system', 'max_video_height') ?: '100%', $PostMedia->height); $height = min(DI::config()->get('system', 'max_video_height') ?: '100%', $PostMedia->height);
$width = 'auto'; $width = 'auto';
@ -3696,7 +3696,7 @@ class Item
$width = '100%'; $width = '100%';
} }
/// @todo Move the template to /content as well /// @todo Move the template to /content as well
$media = Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [ $media = Renderer::replaceMacros(Renderer::getMarkupTemplate($PostMedia->type == Post\Media::HLS ? 'hls_top.tpl' : 'video_top.tpl'), [
'$video' => [ '$video' => [
'id' => $PostMedia->id, 'id' => $PostMedia->id,
'src' => (string)$PostMedia->url, 'src' => (string)$PostMedia->url,

View file

@ -345,7 +345,7 @@ class Engagement
foreach ($media as $entry) { foreach ($media as $entry) {
if ($entry['type'] == Post\Media::IMAGE) { if ($entry['type'] == Post\Media::IMAGE) {
$type = $type | self::MEDIA_IMAGE; $type = $type | self::MEDIA_IMAGE;
} elseif ($entry['type'] == Post\Media::VIDEO) { } elseif (in_array($entry['type'], [Post\Media::VIDEO, Post\Media::HLS])) {
$type = $type | self::MEDIA_VIDEO; $type = $type | self::MEDIA_VIDEO;
} elseif ($entry['type'] == Post\Media::AUDIO) { } elseif ($entry['type'] == Post\Media::AUDIO) {
$type = $type | self::MEDIA_AUDIO; $type = $type | self::MEDIA_AUDIO;

View file

@ -50,6 +50,7 @@ class Media
const PLAIN = 19; const PLAIN = 19;
const ACTIVITY = 20; const ACTIVITY = 20;
const ACCOUNT = 21; const ACCOUNT = 21;
const HLS = 22;
const DOCUMENT = 128; const DOCUMENT = 128;
/** /**
@ -220,19 +221,16 @@ class Media
} else { } else {
Logger::notice('No image data', ['media' => $media]); Logger::notice('No image data', ['media' => $media]);
} }
if (!empty($media['preview'])) {
$imagedata = Images::getInfoFromURLCached($media['preview']);
if ($imagedata) {
$media['preview-width'] = $imagedata[0];
$media['preview-height'] = $imagedata[1];
}
}
} }
if ($media['type'] != self::DOCUMENT) { if ($media['type'] != self::DOCUMENT) {
$media = self::addType($media); $media = self::addType($media);
} }
if (!empty($media['preview'])) {
$media = self::addPreviewData($media);
}
if (in_array($media['type'], [self::TEXT, self::APPLICATION, self::HTML, self::XML, self::PLAIN])) { if (in_array($media['type'], [self::TEXT, self::APPLICATION, self::HTML, self::XML, self::PLAIN])) {
$media = self::addActivity($media); $media = self::addActivity($media);
} }
@ -248,6 +246,21 @@ class Media
return $media; return $media;
} }
private static function addPreviewData(array $media): array
{
if (!empty($media['preview-width']) && !empty($media['preview-height'])) {
return $media;
}
$imagedata = Images::getInfoFromURLCached($media['preview']);
if ($imagedata) {
$media['preview-width'] = $imagedata[0];
$media['preview-height'] = $imagedata[1];
}
return $media;
}
/** /**
* Adds the activity type if the media entry is linked to an activity * Adds the activity type if the media entry is linked to an activity
* *
@ -466,6 +479,8 @@ class Media
$type = self::TEXT; $type = self::TEXT;
} elseif (($filetype == 'application') && ($subtype == 'x-bittorrent')) { } elseif (($filetype == 'application') && ($subtype == 'x-bittorrent')) {
$type = self::TORRENT; $type = self::TORRENT;
} elseif (($filetype == 'application') && ($subtype == 'vnd.apple.mpegurl')) {
$type = self::HLS;
} elseif ($filetype == 'application') { } elseif ($filetype == 'application') {
$type = self::APPLICATION; $type = self::APPLICATION;
} else { } else {
@ -473,7 +488,7 @@ class Media
Logger::info('Unknown type', ['filetype' => $filetype, 'subtype' => $subtype, 'media' => $mimeType]); Logger::info('Unknown type', ['filetype' => $filetype, 'subtype' => $subtype, 'media' => $mimeType]);
} }
Logger::debug('Detected type', ['filetype' => $filetype, 'subtype' => $subtype, 'media' => $mimeType]); Logger::debug('Detected type', ['type' => $type, 'filetype' => $filetype, 'subtype' => $subtype, 'media' => $mimeType]);
return $type; return $type;
} }

25590
view/js/hls/hls-demo.js Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

29344
view/js/hls/hls.js Normal file

File diff suppressed because it is too large Load diff

3105
view/js/hls/hls.js.d.ts vendored Normal file

File diff suppressed because it is too large Load diff

1
view/js/hls/hls.js.map Normal file

File diff suppressed because one or more lines are too long

21113
view/js/hls/hls.light.js Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

2
view/js/hls/hls.light.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

20549
view/js/hls/hls.light.mjs Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

2
view/js/hls/hls.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

28597
view/js/hls/hls.mjs Normal file

File diff suppressed because it is too large Load diff

1
view/js/hls/hls.mjs.map Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,24 @@
{{*
* Copyright (C) 2010-2024, the Friendica project
* SPDX-FileCopyrightText: 2010-2024 the Friendica project
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*}}
<div class="video-top-wrapper lframe" id="video-top-wrapper-{{$video.id}}">
<script src="view/js/hls/hls.min.js"></script>
<video id="{{$video.id}}" controls poster="{{$video.preview}}" width="{{$video.width}}" height="{{$video.height}}"
title="{{$video.description}}">
<a href="{{$video.src}}">{{$video.name}}</a>
</video>
<script>
var video = document.getElementById('{{$video.id}}');
var videoSrc = '{{$video.src}}';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
}
</script>
</div>