Skip to content

Commit 99d34c8

Browse files
committed
Plugin: Text2Speech: Allow to generate audio for LP items - refs #4622
1 parent 87c808c commit 99d34c8

File tree

6 files changed

+180
-2
lines changed

6 files changed

+180
-2
lines changed

main/lp/lp_add_audio.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,108 @@
243243
$page .= '<ul class="lp_resource">'.$documentTree.'</ul>';
244244
$page .= '</li>';
245245
$page .= '</ul>';
246+
247+
$text2speechPlugin = Text2SpeechPlugin::create();
248+
249+
if ($text2speechPlugin->isEnabled(true)) {
250+
$page .= '<div class="clearfix"></div>
251+
<h3 class="page-header">
252+
<small>'.get_lang('Or').'</small>
253+
'.$text2speechPlugin->get_title().'
254+
</h3>
255+
<div class="row">
256+
<div class="col-sm-8 col-sm-offset-2">
257+
<p>
258+
<button id="btn-tts" class="btn btn-default" type="button">
259+
<span id="btn-tts__spinner" class="fa fa-spinner fa-spin" aria-hidden="true" style="display: none;"></span>
260+
'.$text2speechPlugin->get_lang('GenerateAudioFromContent').'
261+
</button>
262+
</p>
263+
<p id="tts-player" id="tts-player" style="display: none;">
264+
<audio controls class="skip"></audio>
265+
</p>
266+
<p id="tts-warning" class="alert alert-warning" style="display: none;">
267+
'.get_lang('ErrorOccurred').'
268+
</p>
269+
<p>
270+
<button id="btn-save-tts" class="btn btn-primary" type="button" disabled>
271+
<span id="btn-save-tts__spinner" class="fa fa-spinner fa-spin" aria-hidden="true" style="display: none;"></span>
272+
'.get_lang('SaveRecordedAudio').'
273+
</button>
274+
</p>
275+
</div>
276+
</div>
277+
<script>
278+
$(function () {
279+
var btnTts = $(\'#btn-tts\');
280+
var btnTssSpiner = $(\'#btn-tts__spinner\');
281+
var ttsPlayer = $(\'#tts-player\');
282+
var ttsPlayerAudio = $(\'#tts-player audio\');
283+
var ttsWarning = $(\'#tts-warning\');
284+
285+
var btnSaveTts = $(\'#btn-save-tts\');
286+
var btnSaveTtsSpiner = $(\'#btn-save-tts__spinner\');
287+
288+
btnTts.on(\'click\', function (e) {
289+
e.preventDefault();
290+
291+
ttsWarning.hide();
292+
btnTts.prop(\'disabled\', true);
293+
btnTssSpiner.show();
294+
295+
$
296+
.ajax(_p.web_plugin + \'text2speech/convert.php?item_id='.$lp_item_id.'\')
297+
.done(function (response) {
298+
ttsPlayer.show();
299+
ttsPlayerAudio.prop(\'src\', response).mediaelementplayer();
300+
btnSaveTts.prop(\'disabled\', false);
301+
})
302+
.fail(function () {
303+
ttsPlayer.hide();
304+
ttsWarning.show();
305+
btnSaveTts.prop(\'disabled\', true);
306+
})
307+
.always(function () {
308+
btnTssSpiner.hide();
309+
btnTts.prop(\'disabled\', false);
310+
});
311+
});
312+
313+
btnSaveTts.on(\'click\', function () {
314+
btnSaveTts.prop(\'disabled\', true);
315+
btnSaveTtsSpiner.show();
316+
317+
var xhr = new XMLHttpRequest();
318+
xhr.open(\'GET\', ttsPlayerAudio.prop(\'src\'));
319+
xhr.responseType = \'blob\';
320+
xhr.onload = function (recordedBlob) {
321+
console.log(recordedBlob);
322+
var formData = new FormData();
323+
formData.append(\'file\', recordedBlob.target.response, \'audio-'.$lp_item_id.'\.wav\');
324+
formData.append(\'id\', '.$lp_item_id.');
325+
326+
$.ajax({
327+
url: $(\'#add_audio\').prop(\'action\'),
328+
data: formData,
329+
processData: false,
330+
contentType: false,
331+
type: \'POST\',
332+
success: function (fileURL) {
333+
if (!fileURL) {
334+
return;
335+
}
336+
337+
window.location.reload();
338+
}
339+
});
340+
};
341+
xhr.send();
342+
});
343+
});
344+
</script>
345+
';
346+
}
347+
246348
$page .= '</div>';
247349
$page .= '</div>';
248350

plugin/text2speech/convert.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/* For license terms, see /license.txt */
4+
5+
use Chamilo\CourseBundle\Entity\CDocument;
6+
use Chamilo\CourseBundle\Entity\CLpItem;
7+
use Symfony\Component\HttpFoundation\Request as HttpRequest;
8+
use Symfony\Component\HttpFoundation\Response as HttpResponse;
9+
10+
require_once __DIR__.'/../../main/inc/global.inc.php';
11+
12+
$httpRequest = HttpRequest::createFromGlobals();
13+
$httpResponse = HttpResponse::create();
14+
15+
$plugin = Text2SpeechPlugin::create();
16+
17+
$isAllowedToEdit = api_is_allowed_to_edit(false, true);
18+
19+
$em = Database::getManager();
20+
21+
try {
22+
if (!$plugin->isEnabled(true)
23+
|| !$isAllowedToEdit
24+
) {
25+
throw new Exception();
26+
}
27+
28+
$textToConvert = '';
29+
30+
if ($httpRequest->query->has('text')) {
31+
$textToConvert = $httpRequest->query->get('text');
32+
} elseif ($httpRequest->query->has('item_id')) {
33+
$itemId = $httpRequest->query->getInt('item_id');
34+
35+
$item = $em->find(CLpItem::class, $itemId);
36+
37+
if (!$item) {
38+
throw new Exception();
39+
}
40+
41+
$course = api_get_course_entity($item->getCId());
42+
$documentRepo = $em->getRepository(CDocument::class);
43+
44+
$document = $documentRepo->findOneBy([
45+
'cId' => $course->getId(),
46+
'iid' => $item->getPath(),
47+
]);
48+
49+
if (!$document) {
50+
throw new Exception();
51+
}
52+
53+
$textToConvert = file_get_contents(
54+
api_get_path(SYS_COURSE_PATH).$course->getDirectory().'/document/'.$document->getPath()
55+
);
56+
$textToConvert = strip_tags($textToConvert);
57+
}
58+
59+
if (empty($textToConvert)) {
60+
throw new Exception();
61+
}
62+
63+
$path = $plugin->convert($textToConvert);
64+
65+
$httpResponse->setContent($path);
66+
} catch (Exception $exception) {
67+
$httpResponse->setStatusCode(HttpResponse::HTTP_BAD_REQUEST);
68+
}
69+
70+
$httpResponse->send();

plugin/text2speech/lang/english.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
$strings['plugin_title'] = 'Text to Speech (Text2Speech)';
55
$strings['plugin_comment'] = 'Plugin to convert text to speech using a 3rd-party service';
66
$strings['tool_enable'] = 'Enable plugin';
7+
8+
$strings['GenerateAudioFromContent'] = 'Generate audio from content';

plugin/text2speech/lang/french.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
$strings['plugin_title'] = 'Texte pour parler (Text2Speech)';
55
$strings['plugin_comment'] = "Ce plugin permet de convertir du texte en parole à l'aide d'un service tiers";
66
$strings['tool_enable'] = 'Activer le plug-in';
7+
8+
$strings['GenerateAudioFromContent'] = 'Generate audio from content';

plugin/text2speech/lang/spanish.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
$strings['plugin_title'] = 'Texto a Voz (Text2Speech)';
44
$strings['plugin_comment'] = 'Este plugin es para convertir texto a voz usando un servicio de terceros';
55
$strings['tool_enable'] = 'Enable plugin';
6+
7+
$strings['GenerateAudioFromContent'] = 'Generar audio desde el contenido';

plugin/text2speech/src/mozillatts/MozillaTTS.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private function request(string $data): string
2424
{
2525
$filename = uniqid().'.wav';
2626
$filePath = $this->filePath.$filename;
27-
$resource = fopen($filePath, 'w');
27+
// $resource = fopen(realpath($filePath), 'w');
2828

2929
$client = new GuzzleHttp\Client();
3030
$client->get($this->url.'?api_key='.urlencode($this->apiKey).
@@ -33,7 +33,7 @@ private function request(string $data): string
3333
'Cache-Control' => 'no-cache',
3434
'Content-Type' => 'audio/wav',
3535
],
36-
'sink' => $resource,
36+
'sink' => $filePath,
3737
]);
3838

3939
return $filename;

0 commit comments

Comments
 (0)