Компонент диктофона

Спасибо, я думаю, что вас понял. Прямая аудиозапись невозможна.

Компонент в настоящее время не работает из-за проблемы с CSP.

Добавление https://cdn.jsdelivr.net/ в настройку сайта content security policy script src не решает проблему: кнопка записи будет работать, но создание файла вызовет другую ошибку JS:

Отказано в создании worker из 'blob:https://discourse.canapin.dev/a2d7c36c-2919-48a4-9ca6-8da59a2b020e', так как это нарушает следующую директиву Content Security Policy: "worker-src 'self' https://discourse.canapin.dev/assets/ https://discourse.canapin.dev/brotli_asset/ https://discourse.canapin.dev/javascripts/ https://discourse.canapin.dev/plugins/".

Голосовой диктофон (в основном) работает на моём сайте. Ниже приведены скриншоты моего процесса…

Сразу после записи ничего не кликабельно (но я вижу, что файл действительно записан и вставлен в пост, о чём говорит подчеркнутая красным область)…

Затем, нажав кнопку «Назад» в браузере (поскольку кнопка «Загрузить» не реагирует), я возвращаюсь к редактору, где вижу, что файл вставлен и воспроизводится в окне предпросмотра…

После нажатия на + Создать тему пост отображается корректно…

Однако сразу после нажатия кнопки Остановить запись в консоли возникла следующая ошибка…

Также после нажатия кнопки Загрузить появляется вторая ошибка…

И наконец, после нажатия кнопки Отмена возникает третья ошибка…

Несмотря на эти ошибки, аудиоклип отображается и воспроизводится в посте корректно.

Пытаюсь разобраться с ошибками, которые возникают при использовании этого компонента темы.

Помимо того, что модальное окно не закрывается, остальное, кажется, работает.

(И если я обновляю страницу, чтобы выйти из модального окна, я возвращаюсь в редактор, где файл уже записан и корректно загружен, воспроизводится, но не в предварительном просмотре, а только после сохранения публикации.)

Вот моя лучшая подсказка на данный момент…

Возможно ли это решение…

1) Когда модальное окно открывается (после нажатия кнопки микрофона в редакторе)…

2) Когда я нажимаю кнопку воспроизведения (в модальном окне), чтобы прослушать запись перед загрузкой…

3) Когда я нажимаю кнопку загрузки (в модальном окне)…

Вот полный лог, скопированный из инспектора 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
$._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

Буду благодарен за любые советы!

2 лайка

Я исправил этот компонент темы.

6 лайков

На iPad и iPhone дальше продвинуться не удаётся:

Та же проблема, что и раньше, если я правильно помню.

Это другая проблема, и она, вероятно, существовала уже давно. Я скоро займусь этим.

4 лайка

У меня тоже, но в браузере. Вот несколько ошибок из консоли. Спасибо, что вернули это к жизни, Ангус.

2 лайка

Похоже, это проблема с Safari. Я скоро займусь этим.

1 лайк

Да, это проблема Safari, и она существует уже давно (на самом деле, это, вероятно, никогда не работало в Safari).

Компонент работает в Chrome и Firefox, как и раньше. Я дополнительно обновил компонент, чтобы использовать нативный JavaScript API MediaRecorder (вместо устаревшей npm-библиотеки пятилетней давности). Однако кому-то, у кого есть больше времени, нужно будет заставить нативный API MediaRecorder и элемент audio корректно работать в Safari. Я с радостью помогу с PR для этой конкретной задачи.

@peter.be @denvergeeks, возможно, вам стоит сосредоточить свои усилия именно на этом. Я с радостью сделаю вас мейнтейнерами репозитория.

6 лайков

Спасибо, Энгус. На данный момент у меня не будет времени углубляться в эту тему.

Кстати, я изначально пробовал использовать API MediaRecorder при разработке плагина, но быстро выяснил, что из-за проблем с кодеками и форматами невозможно обеспечить поддержку записи и воспроизведения во всех браузерах (всегда находится какая-то комбинация, которая не работает). Я потратил на это довольно много времени, но, насколько мне известно, при использовании API MediaRecorder нет способа обеспечить поддержку всех браузеров. Вот почему я использовал mp3-кодировщик.

3 лайка

Спасибо @peter.be и @angus! Я протестировал и обнаружил, что этот TC теперь работает, за исключением:

  1. не работает в Safari на macOS (хотя работает в Chrome на macOS)

  2. не работает в Safari, Chrome, Firefox или Brave на iOS

Вот одно из возможных решений…

3 лайка

@denvergeeks, вы проверяли воспроизведение в других браузерах?

Когда я тестировал, запись работала, но особенно при переключении с Safari на Chrome и наоборот всегда возникали проблемы с воспроизведением. В частности, если я правильно помню, файлы, записанные через Chrome, не воспроизводились в Safari, независимо от используемого кодека.

Но вы сказали, что проверяли это, и всё работало (со всеми комбинациями записи и воспроизведения между разными браузерами)?

Да, @peter.be — я только что проверил и обнаружил, что…

Записи, сделанные в Chrome на Windows:

  • воспроизводятся в Chrome на MacOS
  • воспроизводятся в Firefox на MacOS

  • не воспроизводятся в Safari на MacOS
  • не воспроизводятся в Chrome на iOS
  • не воспроизводятся в Safari на iOS
  • не воспроизводятся в Firefox на iOS
  • не воспроизводятся в Brave на iOS
1 лайк

Верно…

Именно поэтому я решил использовать mp3-кодек. Использование только MediaRecorder API таким образом не будет поддерживаться во всех браузерах.

1 лайк

Так… мы снова вернулись к ситуации, когда плагин работает, а компонент — нет :wink:

2 лайка

Компонент работает так же, как и всегда. Учитывая явный интерес к этому вопросу, я постараюсь найти время, чтобы разобраться с проблемами в Safari в конце этой недели.

4 лайка

Отлично, этот компонент теперь:

  • поддерживает все браузеры (включая Safari, Firefox и Chrome для iOS)
  • не требует внешних зависимостей
  • работает с последней версией Discourse
9 лайков

Как говорят наши британские друзья: действительно великолепно.

Работает отлично. Спасибо.

2 лайка

Счастливый Очень Смешной GIF от Disney Zootopia

2 лайка