130 lines
3.8 KiB
TypeScript
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);
|
||
|
|
}
|
||
|
|
|