Voice2HTML Emacs package generates voice mail and publishes it on remote WWW server. This package serves the purpose to provide voice mail that may be quickly published on remote WWW servers. Requirement for user is to have own web hosting and SSH access to it. Why it is useful? You may send voice mail or voice messages to people over SMS, they can just click on the link in the SMS by using their smart phone and listen to the message directly. You could even send voice mail URL by letter to people who will later browse it online. Insert the URL for voice mail into email or other chat applications which otherwise do not allow transfers of voice.

Tip
Check out the sample voice mail: https://gnu.support/files/voice/2022-07-14-05-06-18a5cbb.ogg.html

To install this package, simply save the below embedded code, then install it with:

{M-x package-install-file RET voice2html.el RET}

The embedded code follows:

;;; voice2html.el --- Voice2HTML generates voice mail and publishes it on remote WWW server.

;; Copyright (C) 2022 by Jean Louis

;; Author: Jean Louis <bugs@gnu.support>
;; Version: 0.1
;; Package-Requires: ()
;; Keywords: convenience hypermedia multimedia
;; URL: https://gnu.support/gnu-emacs/packages/GNU-Emacs-Package-voice2html-el-70627.html

;; This file is not part of GNU Emacs.

;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This package serves the purpose to provide voice mail that may be
;; quickly published on remote WWW servers.  Requirement for user is
;; to have own web hosting and SSH access to it.  Local computer shall
;; have the command `rec' from SOX sound tools.  Why it is useful? You
;; may send voice mail or voice messages to people over SMS, they can
;; just click on the link in the SMS by using their smart phone and
;; listen to the message directly.  You could even send voice mail URL
;; by letter to people who will later browse it online.  Insert the
;; URL for voice mail into email or other chat applications which
;; otherwise do not allow transfers of voice.

;; First customize all variables by doing {M-x customize-group RET voice2html RET}
;;
;; then
;;
;; to record and publish your voice mail to remote WWW server, do:
;;
;; M-x voice2html-voice-record
;;
;; then press `q' to stop recording and start transfer to remote server
;;
;; use the C-u M-x voice2html-voice-record to prepare the HTML file
;; with custom description.
;;
;; in Dired on the voice or HTML file, do following to verify that
;; file has been published:
;;
;; M-x voice2html-browse-url

;;; Change Log:

;;; Code:

;;;; Customizable Options

