Merci, je pense que je vous comprends. L’enregistrement audio direct n’est pas possible.
Le composant ne fonctionne actuellement pas en raison d’un problème de CSP.
L’ajout de https://cdn.jsdelivr.net/ au paramètre du site content security policy script src ne résout pas le problème : le bouton d’enregistrement fonctionnera, mais la création du fichier déclenchera une autre erreur JavaScript :
Refused to create a worker from 'blob:https://discourse.canapin.dev/a2d7c36c-2919-48a4-9ca6-8da59a2b020e' because it violates the following Content Security Policy directive: \"worker-src 'self' https://discourse.canapin.dev/assets/ https://discourse.canapin.dev/brotli_asset/ https://discourse.canapin.dev/javascripts/ https://discourse.canapin.dev/plugins/\".
Le Voice Recorder fonctionne (principalement) sur mon site. Voir les captures d’écran ci-dessous de mon processus…
Juste après l’enregistrement, rien n’est cliquable (mais je peux voir en rouge souligné que le fichier a bien été enregistré et inséré dans le post)…
Ensuite, en cliquant sur le bouton Précédent du navigateur (car le bouton Upload ne répond pas), je reviens à l’éditeur où je peux voir que le fichier a été inséré et fonctionne pour la lecture dans le volet d’aperçu…
Ensuite, après avoir cliqué sur + Créer un sujet, le post apparaît correctement…
Cependant, j’ai obtenu cette erreur dans la console immédiatement après avoir cliqué sur le bouton Arrêter l’enregistrement…
De plus, après avoir cliqué sur le bouton Upload, j’obtiens une deuxième erreur…
Et enfin, après avoir cliqué sur le bouton Annuler, j’obtiens une troisième erreur…
Malgré ces erreurs, le clip audio apparaît et se lit correctement dans le post.
J’essaie de comprendre les erreurs que je reçois en essayant d’utiliser ce composant de thème.
Outre le fait que la modale ne se ferme pas, tout le reste semble fonctionner.
(Et si je rafraîchis la page pour échapper à la modale, j’arrive dans le compositeur où le fichier a été enregistré et correctement téléchargé, et il est jouable, mais pas dans l’aperçu, seulement après avoir sauvegardé le message.)
Voici mon meilleur indice jusqu’à présent…

