-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
171 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Platform } from "obsidian"; | ||
|
||
const version = "7.0"; | ||
const pkg = "@aidenlx/ffmpeg-static@0.1.0"; | ||
|
||
export const getBinaryName = () => { | ||
if (!Platform.isDesktopApp) return null; | ||
return ( | ||
`ffmpeg-${version}-${process.platform}-${process.arch}` + | ||
(process.platform === "win32" ? ".exe" : "") | ||
); | ||
}; | ||
|
||
const toBinaryURL = (binaryName: string) => | ||
`https://www.unpkg.com/${pkg}/bin/${binaryName}.gz`; | ||
|
||
export async function isPlatformSupported(): Promise<boolean> { | ||
const binaryName = getBinaryName(); | ||
if (!binaryName) return false; | ||
const url = toBinaryURL(binaryName); | ||
const resp = await fetch(url, { method: "HEAD" }); | ||
if (resp.status === 404) return false; | ||
if (!resp.ok) throw new Error(`Failed to fetch ${url}: ${resp.statusText}`); | ||
return true; | ||
} | ||
|
||
export async function downloadBinary(): Promise<ArrayBuffer> { | ||
const binaryName = getBinaryName(); | ||
if (!binaryName) throw new Error("Not desktop app"); | ||
|
||
const url = toBinaryURL(binaryName); | ||
const resp = await fetch(url); | ||
if (!resp.ok) throw new Error(`Failed to fetch ${url}: ${resp.statusText}`); | ||
const stream = resp.body?.pipeThrough(new DecompressionStream("gzip")); | ||
if (!stream) throw new Error("No stream"); | ||
return await new Response(stream).arrayBuffer(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { getSpawn } from "@/lib/require"; | ||
|
||
// Dedicated function to convert Node.js Buffer to ArrayBuffer | ||
function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer { | ||
return buffer.buffer.slice( | ||
buffer.byteOffset, | ||
buffer.byteOffset + buffer.byteLength, | ||
); | ||
} | ||
|
||
export class FFmpegError extends Error { | ||
constructor(message: string, public stderr: string[]) { | ||
super(message); | ||
} | ||
} | ||
|
||
export function ffmpeg(opts: { | ||
args: string[]; | ||
binary: string; | ||
pipe: true; | ||
}): Promise<ArrayBuffer>; | ||
export function ffmpeg(opts: { | ||
args: string[]; | ||
binary: string; | ||
pipe?: false; | ||
}): Promise<void>; | ||
export function ffmpeg({ | ||
args, | ||
binary: ffmpeg, | ||
pipe = false, | ||
}: { | ||
args: string[]; | ||
binary: string; | ||
pipe?: boolean; | ||
}): Promise<ArrayBuffer | void> { | ||
const spawn = getSpawn(); | ||
if (!spawn) throw new Error("Not desktop app"); | ||
return new Promise<ArrayBuffer | void>((resolve, reject) => { | ||
console.debug(`Running FFmpeg with args: ${args.join(" ")}`); | ||
if (!pipe) console.debug("stdout to /dev/null"); | ||
const stdout: Buffer[] = []; | ||
function handleStdErr(process: { stderr: NodeJS.ReadableStream }) { | ||
const stderr: string[] = []; | ||
process.stderr.on("data", (data) => { | ||
const message = data.toString("utf-8"); | ||
console.debug(`> FFMPEG: ${message}`); | ||
stderr.push(message); | ||
}); | ||
return stderr; | ||
} | ||
if (pipe) { | ||
const process = spawn(ffmpeg, args, { | ||
// Ignore stdin, pipe stdout and stderr | ||
stdio: ["ignore", "pipe", "pipe"], | ||
}); | ||
const stderr = handleStdErr(process); | ||
process.stdout.on("data", (data) => stdout.push(data)); | ||
process.on("error", (err) => | ||
reject( | ||
new FFmpegError(`FFmpeg error (${err.name}): ${err.message}`, stderr), | ||
), | ||
); | ||
process.on("close", (code) => { | ||
if (code === 0) { | ||
const output = Buffer.concat(stdout); | ||
resolve(bufferToArrayBuffer(output)); | ||
} else { | ||
reject(new FFmpegError(`FFmpeg error (code: ${code})`, stderr)); | ||
} | ||
}); | ||
} else { | ||
const process = spawn(ffmpeg, args, { | ||
stdio: ["ignore", "ignore", "pipe"], | ||
}); | ||
process.stderr.on("data", (data: Buffer) => | ||
console.debug(data.toString("utf-8")), | ||
); | ||
process.on("error", (err) => reject(new Error(`FFmpeg error: ${err}`))); | ||
process.on("close", (code) => { | ||
if (code === 0) { | ||
resolve(); | ||
} else { | ||
reject( | ||
new Error( | ||
`FFmpeg exited with code ${code}, see debug logs for output`, | ||
), | ||
); | ||
} | ||
}); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { ffmpeg } from "./ffmpeg"; | ||
|
||
// Function to convert MP4 to MP3 using FFmpeg | ||
export async function prepareWhisper( | ||
path: string, | ||
{ binary }: { binary: string }, | ||
): Promise<Blob> { | ||
const mp3Data = await ffmpeg({ | ||
args: [ | ||
/* eslint-disable prettier/prettier */ | ||
"-i", path, | ||
"-vn", | ||
"-map_metadata", "-1", | ||
// opus, bitrate: 16 kbps, audio rate: 12 kHz, mono audio | ||
"-c:a", "libopus", | ||
"-f", "opus", | ||
"-b:a", "16k", | ||
"-ar", "12000", | ||
"-ac", "1", | ||
"-af", "speechnorm", | ||
"pipe:1", | ||
/* eslint-enable prettier/prettier */ | ||
], | ||
binary, | ||
pipe: true, | ||
}); | ||
return new Blob([mp3Data], { type: "audio/opus" }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters