ginga subtitle

This commit is contained in:
aynsix
2020-06-24 19:51:06 +03:00
parent 27b424f712
commit d9f11cbe06
3 changed files with 153 additions and 17 deletions

View File

@@ -22,13 +22,17 @@ use Alchemy\Phrasea\Metadata\PhraseanetMetadataReader;
use Alchemy\Phrasea\Metadata\PhraseanetMetadataSetter; use Alchemy\Phrasea\Metadata\PhraseanetMetadataSetter;
use Alchemy\Phrasea\Record\RecordWasRotated; use Alchemy\Phrasea\Record\RecordWasRotated;
use DataURI\Parser; use DataURI\Parser;
use GuzzleHttp\Client;
use MediaAlchemyst\Alchemyst; use MediaAlchemyst\Alchemyst;
use MediaVorus\MediaVorus; use MediaVorus\MediaVorus;
use PHPExiftool\Reader;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class ToolsController extends Controller class ToolsController extends Controller
{ {
const GINGER_BASE_URL = "https://test.api.ginger.studio/recognition/speech";
const GINGER_TOKEN = "39c6011d-3bbe-4f39-95d0-a327d320ded4";
const GINGER_TRANSCRIPT_FORMAT = "text/vtt";
use DataboxLoggerAware; use DataboxLoggerAware;
use DispatcherAware; use DispatcherAware;
use FilesystemAware; use FilesystemAware;
@@ -45,7 +49,6 @@ class ToolsController extends Controller
if (count($records) == 1) { if (count($records) == 1) {
/** @var \record_adapter $record */ /** @var \record_adapter $record */
$record = $records->first(); $record = $records->first();
$databox = $record->getDatabox();
/**Array list of subdefs**/ /**Array list of subdefs**/
$listsubdef = array_keys($record-> get_subdefs()); $listsubdef = array_keys($record-> get_subdefs());
@@ -88,14 +91,13 @@ class ToolsController extends Controller
$metadatas = true; $metadatas = true;
} }
} }
$conf = $this->getConf();
return $this->render('prod/actions/Tools/index.html.twig', [ return $this->render('prod/actions/Tools/index.html.twig', [
'records' => $records, 'records' => $records,
'record' => $record, 'record' => $record,
'recordSubdefs' => $recordAccessibleSubdefs, 'recordSubdefs' => $recordAccessibleSubdefs,
'metadatas' => $metadatas, 'metadatas' => $metadatas,
'listsubdef' => $listsubdef 'listsubdef' => $listsubdef
]); ]);
} }
@@ -118,6 +120,7 @@ class ToolsController extends Controller
} }
foreach ($records as $record) { foreach ($records as $record) {
/** @var \media_subdef $subdef */
foreach ($record->get_subdefs() as $subdef) { foreach ($record->get_subdefs() as $subdef) {
if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) { if ($subdef->get_type() !== \media_subdef::TYPE_IMAGE) {
continue; continue;
@@ -146,6 +149,7 @@ class ToolsController extends Controller
foreach ($selection as $record) { foreach ($selection as $record) {
$substituted = false; $substituted = false;
/** @var \media_subdef $subdef */
foreach ($record->get_subdefs() as $subdef) { foreach ($record->get_subdefs() as $subdef) {
if ($subdef->is_substituted()) { if ($subdef->is_substituted()) {
$substituted = true; $substituted = true;
@@ -362,14 +366,6 @@ class ToolsController extends Controller
return $this->app->json($return); return $this->app->json($return);
} }
/**
* @return Reader
*/
private function getExifToolReader()
{
return $this->app['exiftool.reader'];
}
/** /**
* @return Alchemyst * @return Alchemyst
*/ */
@@ -449,13 +445,130 @@ class ToolsController extends Controller
try { try {
$record->set_metadatas($metadatas); $record->set_metadatas($metadatas);
} }
catch (Exception $e) { catch (\Exception $e) {
return $this->app->json(['success' => false, 'errorMessage' => $e->getMessage()]); return $this->app->json(['success' => false, 'errorMessage' => $e->getMessage()]);
} }
return $this->app->json(['success' => true, 'errorMessage' => '']); return $this->app->json(['success' => true, 'errorMessage' => '']);
} }
public function autoSubtitleAction(Request $request)
{
$return = ['success' => false, 'errorMessage' => ''];
$record = new \record_adapter($this->app,
(int)$request->request->get("databox_id"),
(int)$request->request->get("record_id")
);
if ($record->has_preview() && ($previewLink = $record->get_preview()->get_permalink()) !== null && $request->request->get("meta_struct_id")) {
switch ($request->request->get("subtitle_language_source")) {
case 'En':
$language = 'en-GB';
break;
case 'De':
$language = 'de-DE';
break;
case 'Fr':
default:
$language = 'fr-FR';
break;
}
$permalinkUrl = $previewLink->get_url()->__toString();
$gingerClient = new Client();
try {
$response = $gingerClient->post(self::GINGER_BASE_URL.'/media/', [
'headers' => [
'Authorization' => 'token '.self::GINGER_TOKEN
],
'json' => [
'url' => $permalinkUrl,
'language' => $language
]
]);
} catch(\Exception $e) {
$return['errorMessage'] = $e->getMessage();
return $this->app->json($return);
}
if ($response->getStatusCode() !== 201) {
return $this->app->json($return);
}
$responseMediaBody = $response->getBody()->getContents();
$responseMediaBody = json_decode($responseMediaBody,true);
$checkStatus = null;
do {
// first wait 5 second before check subtitling status
sleep(5);
try {
$response = $gingerClient->get(self::GINGER_BASE_URL.'/task/'.$responseMediaBody['task_id'].'/', [
'headers' => [
'Authorization' => 'token '.self::GINGER_TOKEN
]
]);
} catch (\Exception $e) {
$checkStatus = false;
}
if ($response->getStatusCode() !== 200) {
$checkStatus = false;
break;
}
$responseTaskBody = $response->getBody()->getContents();
$responseTaskBody = json_decode($responseTaskBody,true);
} while($responseTaskBody['status'] != 'SUCCESS');
if (!$checkStatus) {
return $this->app->json($return);
}
try {
$response = $gingerClient->get(self::GINGER_BASE_URL.'/media/'.$responseMediaBody['media']['uuid'].'/', [
'headers' => [
'Authorization' => 'token '.self::GINGER_TOKEN,
'ACCEPT' => self::GINGER_TRANSCRIPT_FORMAT
],
'query' => [
'language' => $language
]
]);
} catch (\Exception $e) {
return $this->app->json($return);
}
if ($response->getStatusCode() !== 201) {
return $this->app->json($return);
}
$transcriptContent = $response->getBody()->getContents();
$metadatas[0] = [
'meta_struct_id' => (int)$request->request->get("meta_struct_id"),
'meta_id' => '',
'value' => $transcriptContent
];
try {
$record->set_metadatas($metadatas);
} catch (\Exception $e) {
$return['errorMessage'] = $e->getMessage();
return $this->app->json($return);
}
$return['success'] = true;
}
return $this->app->json($return);
}
public function videoEditorAction(Request $request) public function videoEditorAction(Request $request)
{ {
$records = RecordsRequest::fromRequest($this->app, $request, false); $records = RecordsRequest::fromRequest($this->app, $request, false);
@@ -491,7 +604,7 @@ class ToolsController extends Controller
$fieldValue = array_pop($fieldValues); $fieldValue = array_pop($fieldValues);
$field['value'] = $fieldValue->getValue(); $field['value'] = $fieldValue->getValue();
} }
$videoTextTrackFields[] = $field; $videoTextTrackFields[$meta->get_id()] = $field;
unset($field); unset($field);
} }
} }

View File

@@ -72,6 +72,9 @@ class Tools implements ControllerProviderInterface, ServiceProviderInterface
$controllers->post('/metadata/save/', 'controller.prod.tools:saveMetasAction') $controllers->post('/metadata/save/', 'controller.prod.tools:saveMetasAction')
->bind('prod_tools_metadata_save'); ->bind('prod_tools_metadata_save');
$controllers->post('/auto-subtitle/', 'controller.prod.tools:autoSubtitleAction')
->bind('prod_tools_auto_subtitle');
$controllers->get('/videoEditor', 'controller.prod.tools:videoEditorAction'); $controllers->get('/videoEditor', 'controller.prod.tools:videoEditorAction');
return $controllers; return $controllers;

View File

@@ -242,9 +242,9 @@
<p class="item"> <p class="item">
<label>{{ "prod:videoeditor:subtitleRequestTab:label:: Source Audio language" | trans }}</label> <label>{{ "prod:videoeditor:subtitleRequestTab:label:: Source Audio language" | trans }}</label>
<select name="subtitle_language_source" id="subtitle_language_source"> <select name="subtitle_language_source" id="subtitle_language_source">
<option value="fr">Fr</option> {% for videoTextTrackField in videoTextTrackFields %}
<option value="en">En</option> <option value="{{ videoTextTrackField.meta_struct_id}}">{{ videoTextTrackField.label}}</option>
<option value="de">De</option> {% endfor %}
</select> </select>
</p> </p>
<p class="item"> <p class="item">
@@ -352,4 +352,24 @@
overlapChapters: {% if overlapChapters != NULL %}{{ overlapChapters }}{% else %}1{% endif %}, overlapChapters: {% if overlapChapters != NULL %}{{ overlapChapters }}{% else %}1{% endif %},
} }
}; };
$('#submit-subtitle-request').on('click', function (e) {
e.preventDefault();
console.log("auto-subtitle process");
$.ajax({
type: 'POST',
url: '/prod/tools/auto-subtitle/',
dataType: 'json',
data: {
databox_id: {{ record.get_base_id }},
record_id: {{ record.get_record_id }},
meta_struct_id: $('#subtitle_language_source').val(),
subtitle_language_source: $('#subtitle_language_source option:selected').text()
},
success: function success(data) {
console.log(data);
}
});
});
</script> </script>