mdfpwm support
This commit is contained in:
parent
745b92660c
commit
55840b54e5
2 changed files with 89 additions and 12 deletions
34
index.ts
34
index.ts
|
|
@ -1,9 +1,10 @@
|
||||||
import { Hono } from 'hono'
|
import { Hono } from 'hono'
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
const joypixels = require("emoji-toolkit");
|
const joypixels = require("emoji-toolkit");
|
||||||
import { mkdirSync, writeFileSync, existsSync, rmSync, readFileSync, readFile } from 'fs'
|
import { mkdirSync, writeFileSync, existsSync, rmSync, readFileSync, readFile, writeFile } from 'fs'
|
||||||
import { $ } from 'bun';
|
import { $ } from 'bun';
|
||||||
import ytSearch from 'yt-search';
|
import ytSearch from 'yt-search';
|
||||||
|
import { writeMDFPWMv3 } from './mdfpwmWriter';
|
||||||
let ytdlpPath = "yt-dlp"
|
let ytdlpPath = "yt-dlp"
|
||||||
if(existsSync("./yt-dlp")) {
|
if(existsSync("./yt-dlp")) {
|
||||||
ytdlpPath = "./yt-dlp"
|
ytdlpPath = "./yt-dlp"
|
||||||
|
|
@ -22,8 +23,34 @@ app.post("/youtube", async (c) => {
|
||||||
|
|
||||||
let title = body.title;
|
let title = body.title;
|
||||||
let artist = body.artist;
|
let artist = body.artist;
|
||||||
|
let filename;
|
||||||
|
if(body.mdfpwm) {
|
||||||
|
filename = "cache/"+Bun.hash(title+"-"+artist)+".mdfpwm"
|
||||||
|
|
||||||
let filename = "cache/"+Bun.hash(title+"-"+artist)+".dfpwm"
|
if(!existsSync(filename)) {
|
||||||
|
const searchResult = await ytSearch(`${artist} ${title}`);
|
||||||
|
const video = searchResult.videos[0];
|
||||||
|
if (!video) throw new Error("No video found");
|
||||||
|
console.log(video)
|
||||||
|
|
||||||
|
await $`${ytdlpPath} --audio-format opus -x ${video.url} -o test`;
|
||||||
|
console.timeEnd("yt-dlp")
|
||||||
|
|
||||||
|
// this makes left.dfpwm & right.dfpwm
|
||||||
|
await $`ffmpeg -i test.opus -filter_complex "[0:a]channelsplit=channel_layout=stereo[left][right]; [left]highpass=f=60,lowpass=f=15000,dynaudnorm[leftf]; [right]highpass=f=60,lowpass=f=15000,dynaudnorm[rightf]" -map "[leftf]" -ar 48000 -f dfpwm left.dfpwm -map "[rightf]" -ar 48000 -f dfpwm right.dfpwm`
|
||||||
|
rmSync("test.opus")
|
||||||
|
|
||||||
|
writeFileSync(filename, writeMDFPWMv3(
|
||||||
|
readFileSync("left.dfpwm"),
|
||||||
|
readFileSync("right.dfpwm"),
|
||||||
|
{ title: title, artist: artist, album: title }
|
||||||
|
))
|
||||||
|
|
||||||
|
rmSync("right.dfpwm")
|
||||||
|
rmSync("left.dfpwm")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename = "cache/"+Bun.hash(title+"-"+artist)+".dfpwm"
|
||||||
|
|
||||||
if(!existsSync(filename)) {
|
if(!existsSync(filename)) {
|
||||||
const searchResult = await ytSearch(`${artist} ${title}`);
|
const searchResult = await ytSearch(`${artist} ${title}`);
|
||||||
|
|
@ -34,10 +61,11 @@ app.post("/youtube", async (c) => {
|
||||||
await $`ffmpeg -i test.opus -af "highpass=f=60, lowpass=f=15000, dynaudnorm" -ar 48000 -ac 1 -f dfpwm "${filename}"`;
|
await $`ffmpeg -i test.opus -af "highpass=f=60, lowpass=f=15000, dynaudnorm" -ar 48000 -ac 1 -f dfpwm "${filename}"`;
|
||||||
rmSync("test.opus")
|
rmSync("test.opus")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c.body(readFileSync(filename), {
|
return c.body(readFileSync(filename), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'audio/vnd.dfpwm',
|
'Content-Type': `audio/vnd.${body.mdfpwm ? "m" : ""}dfpwm`,
|
||||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
49
mdfpwmWriter.ts
Normal file
49
mdfpwmWriter.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
export interface MDFPWMMetadata {
|
||||||
|
title?: string;
|
||||||
|
artist?: string;
|
||||||
|
album?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toS1(str: string): Buffer {
|
||||||
|
const utf8 = Buffer.from(str, "utf-8");
|
||||||
|
const len = utf8.length;
|
||||||
|
return Buffer.concat([Buffer.from([len]), utf8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writeMDFPWMv3(
|
||||||
|
left: Buffer,
|
||||||
|
right: Buffer,
|
||||||
|
meta: MDFPWMMetadata = {}
|
||||||
|
): Buffer {
|
||||||
|
if (left.length !== right.length) {
|
||||||
|
throw new Error("Left and right DFPWM buffers must be the same length");
|
||||||
|
}
|
||||||
|
|
||||||
|
let length = left.byteLength*2;
|
||||||
|
const mdfpwm = []
|
||||||
|
mdfpwm.push(Buffer.from("MDFPWM\x03", "ascii"));
|
||||||
|
mdfpwm.push(Buffer.alloc(4));
|
||||||
|
mdfpwm.push(toS1(meta.artist || ""));
|
||||||
|
mdfpwm.push(toS1(meta.title || ""));
|
||||||
|
mdfpwm.push(toS1(meta.album || ""));
|
||||||
|
mdfpwm[1]!.writeUint32LE(length)
|
||||||
|
|
||||||
|
for(let i =0; i < length / 12000; i++) {
|
||||||
|
const lStart = i * 6000;
|
||||||
|
const rStart = i * 6000;
|
||||||
|
|
||||||
|
const lChunk = left.subarray(lStart, lStart + 6000);
|
||||||
|
mdfpwm.push(lChunk);
|
||||||
|
if (lChunk.length < 6000) {
|
||||||
|
mdfpwm.push(Buffer.alloc(6000 - lChunk.length, 0x55));
|
||||||
|
}
|
||||||
|
|
||||||
|
const rChunk = right.subarray(rStart, rStart + 6000);
|
||||||
|
mdfpwm.push(rChunk);
|
||||||
|
if (rChunk.length < 6000) {
|
||||||
|
mdfpwm.push(Buffer.alloc(6000 - rChunk.length, 0x55));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer.concat(mdfpwm)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue