mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
m3u8 tidy
This commit is contained in:
@@ -16,6 +16,7 @@ use Utopia\Database\Validator\UID;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Numeric;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
@@ -646,16 +647,36 @@ App::get('/v1/videos/:videoId/streams/:streamId')
|
||||
}
|
||||
|
||||
foreach ($renditions as $rendition) {
|
||||
$uri = null;
|
||||
$metadata = $rendition->getAttribute('metadata');
|
||||
$manifest = $metadata['hls'];
|
||||
|
||||
$_audios = [];
|
||||
foreach ($manifest as $key => $value) {
|
||||
if ($value['type'] === 'audio') {
|
||||
$_audios[] = [
|
||||
'type' => 'group_audio',
|
||||
'name' => 'audio_' . $value['id'],
|
||||
'default' => ($key === 0) ? 'YES' : 'NO',
|
||||
'uri' => $baseUrl . '/renditions/' . $rendition->getId() . '/types/' . $value['id'],
|
||||
];
|
||||
} elseif ($value['type'] === 'video') {
|
||||
$uri = $baseUrl . '/renditions/' . $rendition->getId() . '/types/' . $value['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$_renditions[] = [
|
||||
'bandwidth' => ($rendition->getAttribute('videoBitrate') + $rendition->getAttribute('audioBitrate')),
|
||||
'resolution' => $rendition->getAttribute('width') . 'X' . $rendition->getAttribute('height'),
|
||||
'name' => $rendition->getAttribute('name'),
|
||||
'uri' => $baseUrl . '/renditions/' . $rendition->getId(),
|
||||
'subs' => !empty($paramsSubtitles) ? ' SUBTITLES="subs"' : '',
|
||||
'uri' => $uri,
|
||||
'subs' => !empty($_subtitles) ? 'subs' : null,
|
||||
'audio' => !empty($_audios) ? 'group_audio' : null,
|
||||
];
|
||||
}
|
||||
|
||||
$template = new View(__DIR__ . '/../../views/videos/hls-master.phtml');
|
||||
$template->setParam('audios', $_audios);
|
||||
$template->setParam('subtitles', $_subtitles);
|
||||
$template->setParam('renditions', $_renditions);
|
||||
$response
|
||||
@@ -733,7 +754,7 @@ App::get('/v1/videos/:videoId/streams/:streamId')
|
||||
});
|
||||
|
||||
|
||||
App::get('/v1/videos/:videoId/streams/:streamId/renditions/:renditionId')
|
||||
App::get('/v1/videos/:videoId/streams/:streamId/renditions/:renditionId/types/:typeId')
|
||||
->desc('Get video rendition manifest')
|
||||
->groups(['api', 'video'])
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
@@ -747,11 +768,12 @@ App::get('/v1/videos/:videoId/streams/:streamId/renditions/:renditionId')
|
||||
->param('videoId', null, new UID(), 'Video unique ID.')
|
||||
->param('streamId', '', new WhiteList(['hls', 'dash']), 'stream protocol name')
|
||||
->param('renditionId', '', new UID(), 'Rendition unique ID.')
|
||||
->param('typeId', '', new Range(0, 10), 'Stream type id.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
->inject('user')
|
||||
->action(function (string $videoId, string $streamId, string $renditionId, Response $response, Database $dbForProject, string $mode, Document $user) {
|
||||
->action(function (string $videoId, string $streamId, string $renditionId, string $typeId, Response $response, Database $dbForProject, string $mode, Document $user) {
|
||||
|
||||
$video = Authorization::skip(fn() => $dbForProject->findOne('videos', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$videoId])
|
||||
@@ -777,6 +799,7 @@ App::get('/v1/videos/:videoId/streams/:streamId/renditions/:renditionId')
|
||||
|
||||
$segments = Authorization::skip(fn() => $dbForProject->find('videos_renditions_segments', [
|
||||
new Query('renditionId', Query::TYPE_EQUAL, [$renditionId]),
|
||||
new Query('representationId', Query::TYPE_EQUAL, [$typeId]),
|
||||
], 5000));
|
||||
|
||||
if (empty($segments)) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
<?php foreach ($this->getParam('audios', []) as $audio): ?>
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="<?php echo $audio['name']; ?>",DEFAULT=<?php echo $audio['default']; ?>,URI="<?php echo $audio['uri']; ?>"<?php echo PHP_EOL?>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($this->getParam('subtitles', []) as $subtitle): ?>
|
||||
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="<?php echo $subtitle['name']; ?>",DEFAULT=<?php echo $subtitle['default']; ?>,AUTOSELECT=NO,FORCED=NO,LANGUAGE="<?php echo $subtitle['code']; ?>",URI="<?php echo $subtitle['uri']; ?>"<?php echo PHP_EOL?>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($this->getParam('renditions', []) as $rendition): ?>
|
||||
#EXT-X-STREAM-INF:BANDWIDTH="<?php echo $rendition['bandwidth']; ?>",RESOLUTION="<?php echo $rendition['resolution']; ?>",NAME="<?php echo $rendition['name']; ?>"<?php if($rendition['subs'] !== null): echo $rendition['subs']; endif?><?php echo PHP_EOL?>
|
||||
#EXT-X-STREAM-INF:BANDWIDTH="<?php echo $rendition['bandwidth']; ?>",RESOLUTION="<?php echo $rendition['resolution']; ?>",NAME="<?php echo $rendition['name']; ?>"<?php if($rendition['subs'] !== null):?>,SUBTITLES="<?php echo $rendition['subs'];?>"<?php endif;?><?php if($rendition['subs'] !== null):?>,AUDIO="<?php echo $rendition['audio'];?>"<?php endif;?> <?php echo PHP_EOL?>
|
||||
<?php echo $rendition['uri'] ?><?php echo PHP_EOL?>
|
||||
<?php endforeach; ?>
|
||||
@@ -246,15 +246,15 @@ class TranscodingV1 extends Worker
|
||||
}
|
||||
|
||||
if ($profile['stream'] === 'hls') {
|
||||
$urls = $this->getHlsSegmentsUrls($this->outDir . 'master.m3u8');
|
||||
foreach ($urls as $pos => $url) {
|
||||
$m3u8 = $this->getHlsSegments($this->outDir . $url);
|
||||
$refs = $this->getHlsSegmentsUrls($this->outDir . 'master.m3u8');
|
||||
foreach ($refs as $ref) {
|
||||
$m3u8 = $this->getHlsSegments($this->outDir . $ref['path']);
|
||||
if (!empty($m3u8['segments'])) {
|
||||
foreach ($m3u8['segments'] as $segment) {
|
||||
Authorization::skip(function () use ($segment, $project, $query, $renditionPath, $pos) {
|
||||
Authorization::skip(function () use ($segment, $project, $query, $renditionPath, $ref) {
|
||||
return $this->database->createDocument('videos_renditions_segments', new Document([
|
||||
'renditionId' => $query->getId(),
|
||||
'representationId' => $pos,
|
||||
'representationId' => $ref['id']+0,
|
||||
'fileName' => $segment['fileName'],
|
||||
'path' => $renditionPath,
|
||||
'duration' => $segment['duration'],
|
||||
@@ -262,6 +262,8 @@ class TranscodingV1 extends Worker
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$query->setAttribute('metadata', json_encode(['hls' => $refs]));
|
||||
$query->setAttribute('targetDuration', $m3u8['targetDuration']);
|
||||
}
|
||||
} else {
|
||||
@@ -464,7 +466,13 @@ class TranscodingV1 extends Worker
|
||||
if ($end !== false) {
|
||||
$start = strpos($line, $this->args['videoId']);
|
||||
if ($start !== false) {
|
||||
$files[] = substr($line, $start, ($end - $start) + 4);
|
||||
$path = substr($line, $start, ($end - $start) + 4);
|
||||
$parts = explode('_', $path);
|
||||
$files[] = [
|
||||
'id' => $parts[1],
|
||||
'type' => str_contains($line, "TYPE=AUDIO") ? 'audio' : 'video',
|
||||
'path' => $path
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
-6318
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user