Insert Audios in TypeScript Rich Text Editor

The Rich Text Editor allows you to insert audio from online sources and local computers and then insert them into your content. You can insert audio with the following options using the insertAudioSettings property.

Configuring the audio toolbar item

The audio feature is enabled by adding the Audio item to the toolbar using the toolbarSettings.items property.

To use the audio feature, inject the audio module using the RichTextEditor.Inject(Audio) method.

The following example demonstrates configuring the audio toolbar item:

import { RichTextEditor, HtmlEditor, Toolbar, QuickToolbar, Audio } from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(HtmlEditor, Toolbar, QuickToolbar, Audio);

let editor: RichTextEditor = new RichTextEditor({
    toolbarSettings: {
        items: ['Audio']
    },
    value: `<p>Rich Text Editor allows inserting video and audio from online sources and the local computers where you want to insert a video and audio into your content.</p>`,
});
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
</body>

</html>

Audio save formats

The audio files can be saved as Blob or Base64 URL by using the insertAudioSettings.saveFormat property, which is of enum type, and the generated URL will be set to the src attribute of the <source> tag.

By default, saveFormat is set to Blob.

<audio>
    <source src="blob:http://ej2.syncfusion.com/3ab56a6e-ec0d-490f-85a5-f0aeb0ad8879" type="audio/mp3" >
</audio>

<audio>
    <source src="data:audio/mp3;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHA" type="audio/mp3" >
</audio>

Inserting audio

You can insert audio from either a hosted link or a local machine by clicking the audio button in the editor’s toolbar. A dialog opens allowing you to insert audio from a web URL or upload from your device.

Inserting audio from web URLs

By default, the audio toolbar item opens a dialog for inserting audio from an online source. Entering a valid URL adds it to the src attribute of the <source> tag.

JavaScript Rich Text Editor Audio insert

Uploading audio from local machine

The audio dialog includes a browse option to select audio file from a local machine and insert it into the Rich Text Editor content.

If the insertAudioSettings.path is not specified, the audio is converted to a Blob or Base64 URL and inserted into the editor.

Maximum file size restriction

You can restrict audio uploads from your local machine using the insertAudioSettings.maxFileSize property. By default, the maximum file size is 30000000 bytes (approximately 30 MB).

In the following illustration, the audio size has been validated before uploading, and it is determined whether the audio has been uploaded or not.

import { RichTextEditor, Toolbar, Link, Audio, Count, HtmlEditor, QuickToolbar } from '@syncfusion/ej2-richtexteditor';
import { UploadingEventArgs } from '@syncfusion/ej2-inputs';
RichTextEditor.Inject(Toolbar, Link, Audio, Count, HtmlEditor, QuickToolbar);

let editor: RichTextEditor = new RichTextEditor({
    toolbarSettings: {
        items: ['Audio']
    },
    insertAudioSettings: {
        saveUrl: "https://aspnetmvc.syncfusion.com/services/api/uploadbox/Save",
        path: "../Files/",
        maxFileSize: 30000000
    }
});
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>

Saving audio to the server

Configuration properties

Property Description
saveFormat Sets the default save format when audio is inserted (Blob or Base64)
saveUrl URL endpoint that receives the audio file for server-side processing
removeUrl URL endpoint for deleting audio files from the server
path Destination path on server where audio files are stored

Server-side action

The selected audio can be uploaded to the required destination using the controller action below. Map this method name in insertAudioSettings.saveUrl and provide the required destination path through insertAudioSettings.path properties.

If you want to insert lower-sized audio files in the editor and don’t want a specific physical location for saving the audio, you can opt to save the format as Base64.

In the following code blocks, the audio module has been injected and can insert the audio files saved in the specified path.

import { RichTextEditor, Toolbar, HtmlEditor, Audio } from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(Toolbar, HtmlEditor, Audio);

let editor: RichTextEditor = new RichTextEditor({
   toolbarSettings: {
      items: ['Audio']
   },
   insertAudioSettings: {
      saveUrl: "[SERVICE_HOSTED_PATH]/api/uploadbox/SaveFiles",
      path: "[SERVICE_HOSTED_PATH]/Files/"
  }
});
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>
using System;
using System.IO;
using FileUpload.Models;
using System.Diagnostics;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;

namespace FileUpload.Controllers
{
    public class HomeController : Controller
    {
        private IHostingEnvironment hostingEnv;

        public HomeController(IHostingEnvironment env)
        {
            hostingEnv = env;
        }

        public IActionResult Index()
        {
            return View();
        }

        [AcceptVerbs("Post")]
        public void SaveFiles(IList<IFormFile> UploadFiles)
        {
            try
            {
                foreach (IFormFile file in UploadFiles)
                {
                    if (UploadFiles != null)
                    {
                        string filename = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
                        filename = hostingEnv.WebRootPath + "\\Files" + $@"\{filename}";

                        // Create a new directory, if it does not exists
                        if (!Directory.Exists(hostingEnv.WebRootPath + "\\Files"))
                        {
                            Directory.CreateDirectory(hostingEnv.WebRootPath + "\\Files");
                        }

                        if (!System.IO.File.Exists(filename))
                        {
                            using (FileStream fs = System.IO.File.Create(filename))
                            {
                                file.CopyTo(fs);
                                fs.Flush();
                            }
                            Response.StatusCode = 200;
                        }
                    }
                }
            }
            catch (Exception)
            {
                Response.StatusCode = 204;
            }
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

Renaming audio before inserting

You can use the insertAudioSettings property, to specify the server handler to upload the selected audio. Then by binding the fileUploadSuccess event, you can receive the modified file name from the server and update it in the Rich Text Editor’s insert audio dialog.

import { RichTextEditor, Toolbar, HtmlEditor, Audio } from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(Toolbar, HtmlEditor, Audio);

let editor: RichTextEditor = new RichTextEditor({
   toolbarSettings: {
      items: ['Audio']
  },
  value: ` <p>The Rich Text Editor is WYSIWYG ("what you see is what you get") editor useful to create and edit content, and return the valid <a href="https://ej2.syncfusion.com/home/" target="_blank">HTML markup</a> or <a href="https://ej2.syncfusion.com/home/" target="_blank">markdown</a> of the content</p>`,
  insertAudioSettings: {
      saveUrl: "[SERVICE_HOSTED_PATH]/api/uploadbox/Rename",
      path: "[SERVICE_HOSTED_PATH]/Files/"
  },
  fileUploadSuccess: onFileUploadSuccess
});
editor.appendTo('#editor');

function onFileUploadSuccess (args: any) {
   alert("Get the new file name here");
   if (args.e.currentTarget.getResponseHeader('name') != null) {
       args.file.name = args.e.currentTarget.getResponseHeader('name');
       let filename: any = document.querySelectorAll(".e-file-name")[0];
       filename.innerHTML = args.file.name.replace(document.querySelectorAll(".e-file-type")[0].innerHTML, '');
       filename.title = args.file.name;
   }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>

To configure server-side handler, refer to the below code.

int x = 0;
string file;
[AcceptVerbs("Post")]
public void Rename()
{
    try
    {
        var httpPostedFile = System.Web.HttpContext.Current.Request.Files["UploadFiles"];
        fileName = httpPostedFile.FileName;
        if (httpPostedFile != null)
        {
            var fileSave = System.Web.HttpContext.Current.Server.MapPath("~/Files");
            if (!Directory.Exists(fileSave))
            {
                Directory.CreateDirectory(fileSave);
            }
            var fileName = Path.GetFileName(httpPostedFile.FileName);
            var fileSavePath = Path.Combine(fileSave, fileName);
            while (System.IO.File.Exists(fileSavePath))
            {
                fileName = "rteFiles" + x + "-" + fileName;
                fileSavePath = Path.Combine(fileSave, fileName);
                x++;
            }
            if (!System.IO.File.Exists(fileSavePath))
            {
                httpPostedFile.SaveAs(fileSavePath);
                HttpResponse Response = System.Web.HttpContext.Current.Response;
                Response.Clear();
                Response.Headers.Add("name", fileName);
                Response.ContentType = "application/json; charset=utf-8";
                Response.StatusDescription = "File uploaded succesfully";
                Response.End();
            }
        }
    }
    catch (Exception e)
    {
        HttpResponse Response = System.Web.HttpContext.Current.Response;
        Response.Clear();
        Response.ContentType = "application/json; charset=utf-8";
        Response.StatusCode = 204;
        Response.Status = "204 No Content";
        Response.StatusDescription = e.Message;
        Response.End();
    }
}

Uploading audio with authentication

You can add additional data with the audio uploaded from the Rich Text Editor on the client side, which can even be received on the server side by using the fileUploading event and its customFormData argument, you can pass parameters to the controller action. On the server side, you can fetch the custom headers by accessing the form collection from the current request, which retrieves the values sent using the POST method.

By default, it doesn’t support the UseDefaultCredentials property; we need to manually append the default credentials with the upload request.

import { RichTextEditor, Toolbar, Link, Audio, Count, HtmlEditor, QuickToolbar } from '@syncfusion/ej2-richtexteditor';
import { UploadingEventArgs } from '@syncfusion/ej2-inputs';
RichTextEditor.Inject(Toolbar, Link, Audio, Count, HtmlEditor, QuickToolbar);

let editor: RichTextEditor = new RichTextEditor({
    toolbarSettings: {
        items: ['Audio']
    },
    insertAudioSettings: {
        saveUrl: "[SERVICE_HOSTED_PATH]/api/uploadbox/SaveFiles",
        path: "[SERVICE_HOSTED_PATH]/Files/"
    },
    fileUploading: onFileUpload
});
editor.appendTo('#editor');

function onFileUpload (args: UploadingEventArgs): void {
    var accessToken = "Authorization_token";
    // adding custom Form Data
    args.customFormData = [{ 'Authorization': accessToken }];
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>
public void SaveFiles(IList<IFormFile> UploadFiles)
{
    string currentPath = Request.Form["Authorization"].ToString();
}

Audio replacement functionality

Once an audio file has been inserted, you can change it using the Rich Text Editor quickToolbarSettings audioReplace option. You can replace the audio file using the web URL or the browse option in the audio dialog.

JavaScript Rich Text Editor Audio replace

Deleting audios

To remove audio from the Rich Text Editor content, select the audio and click the audioRemove button from the quick toolbar. It will delete the audio from the Rich Text Editor content as well as from the service location if the insertAudioSettings.removeUrl is given.

Once you select the audio from the local machine, the URL for the audio will be generated. You can remove the audio from the service location by clicking the cross icon.

JavaScript Rich Text Editor Audio delete

Configuring audio display position

Sets the default display property for audio when it is inserted in the Rich Text Editor using the insertAudioSettings.layoutOption property. It has two possible options: Inline and Break. When updating the display positions, it updates the audio elements’ layout position.

The default layoutOption property is set to Inline.

import { RichTextEditor, Toolbar, HtmlEditor, Audio } from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(Toolbar, HtmlEditor, Audio );

let editor: RichTextEditor = new RichTextEditor({
   insertAudioSettings: {
      layoutOption: 'Inline'
  }
});
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>

Drag and drop audio insertion

By default, the Rich Text Editor allows you to insert audios by drag-and-drop from the local file system such as Windows Explorer into the content editor area. And, you can upload the audios to the server before inserting into the editor by configuring the saveUrl property.

In the following sample, you can see feature demo.

import { RichTextEditor, Toolbar, Audio,  Link, HtmlEditor, QuickToolbar } from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(Toolbar, Audio,  Link, HtmlEditor, QuickToolbar );

let editor: RichTextEditor = new RichTextEditor({
    value: `<p>The Syncfusion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here.</p><p><b>Key features:</b></p><ul><li><p>Provides &lt;IFRAME&gt; and &lt;DIV&gt; modes.</p></li><li><p>Bulleted and numbered lists.</p></li><li><p>Handles images, hyperlinks, videos, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager. </p></li></ul><div style='display: inline-block; width: 60%; vertical-align: top; cursor: auto;'><img alt='Sky with sun' src='https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Overview.png' width='309' style='min-width: 10px; min-height: 10px; width: 309px; height: 174px;' class='e-rte-image e-imginline e-rte-drag-image' height='174' /></div>`,
    insertAudioSettings :{
        saveUrl: 'https://services.syncfusion.com/js/production/api/RichTextEditor/SaveFile',
    }
});
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
   <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    
</body>

</html>

Disabling audio drag and drop

You can prevent drag-and-drop action by setting the actionBegin argument cancel value to true. The following code shows how to prevent the drag-and-drop.

    actionBegin: function (args: any): void {
        if(args.type === 'drop' || args.type === 'dragstart') {
            args.cancel =true;
        }
    }

Customizing the Audio Quick Toolbar

The Rich Text Editor enables customization of the audio quick toolbar, allowing you to tailor its functionality with Essential tools such as AudioReplace, Remove, and AudioLayoutOption.

By configuring these options in the quickToolbarSettings property, you enhance the editor’s capabilities, facilitating seamless management and editing of audio directly within your content. This customization ensures a user-friendly experience for manipulating audio elements efficiently.

import { RichTextEditor, Toolbar, Link, Audio, Image, HtmlEditor, QuickToolbar} from '@syncfusion/ej2-richtexteditor';
RichTextEditor.Inject(Toolbar, Link, Image, Audio, HtmlEditor, QuickToolbar);
 
let editor: RichTextEditor = new RichTextEditor({
  toolbarSettings: {
    items: ['Audio']
  },
  quickToolbarSettings: {
    showOnRightClick: true,
    audio: ['AudioReplace', 'Remove', 'AudioLayoutOption']
  },
  value: `<p><b>Get started with Quick Toolbar to click on an audio</b></p>
                    <p>Using the quick toolbar, users can replace, display, and delete the selected audio.</p>
                    <p><audio controls><source src="https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Audio.wav" type="audio/mp3" /></audio></p>`
});
 
editor.appendTo('#editor');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/35.1.37/tailwind3.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
</body>

</html>

See Also