Thank you, I think I understand you. Direct audio recording is not possible.
The component currently doesnāt work because of a CSP issue.
Adding https://cdn.jsdelivr.net/
to the content security policy script src site setting doesnāt fix the issue: the recording button will work, but the file creation will trigger another JS error:
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/".
Voice Recorder is (mostly) working on my site. See the below screenshots of my processā¦
Just after recording, nothing is clickable (but I can see there underlined in red that the file has indeed been recorded and inserted into the post)ā¦
Then clicking the Back browser button (because the Upload button is non-responsive) I arrive back to the composer where I can see the file has been inserted, and does work to play in the preview pane ā¦
Then, after clicking + Create Topic, the post appears properlyā¦
However, I did get this error in the console immediately after I had clicked the Stop Recording buttonā¦
Also, after clicking Upload button I get a second errorā¦
And finally, after clicking the Cancel button I get a third errorā¦
Despite these errors, the audio clip is appearing and playing correctly in the post.
Trying to understand the errors Iām getting in trying to use this Theme Component.
Other than the modal not closing, things otherwise seem to work.
(And if I refresh the page in order to escape the modal, I do arrive back in the composer where the file has recorded and properly uploaded, and is playable, but not in the preview, only after saving the post.)
Here is my best clue thus farā¦
Is this a possible solutionā¦
1) When the modal opens (after I click the microphone button in the composer)ā¦
2) When I click the playback button (in the modal) to review the recording prior to uploadā¦
3) When I click the upload button (in the modal)ā¦
Here is the entire log copied from the Chrome Inspectorā¦
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
$._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
Any tips appreciated!
With iPad and iPhone it canāt go forward from here:
Same issue than earlier, if Iām remembering right.
Thatās a different issue, and has probably been there for a long time. Iāll take a look at it soon.
Same here, but in the browser. Hereās some errors from the console. Thank you for bringing this back to life Angus.
It looks like a safari issue. Iāll take a look at that shortly.
Yeah, itās a safari issue and itās been there for a while (in fact this probably never worked on safari).
The component works in Chrome and Firefox, as it did before. Iāve further updated the component to use the native javascript MediaRecorder API (instead of a 5 year old npm library), however someone with some more time on their hands will need to get the native MediaRecorder API and audio
element to play nicely with Safari. Happy to help with a PR for that specific task.
@peter.be @denvergeeks Perhaps you want to focus your efforts just on that. Iād be happy to make you maintainers of the repository.
Thank you, Angus, I wonāt have the time to dive deeper into this as of now.
For what itās worth - Iāve tried the MediaRecorder API initially when developing the plugin, but quickly came to find that thereās no way to support all browsers for recording and playback (thereās always a combination that doesnāt work) because of codec/format issues. I spent quite some time with this, but as far as Iām aware, thereās no way to support all browsers when using the MediaRecorder API. Thatās why I used a mp3 encoder.
Thanks @peter.be and @angus! I have tested and found that this TC does now work, except:
-
not in Safari on MacOS (although it does work in Chrome on MacOS)
-
not in Safari or Chrome or Firefox or Brave on iOS
Hereās one possible solutionā¦
@denvergeeks have you tested playback in the respective other browser(s)?
When I tested, recording worked, but especially when switching from Safari to Chrome and vice versa there were always playback issues. Specifically, if I remember correctly, files recorded through Chrome would not play back in Safari, no matter what codec I used.
But you said you tested this and it worked (with all combinations for recording and playback between different browsers)?
Yes @peter.be ā I tested just now and found thatā¦
Recordings made in Chrome on Windows:
- do play in Chrome on MacOS
- do play in FireFox on MacOS
- do not play in Safari on MacOS
- do not play in Chrome on iOS
- do not play in Safari on iOS
- do not play in FireFox on iOS
- do not play in Brave on iOS
Rightā¦
Thatās why I chose to use a mp3 encoder. Only using the MediaRecorder API in that way wonāt support all browsers.
So⦠are we back in the situation where a plugin works, but a component not
The component works in the same way it always has. Considering the clear interest in this Iāll try to find some time to address the safari issues later this week.
Ok, this component now
- supports all browsers (including Safari, Firefox and Chrome iOS)
- uses no external dependencies
- works with the latest Discourse
As our british friends say: splendid indeed.
Works nicely. Thanks.