Skip to content

Commit c930334

Browse files
committed
Plugin: Text2Speech: Allow generate audio for LP items - refs chamilo#4622
1 parent c328982 commit c930334

File tree

3 files changed

+173
-2
lines changed

3 files changed

+173
-2
lines changed

main/lp/lp_add_audio.php

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

plugin/text2speech/convert.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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();
71+

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)