{"id":5079,"date":"2023-05-09T00:17:36","date_gmt":"2023-05-09T05:17:36","guid":{"rendered":"https:\/\/www.incredigeek.com\/home\/?p=5079"},"modified":"2023-05-20T18:15:27","modified_gmt":"2023-05-20T23:15:27","slug":"an-https-version-of-simple-whisper-web-interface","status":"publish","type":"post","link":"https:\/\/www.incredigeek.com\/home\/an-https-version-of-simple-whisper-web-interface\/","title":{"rendered":"An HTTPS version of Simple Whisper Web Interface"},"content":{"rendered":"\n<p>This version is the same as we <a href=\"https:\/\/www.incredigeek.com\/home\/a-very-basic-simple-whisper-web-interface\/\" data-type=\"post\" data-id=\"5064\">previously posted<\/a>, but adds a security certificate, and lots of extra new stuff!  You will need a valid certificate, this is fairly easy to setup using Let&#8217;s Encrypt, or you could do a self signed certificate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up Prerequisite<\/h2>\n\n\n\n<p><strong>Installing whisper-ctranslate2<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install -U whisper-ctranslate2<\/pre>\n\n\n\n<p><strong>Install NodeJS<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt install nodejs<\/pre>\n\n\n\n<p>or<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo dnf install nodejs<\/pre>\n\n\n\n<p><strong>Install Node Dependencies<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">npm install formidable\nnpm install https\nnpm install fs<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up Simple Whisper Web Interface<\/h2>\n\n\n\n<p>First we need a web directory to use.<\/p>\n\n\n\n<p>Next lets make an uploads folder<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir uploads<\/pre>\n\n\n\n<p>Code for main.js.  Change WEBSITE.COM to your website name.  Node will need access to the certificates.  You can run this web app as root (If you do that, then root needs node, and prerequisites), or copy the certs to the users directory, and change the path.  If you do the later, look at using a script\/cronjob to copy the updated certificates to the users directory.<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code lang=\"javascript\" class=\"language-javascript line-numbers\">const http = require('http')\nconst https = require('https')\nconst formidable = require('formidable')\nconst fs = require('fs')\n\nconst execSync = require('child_process').execSync\n\nlet newpath = ''\nlet modelSize = 'medium.en'\nconst { exec } = require('node:child_process')\nconst validModels = [\n  'medium.en',\n  'tiny',\n  'tiny.en',\n  'base',\n  'base.en',\n  'small',\n  'small.en',\n  'medium',\n  'medium.en',\n  'large-v1',\n  'large-v2'\n]\n\nvar options = {\n  key: fs.readFileSync('\/path\/to\/privkey.pem'),\n  cert: fs.readFileSync('\/path\/to\/fullchain.pem')\n}\nfs.readFile('.\/index.html', function (err, html) {\n  if (err) throw err\n\n  https\n    .createServer(options, function (req, res) {\n      if (req.url == '\/fileupload') {\n        res.write(html)\n        res.write(`&lt;div class=\"loading results\">&lt;\/div>`)\n        var form = new formidable.IncomingForm()\n        form.parse(req, function (err, fields, files) {\n          console.log('Fields ' + fields.modeltouse)\n          console.log('File ' + files.filetoupload)\n          var oldpath = files.filetoupload.filepath\n          newpath = '.\/uploads\/' + files.filetoupload.originalFilename\n          modelSize = validModels.includes(fields.modeltouse)\n            ? fields.modeltouse\n            : 'medium.en'\n          console.log('modelSize::' + modelSize)\n          fs.rename(oldpath, newpath, function (err) {\n            if (err) {\n              console.log('No file selected!') \/\/ throw err\n              res.write(`&lt;div class=\"results\">No file selected&lt;\/div>`)\n            } else {\n              console.log(newpath)\n              if (fields.timestamps) {\n                      console.log(\"true check\")\n                var output = execSync(\n                  `.\/whisper.sh \"${newpath}\" ${modelSize} \"true\"`,\n                  { encoding: 'utf-8' }\n                )\n              } else {\n                var output = execSync(\n                  `.\/whisper.sh \"${newpath}\" ${modelSize} false`,\n                  { encoding: 'utf-8' }\n                )\n              }\n        res.write(`&lt;script>document.querySelector('.loading').classList.add('hidden')&lt;\/script>`)\n              res.write(\n                `&lt;div class=\"results\">&lt;h2>Results:&lt;\/h2> &lt;p>${output}&lt;\/p>&lt;\/div>`\n              )\n              res.end()\n            }\n          })\n        })\n      } else {\n        res.writeHead(200, { 'Content-Type': 'text\/html' })\n        res.write(html)\n        return res.end()\n      }\n    })\n    .listen(8443)\n})<\/code><\/pre>\n\n\n\n<p>Add the following to index.html<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code lang=\"markup\" class=\"language-markup line-numbers\">&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n  &lt;head>\n    &lt;meta charset=\"UTF-8\" \/>\n    &lt;meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" \/>\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\n    &lt;title>Voice Transcribing Using Whisper&lt;\/title>\n    &lt;link type=\"text\/css\" rel=\"stylesheet\" href=\"style.css\" \/>\n  &lt;\/head>\n  &lt;style>\n    body {\n      background-color: #b9dbe7;\n      align-items: center;\n    }\n\n    .box {\n      border-radius: 25px;\n      padding: 25px;\n      width: 80%;\n      background-color: azure;\n      margin: auto;\n      border-bottom: 25px;\n      margin-bottom: 25px;\n                    font-family: 'advent_prothin', Arial, sans-serif;\n    }\n\n    .button {\n      border-radius: 25px;\n      margin: auto;\n      width: 50%;\n      height: 50px;\n      display: flex;\n      justify-content: center;\n      border-style: solid;\n\n      background-color: #e8d2ba;\n    }\n\n    h1 {\n      text-align: center;\n      padding: 0%;\n      margin: 0%;\n    }\n    @font-face {\n    font-family: 'advent_prothin';\n    src: url('Typewriter.otf');\n    font-weight: normal;\n    font-style: normal;\n\n}\n\n\np {\n      font-size: larger;\n      font-family: 'MyWebFont', Arial, sans-serif;\n    }\n    .headings {\n      font-size: large;\n      font-weight: bold;\n    }\n    input {\n      font-size: medium;\n    }\n    .checkboxes {\n      transform: scale(1.5);\n    }\n    select {\n      font-size: medium;\n    }\n    .results {\n      white-space: pre-wrap;\n      border-radius: 25px;\n      padding: 25px;\n      width: 80%;\n      align-self: center;\n      background-color: azure;\n      margin: auto;\n      font-family: Typewriter;\n    }\n    .hidden {\n              display: none;\n    }\n    .note {\n      font-style: italic;\n      font-size: small;\n      font-weight: normal;\n    }\n        .loading {\n      border: 16px solid azure;\n      border-radius: 50%;\n      border-top: 16px solid rgb(207, 255, 255);\n      width: 64px;\n      height: 64px;\n      animation: spin 1s linear infinite;\n    }\n    \/* Safari *\/\n\n    @keyframes spin {\n      0% {\n        transform: rotate(0deg);\n      }\n      100% {\n        transform: rotate(360deg);\n      }\n    }\n  &lt;\/style>\n  &lt;body>\n    &lt;script>\n    &lt;\/script>\n    &lt;div class=\"box\">\n      &lt;h1>Simple Whisper Web Interface&lt;\/h1>\n      &lt;br \/>\n      &lt;p>\n        Welcome to the very Simple Whisper Web Interface!&lt;br \/>&lt;br \/>\n        This is a very basic, easy to use, web interface for OpenAI's Whisper\n        tool. It has not been extensively tested, so you may encounter bugs or\n        other problems.\n        &lt;br \/>&lt;br \/>\n        Instructions for use. &lt;br \/>1. Select audio file &lt;br \/>2. Select the\n        Model you want to use &lt;br \/>\n        3. Click Transcribe! &lt;br \/>4. Copy your transcription\n      &lt;\/p>\n      &lt;br \/>\n      &lt;br \/>\n      &lt;div class=\"headings\">\n        &lt;form action=\"fileupload\" method=\"post\" enctype=\"multipart\/form-data\">\n          Audio File: &lt;input type=\"file\" name=\"filetoupload\" \/>&lt;br \/>\n\n          &lt;br \/>\n          Model:\n          &lt;select name=\"modeltouse\" id=\"modeltouse\">\n            &lt;option value=\"medium.en\">medium.en&lt;\/option>\n            &lt;option value=\"tiny\">tiny&lt;\/option>\n            &lt;option value=\"tiny.en\">tiny.en&lt;\/option>\n            &lt;option value=\"base\">base&lt;\/option>\n            &lt;option value=\"base.en\">base.en&lt;\/option>\n            &lt;option value=\"small\">small&lt;\/option>\n            &lt;option value=\"small.en\">small.en&lt;\/option>\n            &lt;option value=\"medium\">medium&lt;\/option>\n            &lt;option value=\"medium.en\">medium.en&lt;\/option>\n            &lt;option value=\"large-v1\">large-v1&lt;\/option>\n            &lt;option value=\"large-v2\">large-v2&lt;\/option>\n          &lt;\/select>\n          &lt;p class=\"note\">\n            Large-v2 and medium.en seem to produce the most accurate results.\n          &lt;\/p>\n          Timestamps?\n          &lt;input class=\"checkboxes\" type=\"checkbox\" id=\"timestamps\" name=\"timestamps\" \/>\n          &lt;br \/>\n          &lt;br \/>\n          &lt;br \/>\n          &lt;input class=\"button\" type=\"submit\" value=\"Transcribe!\" \/>\n        &lt;\/form>\n      &lt;\/div>\n    &lt;\/div>\n  &lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p>Run the server with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node main.js<\/pre>\n\n\n\n<p>If we want to start it in the background, run<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node .\/main.js &amp;<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Next steps are to setup a SystemD file so we can auto start on system boot and also make the installation quicker\/easier.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This version is the same as we previously posted, but adds a security certificate, and lots of extra new stuff! You will need a valid certificate, this is fairly easy to setup using Let&#8217;s Encrypt, or you could do a &hellip; <a href=\"https:\/\/www.incredigeek.com\/home\/an-https-version-of-simple-whisper-web-interface\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5079","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/5079","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/comments?post=5079"}],"version-history":[{"count":6,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/5079\/revisions"}],"predecessor-version":[{"id":5160,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/5079\/revisions\/5160"}],"wp:attachment":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/media?parent=5079"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/categories?post=5079"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/tags?post=5079"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}