IMPORTANT: yt-dlp keeps being updated to fight against Youtube anti-download tactics. Whenever it stops working we will need to download again
A simple Electron application to transcribe and translate video files using OpenAI's Whisper API.
- Load local video files.
- Download videos from YouTube URLs using yt-dlp (bundled with app).
- Download videos from Google Drive (public files).
- Persistent storage - downloaded videos are saved to
~/VideoTranscriber/Downloads/for reuse. - Download history - browse and reload previously downloaded videos.
- Extract audio using ffmpeg.
- Transcribe audio using OpenAI Whisper.
- Display transcript synchronized with video playback.
- Highlight words in the transcript as they are spoken.
- Prompts for OpenAI API key on first run and stores it securely.
- Node.js and npm (or yarn)
- An OpenAI API Key
Note: yt-dlp and ffmpeg are bundled with the application - no additional software installation required!
- Clone the repository (or download the source code).
- Navigate to the project directory in your terminal.
- Install dependencies:
npm install
The yt-dlp binaries will be automatically downloaded during installation.
The application provides three ways to load videos:
- Local Files: Click "Load Local Video" to select a file from your computer
- YouTube URLs: Select "Download from YouTube" and enter a YouTube URL
- Google Drive URLs: Select "Download from Google Drive" and enter a public Google Drive video URL
- Downloads Folder: Click the folder icon (📁) to open your downloads directory
- Browse Downloads: Access previously downloaded videos through "Browse Downloaded Videos"
- Download Location: Videos are saved to
~/VideoTranscriber/Downloads/- YouTube videos:
~/VideoTranscriber/Downloads/YouTube/ - Google Drive videos:
~/VideoTranscriber/Downloads/GoogleDrive/
- YouTube videos:
Replace the default Electron icon with your custom logo for a branded application experience.
-
Place Your Logo: Put your logo file as
elsa_logo.pngin the project root directory- For best results: square aspect ratio (1:1), at least 512x512 pixels
- Transparent background recommended
-
Run Icon Setup Script:
npm run setup-icons
This copies your PNG for Linux/window icons and shows conversion instructions.
- Visit Icon Kitchen
- Upload your
elsa_logo.png - Download the generated icons pack
- Extract and copy:
icon.icns→build/icons/icon.icns(macOS)icon.ico→build/icons/icon.ico(Windows)
- macOS (.icns): PNG to ICNS converter
- Windows (.ico): PNG to ICO converter
If you're on macOS, use built-in tools:
# Create iconset with multiple sizes
mkdir icon.iconset
sips -z 16 16 elsa_logo.png --out icon.iconset/icon_16x16.png
sips -z 32 32 elsa_logo.png --out icon.iconset/icon_16x16@2x.png
sips -z 32 32 elsa_logo.png --out icon.iconset/icon_32x32.png
sips -z 64 64 elsa_logo.png --out icon.iconset/icon_32x32@2x.png
sips -z 128 128 elsa_logo.png --out icon.iconset/icon_128x128.png
sips -z 256 256 elsa_logo.png --out icon.iconset/icon_128x128@2x.png
sips -z 256 256 elsa_logo.png --out icon.iconset/icon_256x256.png
sips -z 512 512 elsa_logo.png --out icon.iconset/icon_256x256@2x.png
sips -z 512 512 elsa_logo.png --out icon.iconset/icon_512x512.png
sips -z 1024 1024 elsa_logo.png --out icon.iconset/icon_512x512@2x.png
# Convert to .icns format
iconutil -c icns icon.iconset
mv icon.icns build/icons/
rm -rf icon.iconsetAfter setup, you should have:
build/icons/
├── icon.png # Auto-generated (Linux & window icons)
├── icon.icns # Manual (macOS builds)
└── icon.ico # Manual (Windows builds)
- Development:
npm start- see icons in window title bar and dock - Production:
npm run build- creates apps with custom icons
For detailed troubleshooting and additional options, see SETUP_ICONS.md.
first compile it
npm run build
then run this command
pkgbuild --root "dist/mac-arm64/" --component-plist "component.plist" --install-location "/Applications" --scripts "scripts" --version "1.0.0" --identifier "com.elsa.videotranscriber.pkg" dist/VideoTranscriberInstaller-1.0.0.pkg
To run the application locally for development:
npm startThe application will launch, and you may be prompted for your OpenAI API key if it's the first time or the key is invalid.
To build the application package (e.g., for macOS, Windows, Linux):
npm run buildThis command uses electron-builder to create distributable files in the dist/ directory based on the configuration in package.json.
- Icons: For custom branding, see the "Custom Application Icons" section above. Ensure all icon formats (
icon.png,icon.icns,icon.ico) are in thebuild/icons/directory before building. - Output: For macOS, this command (as currently configured) creates a
.zipfile and a directory containing the.appbundle (e.g.,dist/mac-arm64/).
To create a user-friendly .pkg installer for macOS that handles permissions correctly:
-
Ensure the app is built: Run
npm run buildfirst to generate the.appbundle (e.g., indist/mac-arm64/). -
Ensure the postinstall script exists: Make sure
scripts/postinstallexists and is executable (chmod +x scripts/postinstall). This script runsxattr -cron the installed application. -
Ensure the component plist exists: Make sure
component.plistexists in the project root, correctly referencing the app bundle details and your app's bundle identifier. -
Run pkgbuild: Execute the following command in the project root directory:
pkgbuild --root "dist/mac-arm64/" \ --component-plist "component.plist" \ --install-location "/Applications" \ --scripts "scripts" \ --version "1.0.0" \ --identifier "com.elsa.videotranscriber.pkg" \ --sign "Developer ID Installer: ELSA, Corp. (DQ47627WZ6)" \ dist/VideoTranscriberInstaller-1.0.0.pkg
-
Distribute: Share the generated
dist/VideoTranscriberInstaller-*.pkgfile.
If you encounter issues with electron-builder repeatedly failing to build with errors like "Application entry file main.js in app.asar does not exist," you can use a previously successful build:
- Locate a previous successful build: Find an existing
.appbundle from a previous build (e.g., in anOLD_dist/mac-arm64/directory). - Update component.plist: Make sure
component.plisthas the correct bundle identifier matching your app. - Make the postinstall script executable:
chmod +x scripts/postinstall
- Run pkgbuild with the existing build:
pkgbuild --root "OLD_dist/mac-arm64/" \ --component-plist "component.plist" \ --install-location "/Applications" \ --scripts "scripts" \ --version "1.0.0" \ --identifier "com.elsa.videotranscriber.pkg" \ dist/VideoTranscriberInstaller-1.0.0.pkg
This installer will copy the application to /Applications and run the post-install script to remove the quarantine attribute, allowing users to run the app after installation (they might still need to right-click -> Open the very first time).
Before signing, obtain an Apple Developer certificate:
- Enroll in the Apple Developer Program
- Create a Developer ID Application certificate in your Apple Developer account
- Download and install the certificate in your Keychain
Update the mac section in your package.json:
"mac": {
"target": [
"dir",
"zip",
"dmg"
],
"hardenedRuntime": true,
"gatekeeperAssess": true,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.plist",
"identity": "Developer ID Application: Your Company Name (TEAMID)"
}Replace "Your Company Name (TEAMID)" with your actual Apple Developer certificate name.
Run the build command:
npm run buildThis will build and sign your application using electron-builder.
For distribution outside the App Store:
# First, notarize the .app bundle
xcrun notarytool submit dist/mac-arm64/Video\ Transcriber.app --apple-id "your@email.com" --password "app-specific-password" --team-id "TEAMID" --wait
# Then create the PKG installer
pkgbuild --root "dist/mac-arm64/" \
--component-plist "component.plist" \
--install-location "/Applications" \
--scripts "scripts" \
--version "1.0.0" \
--identifier "com.elsa.videotranscriber.pkg" \
--sign "Developer ID Installer: ELSA, Corp. (DQ47627WZ6)" \
dist/VideoTranscriberInstaller-1.0.0.pkgTo enable automatic notarization during the build process:
- Create the notarize.js script: Create a file at
scripts/notarize.jswith the following content:
const { notarize } = require('@electron/notarize');
const { build } = require('../package.json');
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
// Only notarize on macOS
if (electronPlatformName !== 'darwin') {
return;
}
// Check if notarization is enabled
if (!process.env.APPLE_ID || !process.env.APPLE_ID_PASSWORD) {
console.log('Skipping notarization: environment variables not set');
return;
}
console.log('Notarizing application...');
const appName = context.packager.appInfo.productFilename;
const appBundleId = build.appId || 'com.elsa.videotranscriber';
return await notarize({
appBundleId,
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
});
};- Install required dependency:
npm install --save-dev @electron/notarize- Enable in package.json: Ensure the
afterSignhook is specified in your package.json build config:
"build": {
"afterSign": "scripts/notarize.js"
}- Set environment variables for notarization: When building, provide your Apple credentials:
APPLE_ID="your@email.com" APPLE_ID_PASSWORD="app-specific-password" APPLE_TEAM_ID="YOUR_TEAM_ID" npm run buildThe script is designed to skip notarization when environment variables aren't set, allowing you to run a normal build without notarization during development.
For more details on notarization, refer to Apple's documentation or the @electron/notarize package.
When trying to install in another machine, it will complain that the app is not secure.
Go to settings -> privacy & security scroll down to the bottom and allow the app to install anyway. Then your app will be in the applications folder