Est-ce une solution possible…
1) Lorsque la modale s’ouvre (après que j’ai cliqué sur le bouton microphone dans le compositeur)…
2) Lorsque je clique sur le bouton de lecture (dans la modale) pour revoir l’enregistrement avant le téléchargement…
3) Lorsque je clique sur le bouton de téléchargement (dans la modale)…
Voici le journal complet copié de l’inspecteur Chrome…
deprecate-shim.js:33 DEPRECATION: Function prototype extensions have been deprecated, please migrate from function(){}.on('foo') to on('foo', function() {}). [deprecation id: function-prototype-extensions.on] See https://deprecations.emberjs.com/v3.x#toc_function-prototype-extensions-on for more details.
(anonymous) @ deprecate-shim.js:33
e @ deprecate-shim.js:10
(anonymous) @ main.js:43
e @ deprecate-shim.js:10
(anonymous) @ main.js:78
e @ deprecate-shim.js:10
require.deprecate @ deprecate-shim.js:17
value @ function.js:139
(anonymous) @ autoplay-media.js:50
e.withPluginApi @ plugin-api.js:2247
initialize @ autoplay-media.js:47
i.initialize @ app.js:173
(anonymous) @ index.js:126
e.each @ dag-map.js:192
e.walk @ dag-map.js:121
e.each @ dag-map.js:66
e.topsort @ dag-map.js:72
_runInitializer @ index.js:138
runInstanceInitializers @ index.js:124
_bootSync @ instance.js:101
didBecomeReady @ application.js:656
p.invoke @ queue.ts:201
p.flush @ queue.ts:98
h.flush @ deferred-action-queues.ts:75
$._end @ index.ts:616
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._ensureInstance @ index.ts:791
$.schedule @ index.ts:384
_ @ index.js:351
waitForDOMReady @ application.js:409
init @ application.js:323
r @ index.js:388
_ @ core_object.js:122
create @ core_object.js:626
(anonymous) @ start-app.js:4
(anonymous) @ discourse-boot.js:20
(anonymous) @ discourse-boot.js:1
deprecated.js:64 Deprecation notice: DButton no longer supports @action as a string. Please refactor to use an closure action instead. [deprecation id: discourse.d-button-action-string]
e.default @ deprecated.js:64
y @ d-button.js:91
createComponent @ base-component-manager.js:31
createComponent @ ember-component-manager.js:50
create @ manager.js:419
create @ glimmer-component-with-deprecated-parent-view.js:11
(anonymous) @ runtime.js:2679
evaluate @ runtime.js:1052
evaluateSyscall @ runtime.js:4263
evaluateInner @ runtime.js:4234
evaluateOuter @ runtime.js:4227
next @ runtime.js:5058
_execute @ runtime.js:5045
execute @ runtime.js:5038
handleException @ runtime.js:4372
handleException @ runtime.js:4580
throw @ runtime.js:4319
evaluate @ runtime.js:2091
_execute @ runtime.js:4306
execute @ runtime.js:4291
rerender @ runtime.js:4606
render @ index.js:6751
(anonymous) @ index.js:7013
Mt @ runtime.js:4139
_renderRoots @ index.js:6996
_renderRootsTransaction @ index.js:7039
_revalidate @ index.js:7072
p.invoke @ queue.ts:201
p.flush @ queue.ts:98
h.flush @ deferred-action-queues.ts:75
$._end @ index.ts:616
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._end @ index.ts:623
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._end @ index.ts:623
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._ensureInstance @ index.ts:791
$.ensureInstance @ index.ts:579
scheduleRevalidate @ index.js:5390
dirtyTag @ validator.js:411
R @ validator.js:486
F @ index.js:497
z @ index.js:533
_set @ index.js:1848
set @ index.js:1790
r @ index.js:930
De @ index.js:1390
Te @ index.js:1385
set @ observable.js:175
_setModel @ composer.js:1000
await in _setModel (async)
open @ composer.js:980
await in open (async)
editPost @ topic.js:611
$._join @ index.ts:646
$.join @ index.ts:362
p @ index.js:157
(anonymous) @ index.js:708
a @ index.js:128
(anonymous) @ index.js:707
(anonymous) @ index.js:666
_sendComponentAction @ widget.js:275
(anonymous) @ widget.js:319
rerenderResult @ widget.js:291
sendWidgetAction @ widget.js:314
click @ button.js:122
(anonymous) @ hooks.js:236
(anonymous) @ hooks.js:202
rerenderResult @ widget.js:291
R @ hooks.js:202
(anonymous) @ hooks.js:236
dispatch @ jquery.js:5135
g.handle @ jquery.js:4939
deprecated.js:64 Deprecation notice: DButton no longer supports @action as a string. Please refactor to use an closure action instead. [deprecation id: discourse.d-button-action-string]
e.default @ deprecated.js:64
_triggerAction @ d-button.js:164
click @ d-button.js:144
deprecated.js:64 [THEME 11 'Voice Recorder'] Deprecation notice: Defining modals using a controller is deprecated. Use the component-based API instead. (modal: audio_upload) [deprecated since Discourse 3.1] [removal in Discourse 3.2] [deprecation id: discourse.modal-controllers] [info: https://meta.discourse.org/t/268057]
e.default @ deprecated.js:64
show @ modal.js:126
e.default @ show-modal.js:36
showAudioUploadModal @ audio-upload-initializer.js:15
send @ action_support.js:20
r @ index.js:388
_triggerAction @ d-button.js:166
click @ d-button.js:144
deprecated.js:64 Deprecation notice: DButton no longer supports @action as a string. Please refactor to use an closure action instead. [deprecation id: discourse.d-button-action-string]
e.default @ deprecated.js:64
y @ d-button.js:91
createComponent @ base-component-manager.js:31
createComponent @ ember-component-manager.js:50
create @ manager.js:419
create @ glimmer-component-with-deprecated-parent-view.js:11
(anonymous) @ runtime.js:2679
evaluate @ runtime.js:1052
evaluateSyscall @ runtime.js:4263
evaluateInner @ runtime.js:4234
evaluateOuter @ runtime.js:4227
next @ runtime.js:5058
_execute @ runtime.js:5045
execute @ runtime.js:5038
handleException @ runtime.js:4372
handleException @ runtime.js:4580
throw @ runtime.js:4319
evaluate @ runtime.js:2091
_execute @ runtime.js:4306
execute @ runtime.js:4291
rerender @ runtime.js:4606
render @ index.js:6751
(anonymous) @ index.js:7013
Mt @ runtime.js:4139
_renderRoots @ index.js:6996
_renderRootsTransaction @ index.js:7039
_revalidate @ index.js:7072
p.invoke @ queue.ts:201
p.flush @ queue.ts:98
h.flush @ deferred-action-queues.ts:75
$._end @ index.ts:616
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._end @ index.ts:623
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._end @ index.ts:623
_boundAutorunEnd @ index.ts:257
Promise.then (async)
n @ platform.ts:28
flush @ index.js:41
$._scheduleAutorun @ index.ts:803
$._ensureInstance @ index.ts:791
$.ensureInstance @ index.ts:579
scheduleRevalidate @ index.js:5390
dirtyTag @ validator.js:411
R @ validator.js:486
setter @ validator.js:702
c @ index.js:3501
close @ modal.js:62
close @ modal.js:177
show @ modal.js:122
e.default @ show-modal.js:36
showAudioUploadModal @ audio-upload-initializer.js:15
send @ action_support.js:20
r @ index.js:388
_triggerAction @ d-button.js:166
click @ d-button.js:144
Tous les conseils sont les bienvenus !
Avec l’iPad et l’iPhone, cela ne peut pas aller plus loin :
Même problème qu’auparavant, si je me souviens bien.
C’est un problème différent, et il est probablement là depuis longtemps. J’y jetterai un coup d’œil bientôt.
Pareil, mais dans le navigateur. Voici quelques erreurs de la console. Merci de lui avoir redonné vie, Angus.
Il semble que ce soit un problème de Safari. Je vais y jeter un œil sous peu.
Oui, c’est un problème de Safari et il existe depuis un certain temps (en fait, cela n’a probablement jamais fonctionné sur Safari).\n\nLe composant fonctionne sur Chrome et Firefox, comme avant. J’ai également mis à jour le composant pour utiliser l’API native JavaScript MediaRecorder (au lieu d’une bibliothèque npm vieille de 5 ans), cependant quelqu’un avec plus de temps libre devra faire en sorte que l’API native MediaRecorder et l’élément audio fonctionnent bien avec Safari. Je serais heureux d’aider avec une PR pour cette tâche spécifique.\n\n@peter.be @denvergeeks Peut-être que vous voulez concentrer vos efforts uniquement sur cela. Je serais heureux de faire de vous les mainteneurs du dépôt.
Merci, Angus, je n’aurai pas le temps de creuser davantage pour le moment.
Pour ce que ça vaut, j’ai essayé l’API MediaRecorder initialement lors du développement du plugin, mais j’ai rapidement constaté qu’il n’y avait aucun moyen de prendre en charge tous les navigateurs pour l’enregistrement et la lecture (il y a toujours une combinaison qui ne fonctionne pas) en raison de problèmes de codec/format. J’y ai passé pas mal de temps, mais pour autant que je sache, il n’y a aucun moyen de prendre en charge tous les navigateurs lors de l’utilisation de l’API MediaRecorder. C’est pourquoi j’ai utilisé un encodeur mp3.
Merci @peter.be et @angus ! J’ai testé et constaté que ce TC fonctionne maintenant, sauf :
-
pas dans Safari sur MacOS (bien qu’il fonctionne dans Chrome sur MacOS)
-
pas dans Safari, Chrome, Firefox ou Brave sur iOS
Voici une solution possible…
@denvergeeks avez-vous testé la lecture dans les autres navigateurs respectifs ?
Lorsque j’ai testé, l’enregistrement a fonctionné, mais surtout lorsque je passais de Safari à Chrome et vice versa, il y avait toujours des problèmes de lecture. Plus précisément, si je me souviens bien, les fichiers enregistrés via Chrome ne pouvaient pas être lus dans Safari, quel que soit le codec utilisé.
Mais vous avez dit que vous aviez testé cela et que cela avait fonctionné (avec toutes les combinaisons d’enregistrement et de lecture entre différents navigateurs) ?
Oui @peter.be – Je viens de tester et j’ai constaté que…
Enregistrements effectués dans Chrome sur Windows :
- se lisent dans Chrome sur MacOS
- se lisent dans FireFox sur MacOS
- ne se lisent pas dans Safari sur MacOS
- ne se lisent pas dans Chrome sur iOS
- ne se lisent pas dans Safari sur iOS
- ne se lisent pas dans FireFox sur iOS
- ne se lisent pas dans Brave sur iOS
D’accord…
C’est pourquoi j’ai choisi d’utiliser un encodeur mp3. L’utilisation de l’API MediaRecorder de cette manière ne prendra pas en charge tous les navigateurs.
Alors… sommes-nous de retour dans la situation où un plugin fonctionne, mais pas un composant ![]()
Le composant fonctionne comme toujours. Compte tenu de l’intérêt manifeste pour cela, j’essaierai de trouver du temps pour résoudre les problèmes de Safari plus tard cette semaine.
Ok, ce composant maintenant
- prend en charge tous les navigateurs (y compris Safari, Firefox et Chrome iOS)
- n’utilise aucune dépendance externe
- fonctionne avec le dernier Discourse
Comme disent nos amis britanniques : splendide en effet.
Cela fonctionne bien. Merci.











