Record Media

Why The Addition of This Feature

Especially for audio files, the ability to record and upload media ensures that users will upload media. Many users probably do not have audio files saved. Allowing the ability to record and upload unique images / audio recordings / videos also ensures that unique content will be uploaded.

How It Works / Things To Remember

Generally, This is How File Uploads Should Look On Load:

<label for="INPUT_NAME" class="mt-2 bold">LABEL:</label>
<input type="file" accept="(audio|image|video)/*" id="INPUT_NAME" name="INPUT_NAME" class="mt-1" />
<output class="mt-2 block" for="INPUT_NAME"></output>

When you want to include a default image on the page include this as the nextElementSibling of the file input:

<input type="file" accept="(audio|image|video)/*" id="INPUT_NAME-text" name="INPUT_NAME-text" class="mt-1" />
Quick Info on Media Types
Component Accepted Types Recorded Format Max Size Max Number (Multiple) Validation Admin Only Cost
Image: jpeg, jpg, png, webp, gif, bmp, svg webp 5MB 30 Google Image API false Amazon S3 Pricing
Cloud Vision API Pricing
AWS Lambda Pricing
Audio: m4a, flac, mp3, mp4, wav, wma, aac, webm, mpeg, mov, ogg TBD 300MB 10 Not Yet - should transcribe audio and test that way true Amazon S3 Pricing
Video: mp4, mov, avi, wmv, avchd, webm, flv TBD 300MB 10 Not yet - use Amazon or Google Video true Amazon S3 Pricing
  1. Image Upload
    1. Since we use the Pintura image editor to allow users to edit images on the client, and since we need to keep track of what image the editor is currently using and to avoid loading multiple editors for a sing image input and for multiple other reasons, we keep track of the uploaded images in the client side object seen below:
    2. type ImageFilesArray = {
        name: string,
        currentUrl: string,
        currentFile: File,
        type: string,
        inputName: string
      }[];
      type KeepTrackType = {
        images: {
          [nameOfUploadedFile: string]: {
            inputName: string,
            name: string,
            currentUrl: string,
            currentFile: File,
            input: HTMLInputElement,
            index: number,
            imageEditor: PinturaEditor|undefined,
            type: string
          }
        },
        multipleImages: {
          [inputName: string]: {
            files: ImageFilesArray,
            input: HTMLInputElement,
            imageEditor: PinturaEditor|undefined
          }
        }
      }
      /**
        * Object to keep track of all images, audio, and videos that have been submitted on the page. This object should be cleared on page change
        *  
        */
      const KeepTrackPage: KeepTrackType = {
        images: {},
        multipleImages: {}
      };
    3. When the page sees any image, audio, or video components, the record-media.js JavaScript is lazy-loaded.
    4. We set two event listeners on <input type="file" accept="image/*" /> elements. We listen for the change and delete-image events.
    5. When a change event is invoked by the user either uploading or taking an image with their device, we get the name, and multiple attributes of the input and get the files that were uploaded by the user.
      • For multiple image inputs, we create custom forward and back buttons that, when clicked, dispatch a custom nav-media event with a detail that is equal to either next or back.
      • When this custom event is dispatched, we use the client side object to load the appropriate new image into the Pintura editor and disable the forward / back buttons when we reach the start / end of the uploaded images.
    6. When looking at the uploaded image files - we first check that less than 30 images were uploaded (this is the max). We slice the first 30 files out if the length is greater than 30.
    7. We then get the signed urls for the images and lazy-load the pintura image editor.
    8. We post the images to Amazon s3, which runs a Lambda function on image upload that checks whether the image is inappropriate using the Google Image API. If it is inappropriate then the image is removed from the bucket. Should probably add functionality so that when the image fails to load on the client, it ios replaced by a default image.
    9. We get a pintura image editor and append it to the output element with the <details> elements for adding short and long descriptions to the element. The short input is normally used to be the alt attribute for the image, and the long description is used as the data-text attribute.
    10. To include a default image in the page, render the
  2. Audio Upload
    1. When the page sees any image, audio, or video components, the record-media.js JavaScript is lazy-loaded.
    2. The audio and video uploads basically go through the same process as the image upload except we use MultiPart uploads to stream the response to s3 in 5MB chunks.
  3. Video Upload
    1. When the page sees any image, audio, or video components, the record-media.js JavaScript is lazy-loaded.
    2. The audio and video uploads basically go through the same process as the image upload except we use MultiPart uploads to stream the response to s3 in 5MB chunks.

Image Upload

Audio Upload

I haven't decided to upload audio and video files yet to test the previously uploaded functionality for audio and video files. When you do, you should set the min-height style attribute on the output element to prevent CLS.

Video Upload

I haven't decided to upload audio and video files yet to test the previously uploaded functionality for audio and video files. When you do, you should set the min-height style attribute on the output element to prevent CLS.

Upload Media and Get The URL

Since we will allow users to write their own code for the website, we should allow them to upload audio, video, and image files and copy the url of those files. To allow this functionality, include the data-copy-url attribute on the <input /> element. See examples below.

Upload Image, Get Data

Upload an image using the <input type="file"> input below, submit the form, and get the HTML that should be used for the image.