(defgroup voice2html nil
  "Voice2HTML customizations category."
  :group 'applications)

(defcustom voice2html-voice-recording-function 'voice2html-voice-record
  "Function that is used to record voice.

By default it is `voice2html-voice-record'.  Function must return
concatenated full path of the voice file that uses variable
`voice2html-local-upload-directory'."
  :group 'voice2html
  :type 'symbol)

(defcustom voice2html-remote-ssh-username ""
  "Remote username."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-remote-ssh-server ""
  "Remote server."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-remote-ssh-directory ""
  "Remote directory."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-local-upload-directory ""
  "Local upload directory where voice files are stored."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-remote-www-url ""
  "Remote URL on which voice mail will be attached."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-sound-recording-extension ".ogg"
  "The default sound recording extension."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-title "Voice Mail For You"
  "Default HTML title for voice mail message."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-description "Press the play button to listen to voice mail: "
  "Default description for voice mail."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-footer "Thanks for listening."
  "Default HTML footer for voice mail."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-phone ""
  "Your phone number."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-email ""
  "Your email address."
  :group 'voice2html
  :type 'string)

(defcustom voice2html-html-website ""
  "Your website address."
  :group 'voice2html
  :type 'string)

;;;; Variables

(defvar voice2html-buffer-name "*Voice2HTML*"
  "Buffer name for Voice2HTML application.")

;;;; Verification of settings

(defun voice2html-verification ()
  "Verify that settings are available."
  (if (and voice2html-voice-recording-function
	       voice2html-remote-ssh-username
	       voice2html-remote-ssh-server
	       voice2html-remote-ssh-directory
	       voice2html-remote-www-url
	       (file-directory-p voice2html-local-upload-directory))
      t
    (error "You must define all necessary variables")))

;;;; File and URL construction

(defun voice2html-file-name ()
  "Return voice file name.

It is generate in such way as to disable web harvesting for
previous voices."
  (let* ((time (format-time-string "%Y-%m-%d-%H-%M-%S"))
	 (current-time (format-time-string "%c"))
	 (file-name (concat time (substring (md5 current-time) 0 5) voice2html-sound-recording-extension)))
    file-name))

(defun voice2html-url (file)
  "Return remote WWW url for FILE."
  (concat (file-name-as-directory voice2html-remote-www-url) file))

;;;; HTML Generation

(defun voice2html-mother-fucking-template (title voice-url &optional description)
  "Return HTML populated by TITLE, VOICE-URL and optional DESCRIPTION."
  (let* ((description (or description voice2html-html-description))
	 (html (format "<!DOCTYPE html>
<html>
  <head>
    <meta charset=\"utf-8\">
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
    <title>%s</title>
    <style type=\"text/css\">
      body{ margin:40px auto;
      max-width:650px;
      line-height:1.6;
      font-size:18px;
      color:#444;
      padding:0 10px;
      }
      h1,h2,h3{line-height:1.2}
    </style>
  </head>
  <body>
    <h1 style=\"text-align: center\">%s</h1>
    <p style=\"text-align: center\">%s</p>
    <div style=\"text-align: center\">
    <audio controls autoplay>
      <source src=\"%s\" type=\"audio/ogg\">
      Your browser does not support the OGG audio element.
    </audio>
    </div>
    <footer>
      <p style=\"text-align: center\">%s</p>
      <p style=\"text-align: center\">%s</p>
    </footer>
  </body>
</html>" title title description voice-url voice2html-html-footer (voice2html-generate-footer))))
    html))

(defun voice2html-html-file-name (file)
  "Return HTML file name for voice FILE."
  (concat (file-name-as-directory voice2html-local-upload-directory) file ".html"))

(defun voice2html-generate-html (file &optional description)
  "Generate Voice2HTML HTML file for FILE."
  (let* ((html-file (voice2html-html-file-name file))
	 (voice-url (voice2html-url (file-name-nondirectory file)))
	 (html (voice2html-mother-fucking-template voice2html-html-title voice-url description)))
    (with-temp-file html-file
      (insert html))
    html-file))

(defun voice2html-generate-footer ()
  "Generate fancy footer with email address, phone and website."
  (let ((email (if (string-match "@" voice2html-html-email)
		   (format "📧 <a href=\"mailto:%s\">%s</a></br>" voice2html-html-email voice2html-html-email)
		 ""))
	(phone (if (string-match "[[:digit:]]" voice2html-html-phone)
		   (format "📱 <a href=\"tel:%s\">%s</a></br>" voice2html-html-phone voice2html-html-phone)
		 ""))
	(website (if (string-match "http" voice2html-html-website)
		   (format "🌐 <a href=\"%s\">%s</a></br>" voice2html-html-website voice2html-html-website)
		   "")))
    (concat email phone website)))

;;;; View URL in browser

(defun voice2html-browse-url ()
  "Browse URL on Voice2HTML file in Dired."
  (interactive)
  (let ((file (dired-get-filename t)))
    (when file
      (let ((url (concat (file-name-as-directory voice2html-remote-www-url) file)))
	(browse-url url)))))

;;;; Voice Recording

(defun voice2html-voice-record (&optional prefix insert)
  "Record voice message."
  (interactive "P")
  (voice2html-verification)
  (let* ((description (when prefix (read-string "Description: ")))
	 (voice-file (voice2html-file-name))
	 (voice-file-path (concat (file-name-as-directory voice2html-local-upload-directory) voice-file))
	 (voice-url (concat (file-name-as-directory voice2html-remote-www-url) (file-name-nondirectory (voice2html-html-file-name voice-file))))
	 (voice-message (concat voice2html-html-title ": " voice-url)))
    (when insert
      (insert voice2html-html-title ":\n" voice-url))
    (switch-to-buffer voice2html-buffer-name)
    (erase-buffer)
    (setq-local header-line-format "➜ Finish Voice2HTML recording with 'q'")
    (let ((process (start-process "Voice2HTML" voice2html-buffer-name "rec" "-r" "48000" voice-file-path)))
      (kill-new voice-message)
      (message "Killed: %s" voice-message)
      (local-set-key "q" (lambda () (interactive) (signal-process process 'TERM)
			   (local-set-key "q" 'kill-current-buffer)
			   (voice2html-generate-html voice-file description)
			   (voice2html-transfer-voice voice-file-path)
			   (unless insert
			     (progn (dired-jump nil voice-file-path)
				    (revert-buffer)))))
      (prog2
	  (recursive-edit)
	  voice-url))))

(defun voice2html-voice-record-and-insert-url (&optional prefix)
  "Insert recorded voice mail into buffer.

With PREFIX insert optional description."
  (interactive "P")
  (voice2html-voice-record prefix t))

;;;; Transfer voice mail to remote server

(defun voice2html-transfer-voice (voice-file)
  "Transfer full HTML and VOICE-FILE to remote server."
  (let ((html-file (voice2html-html-file-name (file-name-nondirectory voice-file)))
	(remote-ssh-path (concat voice2html-remote-ssh-username "@" voice2html-remote-ssh-server ":" (file-name-as-directory voice2html-remote-ssh-directory))))
    (message "Transferring `%s' to `%s'" html-file remote-ssh-path)
    (call-process "scp" nil nil nil html-file remote-ssh-path)
    (message "Transferring `%s' to `%s'" voice-file remote-ssh-path)
    (call-process "scp" nil nil nil voice-file remote-ssh-path)))

;;; voice2html.el ends here

or you may download the file from: https://gnu.support/files/emacs/packages/voice2html.el

and then install it with the Emacs command:

{M-x package-install-file RET voice2html.el RET}