mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
subtitle lan code
This commit is contained in:
@@ -569,6 +569,16 @@ return [
|
||||
'description' => 'Video subtitle not found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::VIDEO_LANGUAGE_CODE_NOT_VALID => [
|
||||
'name' => Exception::VIDEO_LANGUAGE_CODE_NOT_VALID,
|
||||
'description' => 'Video language code not valid.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::VIDEO_SUBTITLE_NOT_VALID => [
|
||||
'name' => Exception::VIDEO_SUBTITLE_NOT_VALID,
|
||||
'description' => 'Video subtitle not valid.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::VIDEO_NOT_FOUND => [
|
||||
'name' => Exception::VIDEO_NOT_FOUND,
|
||||
'description' => 'Video not found.',
|
||||
|
||||
@@ -163,6 +163,15 @@ App::put('/v1/videos/:videoId')
|
||||
validateFilePermissions($dbForProject, $video['bucketId'], $video['fileId'], $mode);
|
||||
|
||||
$file = validateFilePermissions($dbForProject, $bucketId, $fileId, $mode);
|
||||
|
||||
if (
|
||||
!str_starts_with($file->getAttribute('mimeType'), 'video/') &&
|
||||
!str_starts_with($file->getAttribute('mimeType'), 'audio/') &&
|
||||
$file->getAttribute('mimeType') !== 'application/ogg'
|
||||
) {
|
||||
throw new Exception(Exception::VIDEO_NOT_VALID);
|
||||
}
|
||||
|
||||
$video = Authorization::skip(fn() =>
|
||||
$dbForProject->updateDocument('videos', $videoId, new Document([
|
||||
'bucketId' => $bucketId,
|
||||
@@ -275,7 +284,7 @@ App::post('/v1/videos/:videoId/subtitles')
|
||||
->param('videoId', null, new UID(), 'Video unique ID.')
|
||||
->param('bucketId', '', new CustomId(), 'Subtitle bucket unique ID.')
|
||||
->param('fileId', '', new CustomId(), 'Subtitle file unique ID.')
|
||||
->param('name', '', new Text(128), 'Subtitle name.')
|
||||
->param('name', '', new Text(32), 'Subtitle name.')
|
||||
->param('code', '', new Text(3), 'Subtitle ISO 639-2 three letters alpha code.')
|
||||
->param('default', false, new Boolean(true), 'Default subtitle.')
|
||||
->inject('request')
|
||||
@@ -289,7 +298,7 @@ App::post('/v1/videos/:videoId/subtitles')
|
||||
$found = array_search($code, array_column($languages, 'code2'));
|
||||
|
||||
if (!$found) {
|
||||
throw new Exception(Exception::VIDEO_LANGUAGE_CODE_NOT_FOUND);
|
||||
throw new Exception(Exception::VIDEO_LANGUAGE_CODE_NOT_VALID);
|
||||
}
|
||||
|
||||
$video = Authorization::skip(fn() => $dbForProject->getDocument('videos', $videoId));
|
||||
@@ -301,15 +310,10 @@ App::post('/v1/videos/:videoId/subtitles')
|
||||
validateFilePermissions($dbForProject, $video['bucketId'], $video['fileId'], $mode);
|
||||
$file = validateFilePermissions($dbForProject, $bucketId, $fileId, $mode);
|
||||
|
||||
if (
|
||||
$file->getAttribute('mimeType') !== 'text/vtt' &&
|
||||
$file->getAttribute('mimeType') !== 'text/plain'
|
||||
) {
|
||||
if (!in_array($file->getAttribute('mimeType'), ['text/vtt','text/plain'])) {
|
||||
throw new Exception(Exception::VIDEO_SUBTITLE_NOT_VALID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$subtitle = Authorization::skip(fn() =>
|
||||
$dbForProject->createDocument('videos_subtitles', new Document([
|
||||
'videoId' => $videoId,
|
||||
@@ -374,12 +378,20 @@ App::patch('/v1/videos/:videoId/subtitles/:subtitleId')
|
||||
->param('bucketId', '', new CustomId(), 'Subtitle bucket unique ID.')
|
||||
->param('fileId', '', new CustomId(), 'Subtitle file unique ID.')
|
||||
->param('name', '', new Text(32), 'Subtitle customized name.')
|
||||
->param('code', '', new Text(3), 'Subtitle 3 letter code name.')
|
||||
->param('code', '', new Text(3), 'Subtitle ISO 639-2 three letters alpha code.')
|
||||
->param('default', false, new Boolean(true), 'Default subtitle.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(action: function (string $subtitleId, string $videoId, string $bucketId, string $fileId, string $name, string $code, bool $default, Response $response, Database $dbForProject) {
|
||||
|
||||
$code = strtolower($code);
|
||||
$languages = Config::getParam('locale-languages');
|
||||
$found = array_search($code, array_column($languages, 'code2'));
|
||||
|
||||
if (!$found) {
|
||||
throw new Exception(Exception::VIDEO_LANGUAGE_CODE_NOT_VALID);
|
||||
}
|
||||
|
||||
$subtitle = Authorization::skip(fn() => $dbForProject->getDocument('videos_subtitles', $subtitleId));
|
||||
|
||||
if ($subtitle->isEmpty()) {
|
||||
|
||||
@@ -186,7 +186,7 @@ class Exception extends \Exception
|
||||
public const VIDEO_SUBTITLE_NOT_FOUND = 'video_subtitle_not_found';
|
||||
public const VIDEO_NOT_FOUND = 'video_not_found';
|
||||
public const VIDEO_RENDITION_SEGMENT_NOT_FOUND = 'video_rendition_segment_not_found';
|
||||
public const VIDEO_LANGUAGE_CODE_NOT_FOUND = 'video_language_code_not_found';
|
||||
public const VIDEO_LANGUAGE_CODE_NOT_VALID = 'video_language_code_not_valid';
|
||||
public const VIDEO_SUBTITLE_SEGMENT_NOT_FOUND = 'video_subtitle_segment_not_found';
|
||||
public const VIDEO_SUBTITLE_NOT_VALID = 'video_subtitle_not_valid';
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ class VideosCustomServerTest extends Scope
|
||||
'fileId' => $this->getSubtitle()['$id']
|
||||
]);
|
||||
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/videos', [
|
||||
@@ -235,7 +236,7 @@ class VideosCustomServerTest extends Scope
|
||||
'code' => 'xxx',
|
||||
'default' => true,
|
||||
]);
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/videos/' . $videoId . '/subtitles', [
|
||||
'content-type' => 'application/json',
|
||||
@@ -301,7 +302,7 @@ class VideosCustomServerTest extends Scope
|
||||
$this->assertNotEmpty($response['body']['subtitles']);
|
||||
$this->assertNotEmpty($response['body']['subtitles'][0]['$id']);
|
||||
$this->assertEquals('English', $response['body']['subtitles'][0]['name']);
|
||||
$this->assertEquals('Eng', $response['body']['subtitles'][0]['code']);
|
||||
$this->assertEquals('eng', $response['body']['subtitles'][0]['code']);
|
||||
$this->assertEquals(true, $response['body']['subtitles'][0]['default']);
|
||||
|
||||
return $response['body']['subtitles'];
|
||||
@@ -525,7 +526,6 @@ class VideosCustomServerTest extends Scope
|
||||
|
||||
$this->assertEquals(2, $response['body']['total']);
|
||||
|
||||
|
||||
return $videoId;
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ class VideosCustomServerTest extends Scope
|
||||
public function testGetRenditions(string $videoId): string
|
||||
{
|
||||
|
||||
sleep(50);
|
||||
sleep(30);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/videos/' . $videoId . '/renditions', [
|
||||
'content-type' => 'application/json',
|
||||
@@ -543,30 +543,36 @@ class VideosCustomServerTest extends Scope
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, $response['body']['total']);
|
||||
$this->assertNotEmpty($response['body']['renditions']);
|
||||
|
||||
$rendition = $response['body']['renditions'][0];
|
||||
$this->assertEquals('600X400@834', $rendition['name']);
|
||||
$this->assertEquals('600', $rendition['width']);
|
||||
$this->assertEquals('400', $rendition['height']);
|
||||
$this->assertEquals('770', $rendition['videoBitRate']);
|
||||
$this->assertEquals('64', $rendition['audioBitRate']);
|
||||
$this->assertEquals('ready', $rendition['status']);
|
||||
$this->assertEquals('100', $rendition['progress']);
|
||||
|
||||
$rendition = $response['body']['renditions'][1];
|
||||
$this->assertEquals('300X200@634', $rendition['name']);
|
||||
$this->assertEquals('300', $rendition['width']);
|
||||
$this->assertEquals('200', $rendition['height']);
|
||||
$this->assertEquals('570', $rendition['videoBitRate']);
|
||||
$this->assertEquals('64', $rendition['audioBitRate']);
|
||||
$this->assertEquals('ready', $rendition['status']);
|
||||
$this->assertEquals('100', $rendition['progress']);
|
||||
|
||||
$renditionId = $response['body']['renditions'][0]['$id'];
|
||||
|
||||
foreach ($response['body']['renditions'] as $rendition) {
|
||||
$this->assertEquals('600X400@834', $rendition['name']);
|
||||
$this->assertEquals('600', $rendition['width']);
|
||||
$this->assertEquals('400', $rendition['height']);
|
||||
$this->assertEquals('770', $rendition['videoBitRate']);
|
||||
$this->assertEquals('64', $rendition['audioBitRate']);
|
||||
$this->assertEquals('ready', $rendition['status']);
|
||||
$this->assertEquals('100', $rendition['progress']);
|
||||
}
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/videos/' . $videoId . '/renditions/' . $renditionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals($renditionId, $response['body']['$id']);
|
||||
|
||||
@@ -585,17 +591,19 @@ class VideosCustomServerTest extends Scope
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
preg_match_all('#\b/videos[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $response['body'], $match);
|
||||
$this->assertEquals(4, count($match[0]));
|
||||
$renditionUri = $match[0][0];
|
||||
$subtitleUri = $match[0][1];
|
||||
|
||||
$this->assertEquals(3, count($match[0]));
|
||||
$subtitleUri = $match[0][0];
|
||||
$renditionUri = $match[0][2];
|
||||
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, $renditionUri, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
preg_match_all('#\b/videos[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $response['body'], $match);
|
||||
$this->assertEquals(10, count($match[0]));
|
||||
@@ -635,28 +643,27 @@ class VideosCustomServerTest extends Scope
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$xml = simplexml_load_string($response['body']);
|
||||
|
||||
$this->assertEquals("PT1M32.7S", $xml->attributes()->mediaPresentationDuration);
|
||||
$this->assertEquals("PT10.0S", $xml->attributes()->maxSegmentDuration);
|
||||
$this->assertEquals("PT20.0S", $xml->attributes()->minBufferTime);
|
||||
$subsCount = 0;
|
||||
$isVideo = false;
|
||||
$isAudio = false;
|
||||
$subs[] = ['id' => '2', 'lang' => 'Eng',];
|
||||
$subs[] = ['id' => '3', 'lang' => 'It',];
|
||||
$subs[] = ['id' => '2', 'lang' => 'English',];
|
||||
$subs[] = ['id' => '3', 'lang' => 'Italian',];
|
||||
foreach ($xml->Period->AdaptationSet as $adaptation) {
|
||||
if ((string)$adaptation['contentType'] === 'video') {
|
||||
$isVideo = true;
|
||||
$this->assertEquals("50/1", $adaptation['frameRate']);
|
||||
$this->assertEquals("300", $adaptation['maxWidth']);
|
||||
$this->assertEquals("960", $adaptation['maxWidth']);
|
||||
$this->assertEquals("30:17", $adaptation['par']);
|
||||
$this->assertEquals("und", $adaptation['lang']);
|
||||
foreach ($adaptation->Representation as $representation) {
|
||||
$this->assertEquals("video/mp4", $representation['mimeType']);
|
||||
$this->assertEquals("avc1.640015", $representation['codecs']);
|
||||
$this->assertEquals("300", $representation['width']);
|
||||
$this->assertEquals("200", $representation['height']);
|
||||
$this->assertEquals("20:17", $representation['sar']);
|
||||
$this->assertEquals("avc1.64001f", $representation['codecs']);
|
||||
$this->assertEquals("960", $representation['width']);
|
||||
$this->assertEquals("544", $representation['height']);
|
||||
$this->assertEquals("1:1", $representation['sar']);
|
||||
$this->assertEquals(10, $representation->SegmentList->SegmentURL->count());
|
||||
$videoSegmentBaseUrl = (string)$representation->BaseURL;
|
||||
$videoSegmentInitialization = (string)$representation->SegmentList->Initialization['sourceURL'];
|
||||
@@ -825,7 +832,7 @@ class VideosCustomServerTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
preg_match_all('#\b/videos[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $response['body'], $match);
|
||||
|
||||
var_dump($response['body']);
|
||||
$this->assertEquals(2, count($match[0]));
|
||||
|
||||
$renditionUri = $match[0][0];
|
||||
|
||||
Reference in New Issue
Block a user