Gracias, creo que te entiendo. No es posible grabar audio directamente.
El componente actualmente no funciona debido a un problema de CSP.
Agregar https://cdn.jsdelivr.net/ a la configuración del sitio content security policy script src no soluciona el problema: el botón de grabación funcionará, pero la creación del archivo provocará otro error de JS:
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/".
El Grabador de Voz funciona (en su mayor parte) en mi sitio. Vea las siguientes capturas de pantalla de mi proceso…
Justo después de grabar, nada es clicable (pero puedo ver que está subrayado en rojo que el archivo se ha grabado e insertado correctamente en la publicación)…
Luego, al hacer clic en el botón Atrás del navegador (porque el botón Subir no responde), vuelvo al editor donde puedo ver que el archivo se ha insertado y funciona para reproducirse en el panel de vista previa…
Luego, después de hacer clic en + Crear Tema, la publicación aparece correctamente…
Sin embargo, recibí este error en la consola inmediatamente después de hacer clic en el botón Detener Grabación…
Además, después de hacer clic en el botón Subir recibo un segundo error…
Y finalmente, después de hacer clic en el botón Cancelar recibo un tercer error…
A pesar de estos errores, el clip de audio aparece y se reproduce correctamente en la publicación.
Intentando entender los errores que obtengo al usar este Componente de Tema.
Aparte de que el modal no se cierra, por lo demás todo parece funcionar.
(Y si actualizo la página para escapar del modal, vuelvo al compositor donde el archivo se ha grabado y subido correctamente, y es reproducible, pero no en la vista previa, solo después de guardar la publicación).
Aquí está mi mejor pista hasta ahora…

¿Es esta una posible solución…
1) Cuando se abre el modal (después de hacer clic en el botón del micrófono en el compositor)…
2) Cuando hago clic en el botón de reproducción (en el modal) para revisar la grabación antes de subirla…
3) Cuando hago clic en el botón de subir (en el modal)…
Aquí está el registro completo copiado del Inspector de 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
_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
¡Cualquier consejo es bienvenido!
Ese es un problema diferente, y probablemente ha estado ahí por mucho tiempo. Le echaré un vistazo pronto.
Lo mismo aquí, pero en el navegador. Aquí hay algunos errores de la consola. Gracias por darle vida de nuevo a esto, Angus.
Parece un problema de Safari. Lo revisaré en breve.
Sí, es un problema de Safari y ha estado ahí por un tiempo (de hecho, esto probablemente nunca funcionó en Safari).
El componente funciona en Chrome y Firefox, como lo hacía antes. He actualizado aún más el componente para usar la API nativa de MediaRecorder de JavaScript (en lugar de una biblioteca de npm de 5 años), sin embargo, alguien con más tiempo libre necesitará hacer que la API nativa de MediaRecorder y el elemento audio funcionen bien con Safari. Estaré encantado de ayudar con una PR para esa tarea específica.
@peter.be @denvergeeks Quizás quieran centrar sus esfuerzos solo en eso. Estaría feliz de hacerlos mantenedores del repositorio.
Gracias, Angus, no tendré tiempo de profundizar en esto por ahora.
Por si sirve de algo, probé la API MediaRecorder inicialmente al desarrollar el plugin, pero rápidamente descubrí que no hay forma de admitir todos los navegadores para grabar y reproducir (siempre hay una combinación que no funciona) debido a problemas de códecs/formatos. Pasé bastante tiempo con esto, pero hasta donde sé, no hay forma de admitir todos los navegadores al usar la API MediaRecorder. Por eso utilicé un codificador mp3.
¡Gracias @peter.be y @angus! He probado y he descubierto que esta TC ahora funciona, excepto:
-
no en Safari en MacOS (aunque sí funciona en Chrome en MacOS)
-
no en Safari, Chrome, Firefox o Brave en iOS
Aquí hay una posible solución…
@denvergeeks ¿has probado la reproducción en los otros navegadores respectivos?
Cuando probé, la grabación funcionó, pero especialmente al cambiar de Safari a Chrome y viceversa, siempre hubo problemas de reproducción. Específicamente, si mal no recuerdo, los archivos grabados a través de Chrome no se reproducían en Safari, sin importar el códec que usara.
Pero dijiste que probaste esto y funcionó (¿con todas las combinaciones de grabación y reproducción entre diferentes navegadores)?
Sí @peter.be – Acabo de probar y descubrí que…
Grabaciones realizadas en Chrome en Windows:
- se reproducen en Chrome en MacOS
- se reproducen en FireFox en MacOS
- no se reproducen en Safari en MacOS
- no se reproducen en Chrome en iOS
- no se reproducen en Safari en iOS
- no se reproducen en FireFox en iOS
- no se reproducen en Brave en iOS
Bien…
Por eso elegí usar un codificador mp3. Usar la API MediaRecorder de esa manera no es compatible con todos los navegadores.
Entonces… ¿estamos de vuelta en la situación en la que un plugin funciona, pero un componente no ![]()
El componente funciona de la misma manera que siempre. Teniendo en cuenta el claro interés en esto, intentaré encontrar tiempo para abordar los problemas de Safari más adelante esta semana.
Ok, este componente ahora
- soporta todos los navegadores (incluyendo Safari, Firefox y Chrome iOS)
- no usa dependencias externas
- funciona con el último Discourse
Como dicen nuestros amigos británicos: espléndido, en efecto.
Funciona bien. Gracias.











