Files
dvc-cli/app.ts
2025-11-08 19:41:20 +03:00

130 lines
3.8 KiB
TypeScript

#!/usr/bin/env bun
/**
* Quick test script to verify the library works
*
* Usage:
* bun run test.ts <input-video> [output-dir]
*
* Example:
* bun run test.ts ./video.mp4 ./output
*/
import { convertToDash, checkFFmpeg, checkNvenc, checkMP4Box } from './src/index';
import cliProgress from 'cli-progress';
const input = process.argv[2];
const outputDir = process.argv[3] || './output';
if (!input) {
console.error('❌ Usage: bun run test.ts <input-video> [output-dir]');
process.exit(1);
}
console.log('🔍 Checking system...\n');
const hasFFmpeg = await checkFFmpeg();
const hasNvenc = await checkNvenc();
const hasMP4Box = await checkMP4Box();
console.log(`FFmpeg: ${hasFFmpeg ? '✅' : '❌'}`);
console.log(`NVENC: ${hasNvenc ? '✅ (GPU acceleration)' : '⚠️ (CPU only)'}`);
console.log(`MP4Box: ${hasMP4Box ? '✅' : '❌'}\n`);
if (!hasFFmpeg) {
console.error('❌ FFmpeg not found. Please install FFmpeg first.');
process.exit(1);
}
if (!hasMP4Box) {
console.error('❌ MP4Box not found. Please install: sudo pacman -S gpac');
process.exit(1);
}
console.log(`📹 Input: ${input}`);
console.log(`📁 Output: ${outputDir}\n`);
console.log('🚀 Starting conversion...\n');
// Create multibar container
const multibar = new cliProgress.MultiBar({
format: '{stage} | {bar} | {percentage}% | {name}',
barCompleteChar: '█',
barIncompleteChar: '░',
hideCursor: true,
clearOnComplete: false,
stopOnComplete: true
}, cliProgress.Presets.shades_classic);
// Track progress bars for each profile
const bars: Record<string, any> = {};
let overallBar: any = null;
try {
const result = await convertToDash({
input,
outputDir,
segmentDuration: 2,
useNvenc: hasNvenc,
generateThumbnails: true,
parallel: true,
onProgress: (progress) => {
const stageName = progress.stage === 'encoding' ? 'Encoding' :
progress.stage === 'thumbnails' ? 'Thumbnails' :
progress.stage === 'manifest' ? 'Manifest' :
progress.stage === 'analyzing' ? 'Analyzing' : 'Complete';
// Stage 1: Encoding - show individual profile bars
if (progress.stage === 'encoding' && progress.currentProfile) {
if (!bars[progress.currentProfile]) {
bars[progress.currentProfile] = multibar.create(100, 0, {
stage: 'Encode',
name: progress.currentProfile
});
}
// Use profilePercent (0-100) for individual bars, not overall percent
const profileProgress = progress.profilePercent ?? progress.percent;
bars[progress.currentProfile].update(profileProgress, {
stage: 'Encode',
name: progress.currentProfile
});
}
// Overall progress bar
if (!overallBar) {
overallBar = multibar.create(100, 0, {
stage: stageName,
name: 'Overall'
});
}
overallBar.update(progress.percent, {
stage: stageName,
name: progress.message || 'Overall'
});
}
});
multibar.stop();
console.log('\n✅ Conversion completed successfully!\n');
console.log('📊 Results:');
console.log(` Manifest: ${result.manifestPath}`);
console.log(` Duration: ${result.duration.toFixed(2)}s`);
console.log(` Profiles: ${result.profiles.map(p => p.name).join(', ')}`);
console.log(` Encoder: ${result.usedNvenc ? '⚡ NVENC (GPU)' : '🔧 libx264 (CPU)'}`);
if (result.thumbnailSpritePath) {
console.log(` Thumbnails: ${result.thumbnailSpritePath}`);
console.log(` VTT file: ${result.thumbnailVttPath}`);
}
console.log('\n🎉 Done! You can now use the manifest file in your video player.');
} catch (error) {
multibar.stop();
console.error('\n\n❌ Error during conversion:');
console.error(error);
process.exit(1);
}