Restart repository history from target event
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { exec } from 'child_process';
|
||||
import util from 'util';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { CheckMQAResponse } from '@/types';
|
||||
|
||||
const execPromise = util.promisify(exec);
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { albumPath } = await request.json();
|
||||
|
||||
if (!albumPath || !(await fs.pathExists(albumPath))) {
|
||||
return NextResponse.json({ error: 'Invalid album path' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Find all FLAC files
|
||||
const files = await fs.readdir(albumPath);
|
||||
const flacFiles = files.filter(f => f.toLowerCase().endsWith('.flac'));
|
||||
|
||||
if (flacFiles.length === 0) {
|
||||
return NextResponse.json({ error: 'No FLAC files found' }, { status: 400 });
|
||||
}
|
||||
|
||||
let mqaDetected = false;
|
||||
let outputLog = "";
|
||||
|
||||
// Check all files
|
||||
for (const file of flacFiles) {
|
||||
const filePath = path.join(albumPath, file);
|
||||
const command = `salmon check mqa "${filePath}"`;
|
||||
|
||||
try {
|
||||
const { stdout } = await execPromise(command);
|
||||
const isMQA = !stdout.includes('Did not find MQA syncword');
|
||||
|
||||
outputLog += `[${file}]: ${isMQA ? "MQA DETECTED" : "Clean"}\n`;
|
||||
|
||||
if (isMQA) {
|
||||
mqaDetected = true;
|
||||
}
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
outputLog += `[${file}]: Error - ${errorMessage}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
const response: CheckMQAResponse = {
|
||||
success: true,
|
||||
isMQA: mqaDetected,
|
||||
output: outputLog
|
||||
};
|
||||
|
||||
return NextResponse.json(response);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error checking MQA:', error);
|
||||
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { exec } from 'child_process';
|
||||
import util from 'util';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import * as mm from 'music-metadata';
|
||||
import { CheckUpconvResponse } from '@/types';
|
||||
|
||||
const execPromise = util.promisify(exec);
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { albumPath } = await request.json();
|
||||
|
||||
if (!albumPath || !(await fs.pathExists(albumPath))) {
|
||||
return NextResponse.json({ error: 'Invalid album path' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Find all FLAC files
|
||||
const files = await fs.readdir(albumPath);
|
||||
const flacFiles = files.filter(f => f.toLowerCase().endsWith('.flac'));
|
||||
|
||||
if (flacFiles.length === 0) {
|
||||
return NextResponse.json({ error: 'No FLAC files found' }, { status: 400 });
|
||||
}
|
||||
|
||||
let outputLog = "";
|
||||
let failureCount = 0;
|
||||
let checkedCount = 0;
|
||||
|
||||
// Check all 24-bit files
|
||||
for (const file of flacFiles) {
|
||||
const filePath = path.join(albumPath, file);
|
||||
|
||||
try {
|
||||
// Check bit depth first
|
||||
const metadata = await mm.parseFile(filePath);
|
||||
const bitsPerSample = metadata.format.bitsPerSample || 16;
|
||||
|
||||
if (bitsPerSample < 24) {
|
||||
continue; // Skip non-24-bit files
|
||||
}
|
||||
|
||||
checkedCount++;
|
||||
const command = `salmon check upconv "${filePath}"`;
|
||||
const { stdout } = await execPromise(command);
|
||||
|
||||
// Output example: "01...flac: does not have a high number of wasted bits (Wasted bits: 0/24)"
|
||||
const match = stdout.match(/Wasted bits: (\d+\/\d+)/);
|
||||
const wastedBits = match ? match[1] : 'Unknown';
|
||||
|
||||
// Determine pass/fail based on wasted bits (simplified logic: if wasted bits > 0, it might be upconv, but usually salmon says "has a high number..." if it fails)
|
||||
// Actually salmon output usually says "does not have a high number..." for pass.
|
||||
// Let's rely on the text "does not have a high number".
|
||||
const passed = stdout.includes('does not have a high number');
|
||||
|
||||
outputLog += `[${file}]: ${passed ? "OK" : "POSSIBLE UPCONV"} (${wastedBits})\n`;
|
||||
|
||||
if (!passed) {
|
||||
failureCount++;
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
outputLog += `[${file}]: Error - ${errorMessage}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkedCount === 0) {
|
||||
const response: CheckUpconvResponse = {
|
||||
success: true,
|
||||
output: "No 24-bit files found to check.",
|
||||
wastedBits: "N/A"
|
||||
};
|
||||
return NextResponse.json(response);
|
||||
}
|
||||
|
||||
const response: CheckUpconvResponse = {
|
||||
success: true,
|
||||
output: outputLog,
|
||||
wastedBits: failureCount > 0 ? "Issues Found" : "Clean"
|
||||
};
|
||||
return NextResponse.json(response);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error checking upconv:', error);
|
||||
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user