Merge pull request #14436 from annando/hls

Support for HLS added
This commit is contained in:
Tobias Diekershoff 2024-09-15 09:01:29 +02:00 committed by GitHub
commit 5b8dd38114
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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>