From 115b032f3ae40a681cd8c0d8c5de2a2e2cbeb0f3 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 4 Sep 2022 09:29:56 +0300 Subject: [PATCH] hls-playlist --- app/controllers/api/videos.php | 3 ++- app/init.php | 4 ++-- app/views/videos/hls-master.phtml | 4 ++-- app/workers/transcoding.php | 37 ++++++++++++++++++++++--------- src/Appwrite/Extend/Exception.php | 1 + 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/videos.php b/app/controllers/api/videos.php index 1333762ae3..c96150f8aa 100644 --- a/app/controllers/api/videos.php +++ b/app/controllers/api/videos.php @@ -656,8 +656,9 @@ App::get('/v1/videos/:videoId/streams/:streamId') if ($value['type'] === 'audio') { $_audios[] = [ 'type' => 'group_audio', - 'name' => 'audio_' . $value['id'], + 'name' => $value['language'], 'default' => ($key === 0) ? 'YES' : 'NO', + 'language' => $value['language'], 'uri' => $baseUrl . '/renditions/' . $rendition->getId() . '/types/' . $value['id'], ]; } elseif ($value['type'] === 'video') { diff --git a/app/init.php b/app/init.php index 33f04fea1e..27f04d272b 100644 --- a/app/init.php +++ b/app/init.php @@ -844,8 +844,8 @@ App::setResource('project', function ($dbForConsole, $request, $console) { /** @var Utopia\Database\Database $dbForConsole */ /** @var Utopia\Database\Document $console */ - //$projectId = 'dev'; - $projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', 'console')); + $projectId = 'dev'; + //$projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', 'console')); if ($projectId === 'console') { return $console; diff --git a/app/views/videos/hls-master.phtml b/app/views/videos/hls-master.phtml index 644a273005..ea215ca3e6 100644 --- a/app/views/videos/hls-master.phtml +++ b/app/views/videos/hls-master.phtml @@ -1,12 +1,12 @@ #EXTM3U #EXT-X-VERSION:3 getParam('audios', []) as $audio): ?> -#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="",DEFAULT=,URI="" +#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="",DEFAULT=,LANGUAGE="",URI="" getParam('subtitles', []) as $subtitle): ?> #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="",DEFAULT=,AUTOSELECT=NO,FORCED=NO,LANGUAGE="",URI="" getParam('renditions', []) as $rendition): ?> -#EXT-X-STREAM-INF:BANDWIDTH="",RESOLUTION="",NAME="",SUBTITLES="",AUDIO="" +#EXT-X-STREAM-INF:BANDWIDTH="",RESOLUTION="",NAME="",SUBTITLES="",AUDIO="" \ No newline at end of file diff --git a/app/workers/transcoding.php b/app/workers/transcoding.php index 7b8f7d8304..0bbb9d78d5 100644 --- a/app/workers/transcoding.php +++ b/app/workers/transcoding.php @@ -48,7 +48,7 @@ class TranscodingV1 extends Worker private string $renditionName; - private array $audios = []; + private array $audioTracks = []; private Database $database; @@ -75,12 +75,12 @@ class TranscodingV1 extends Worker $sourceVideo = Authorization::skip(fn() => $this->database->findOne('videos', [new Query('_uid', Query::TYPE_EQUAL, [$this->args['videoId']])])); if (empty($sourceVideo)) { - throw new Exception('Video not found'); + throw new Exception('Video not found', 404, Exception::VIDEO_NOT_FOUND); } $profile = Authorization::skip(fn() => $this->database->findOne('videos_profiles', [new Query('_uid', Query::TYPE_EQUAL, [$this->args['profileId']])])); if (empty($profile)) { - throw new Exception('profile not found'); + throw new Exception('Video profile not found', 404, Exception::VIDEO_PROFILE_NOT_FOUND); } $bucket = Authorization::skip(fn() => $this->database->getDocument('buckets', $sourceVideo['bucketId'])); @@ -126,7 +126,9 @@ class TranscodingV1 extends Worker } foreach ($ffprobe->streams($inPath)->audios()->getIterator() as $stream) { - $this->audios[] = $stream->get('tags')['language']; + if (!empty($stream->get('tags')['language'])) { + $this->audioTracks[] = $stream->get('tags')['language']; + } } $audioStreamCount = $ffprobe->streams($inPath)->audios()->count(); @@ -353,15 +355,14 @@ class TranscodingV1 extends Worker $query->setAttribute('status', self::STATUS_READY); Authorization::skip(fn() => $this->database->updateDocument($collection, $query->getId(), $query)); } catch (\Throwable $th) { - var_dump($th->getCode()); - var_dump($th->getMessage()); $query->setAttribute('metadata', json_encode([ 'code' => $th->getCode(), - 'message' => substr($th->getMessage(), 0, 3600), + 'message' => substr($th->getMessage(), 0, 255), ])); $query->setAttribute('status', self::STATUS_ERROR); Authorization::skip(fn() => $this->database->updateDocument($collection, $query->getId(), $query)); + throw new Exception($th->getMessage(), 500, Exception::GENERAL_UNKNOWN); } } @@ -412,7 +413,7 @@ class TranscodingV1 extends Worker } $hls->setFormat($format) - ->setAudiolanguages($this->audios) + ->setAudioTracks($this->audioTracks) ->setHlsTime($segmentSize) ->setHlsAllowCache(false) ->addRepresentation($representation) @@ -468,18 +469,32 @@ class TranscodingV1 extends Worker $handle = fopen($path, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { - $line = str_replace([",","\r","\n"], "", $line); + $line = str_replace(['"'], '', $line); + $attributes = explode(',', $line); + $language = null; + foreach ($attributes as $attribute) { + if (str_contains($attribute, "LANGUAGE")) { + $parts = explode('=', $attribute); + $language = $parts[1]; + } + } $end = strpos($line, 'm3u8'); if ($end !== false) { $start = strpos($line, $this->args['videoId']); if ($start !== false) { $path = substr($line, $start, ($end - $start) + 4); $parts = explode('_', $path); - $files[] = [ + $tmp = [ 'id' => $parts[1], 'type' => str_contains($line, "TYPE=AUDIO") ? 'audio' : 'video', 'path' => $path - ]; + ]; + + if (!empty($language)) { + $tmp ['language'] = $language; + } + + $files[] = $tmp; } } } diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index edd32346ba..9d5e18d3cd 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -180,6 +180,7 @@ class Exception extends \Exception public const VIDEO_SUBTITLE_SEGMENT_NOT_FOUND = 'video_subtitle_segment_not_found'; + private $type = ''; public function __construct(string $message, int $code = 0, string $type = Exception::GENERAL_UNKNOWN, \Throwable $previous = null)