mirror of
https://github.com/friendica/friendica
synced 2024-12-22 12:40:15 +00:00
Basic support for HLS added
This commit is contained in:
parent
32f8b652ad
commit
072123af8f
23 changed files with 128365 additions and 13 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,8 +488,8 @@ 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
25590
view/js/hls/hls-demo.js
Normal file
File diff suppressed because it is too large
Load diff
1
view/js/hls/hls-demo.js.map
Normal file
1
view/js/hls/hls-demo.js.map
Normal file
File diff suppressed because one or more lines are too long
29344
view/js/hls/hls.js
Normal file
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
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
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
21113
view/js/hls/hls.light.js
Normal file
File diff suppressed because it is too large
Load diff
1
view/js/hls/hls.light.js.map
Normal file
1
view/js/hls/hls.light.js.map
Normal file
File diff suppressed because one or more lines are too long
2
view/js/hls/hls.light.min.js
vendored
Normal file
2
view/js/hls/hls.light.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
view/js/hls/hls.light.min.js.map
Normal file
1
view/js/hls/hls.light.min.js.map
Normal file
File diff suppressed because one or more lines are too long
20549
view/js/hls/hls.light.mjs
Normal file
20549
view/js/hls/hls.light.mjs
Normal file
File diff suppressed because it is too large
Load diff
1
view/js/hls/hls.light.mjs.map
Normal file
1
view/js/hls/hls.light.mjs.map
Normal file
File diff suppressed because one or more lines are too long
2
view/js/hls/hls.min.js
vendored
Normal file
2
view/js/hls/hls.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
view/js/hls/hls.min.js.map
Normal file
1
view/js/hls/hls.min.js.map
Normal file
File diff suppressed because one or more lines are too long
28597
view/js/hls/hls.mjs
Normal file
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
1
view/js/hls/hls.mjs.map
Normal file
File diff suppressed because one or more lines are too long
2
view/js/hls/hls.worker.js
Normal file
2
view/js/hls/hls.worker.js
Normal file
File diff suppressed because one or more lines are too long
1
view/js/hls/hls.worker.js.map
Normal file
1
view/js/hls/hls.worker.js.map
Normal file
File diff suppressed because one or more lines are too long
24
view/templates/hls_top.tpl
Normal file
24
view/templates/hls_top.tpl
Normal 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>
|
Loading…
Reference in a new issue