Problem/Motivation

I want to use recordings not tied to a node or entity, but actually using webform for "loose" user-created content.

Proposed resolution

Providing a webform element (just some wrapping needed), will make this module compatible with the famous webform module.

This should be implemented using a sub module, as the webform dependency will be added.

Remaining tasks

  • Webform allows the editor to choose what element should be shown after the file is uploaded (The audio file recorder filed will always show the HTML5 audio player)

User interface changes

None.

API changes

None - yet ;)

Comments

ytsurk created an issue. See original summary.

ytsurk’s picture

Issue summary: View changes
StatusFileSize
new5.27 KB

Here a first patch.

ytsurk’s picture

Issue summary: View changes

adamfranco’s picture

Status: Active » Fixed

Thanks for the patch. I've included this in 1.0-beta2.

ytsurk’s picture

Thank you for letting this in. When we start promoting this at webform, we might get a lot of installs ;)

First we should to some readiness tasks. Like I said, I'm glad to help, but not right now ...

What do you think about this exposure of the element after the upload ("File upload preview"), this offers itself to be reused by the fieldwidget ..

adamfranco’s picture

Status: Fixed » Active

I'm not quite sure I understand your question:

"What do you think about this exposure of the element after the upload ("File upload preview"), this offers itself to be reused by the fieldwidget .."

Do you mean: Is the preview a security issue?

The preview provided by the audiorecorder module after the recording is completed is all in the browser using data-URLs -- no data has yet been sent to the server yet and so it is private to the current browser window. It has just been injected into the form as hidden elements via javascript.

js/recorder.js lines 73-84:

                // Set our hidden input field to the base-64 value of the recorded
                // data so that it is submitted on POST. The value will look like:
                //   data:audio/mpeg;base64,//uQxAAAAAAAAAAAAAAA...VVU=
                // The file inputs themselves are read-only, so we can't modify and
                // upload the blob directly with them.
                var reader = new FileReader();
                reader.readAsDataURL(blob);
                reader.onloadend = function() {
                    uploadInput.siblings('input.audio_recorder_file-recording').first().val(reader.result);
                }

              });

Then...

js/recorder.js lines 7-15:

      // Rewrite any audio file links as players for preview.
      $(".form-audio-recorder-file .file--audio", context).once('audiorecorder').each(function(index) {
        var fileLinkWrapper = $(this);
        var fileLink = $('a', fileLinkWrapper).first();
        var preview = $('<audio controls src="">');
        preview.attr("src", fileLink.attr("href"));
        fileLinkWrapper.after(preview);
        fileLinkWrapper.hide();
      });

And here is the [dynamic] markup of the field in the browser after recording, before submitting:

<div class="js-form-item form-item js-form-type-audio-recorder-file form-type-audio-recorder-file js-form-item-my-recording-upload form-item-my-recording-upload form-no-label">        
  <div id="edit-my-recording-upload--2" class="js-form-managed-file form-managed-file">
    <input accept="audio/*" data-drupal-selector="edit-my-recording-upload-upload" type="file" id="edit-my-recording-upload-upload" name="files[my_recording_upload]" size="22" class="js-form-file form-file" style="display: none;">
    <audio controls="" src="blob:https://www.example.com/e813fa44-4b33-1440-8dd4-2cde556872d7" style=""></audio>
    <button class="button">Record Again</button>
    <input class="js-hide button js-form-submit form-submit" data-drupal-selector="edit-my-recording-upload-upload-button" formnovalidate="formnovalidate" type="submit" id="edit-my-recording-upload-upload-button" name="my_recording_upload_upload_button" value="Upload">
    <input data-drupal-selector="edit-my-recording-upload-fids" type="hidden" name="my_recording[upload][fids]">
    <input class="audio_recorder_file-recording" data-drupal-selector="edit-my-recording-upload-recording" type="hidden" name="my_recording[upload][recording]" value="data:audio/mpeg;base64,//uQxAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA...much-more-data.....qqqqqqqqqqqqqqqqqqqqqqqqqqqq">
  </div>
</div>

Note the blob:.... URL for the <audio src element -- it is loading out of the browser's working data rather than loading from the server.

ytsurk’s picture

Status: Active » Fixed

Thank you for the quick response, and detailed clarification of the recording process, haven't gone so far yet, and thought it was already stored on the server.

But actually it's not what I meant, I thought of letting a site builder choose how the uploaded "blob" shall be presented,
in a player, as downloadable file, just as text, as I have seen in the webform module. This makes only partially sense, as the file resides as blob in the browser, nor webform's code can be reused. So I would stick with the HTML5 audioplayer only for now.

Regarding security, it's all up to the site builders. If a webform or entity form is exposed to anonymous users, they could fill the disk of the server, or even use the servers disk to store they're audio (if a public:// file-system is used).

We maybe should add a note about this on the project page, so, that we recommend to use a private file system, when exposing to anon users - and also that exposing the audiorecorder to anon users is an open door for denial of service attacks.

ytsurk’s picture

Ah - and also add a note on the project page, that this module supports webform ;)

adamfranco’s picture

I've added this note on the project page about webform support.

As the Webform "Audio recorder" element doesn't introduce any security or file-visibility issues beyond those that are already present for any type of file-upload form submission, I'd rather not devote a lot of project-page text to the intricacies of that use case. I'd be happy to add more notes to the README though if you'd like to take a stab at drafting something.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.