test-batch-metadata.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env node
  2. /**
  3. * Test script for batch metadata extraction
  4. * Tests the new optimized batch API vs individual requests
  5. */
  6. const { spawn } = require('child_process');
  7. const path = require('path');
  8. // Test URLs from TESTING_GUIDE.md
  9. const testUrls = [
  10. 'https://www.youtube.com/watch?v=jNQXAC9IVRw',
  11. 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
  12. 'https://www.youtube.com/watch?v=9bZkp7q19f0',
  13. 'https://www.youtube.com/watch?v=_OBlgSz8sSM'
  14. ];
  15. function getBinaryPath(name) {
  16. const ext = process.platform === 'win32' ? '.exe' : '';
  17. return path.join(__dirname, 'binaries', `${name}${ext}`);
  18. }
  19. function runCommand(command, args) {
  20. return new Promise((resolve, reject) => {
  21. const process = spawn(command, args);
  22. let output = '';
  23. let error = '';
  24. process.stdout.on('data', (data) => {
  25. output += data.toString();
  26. });
  27. process.stderr.on('data', (data) => {
  28. error += data.toString();
  29. });
  30. process.on('close', (code) => {
  31. if (code === 0) {
  32. resolve(output);
  33. } else {
  34. reject(new Error(error));
  35. }
  36. });
  37. });
  38. }
  39. async function testIndividualMetadata(urls) {
  40. console.log('\n🔍 Testing INDIVIDUAL metadata extraction...');
  41. const ytDlpPath = getBinaryPath('yt-dlp');
  42. const startTime = Date.now();
  43. const results = [];
  44. for (const url of urls) {
  45. try {
  46. const args = [
  47. '--dump-json',
  48. '--no-warnings',
  49. '--skip-download',
  50. '--ignore-errors',
  51. '--extractor-args', 'youtube:skip=hls,dash',
  52. url
  53. ];
  54. const output = await runCommand(ytDlpPath, args);
  55. const metadata = JSON.parse(output);
  56. results.push({
  57. url,
  58. title: metadata.title,
  59. duration: metadata.duration
  60. });
  61. } catch (error) {
  62. console.error(` ❌ Failed to fetch ${url}:`, error.message);
  63. }
  64. }
  65. const duration = Date.now() - startTime;
  66. const avgTime = duration / urls.length;
  67. console.log(` ✅ Fetched ${results.length}/${urls.length} videos`);
  68. console.log(` ⏱️ Total time: ${duration}ms`);
  69. console.log(` 📊 Average per video: ${avgTime.toFixed(1)}ms`);
  70. return { results, duration, avgTime };
  71. }
  72. async function testBatchMetadata(urls) {
  73. console.log('\n🚀 Testing BATCH metadata extraction...');
  74. const ytDlpPath = getBinaryPath('yt-dlp');
  75. const startTime = Date.now();
  76. try {
  77. const args = [
  78. '--dump-json',
  79. '--no-warnings',
  80. '--skip-download',
  81. '--ignore-errors',
  82. '--extractor-args', 'youtube:skip=hls,dash',
  83. '--flat-playlist',
  84. ...urls
  85. ];
  86. const output = await runCommand(ytDlpPath, args);
  87. const lines = output.trim().split('\n');
  88. const results = [];
  89. for (const line of lines) {
  90. if (!line.trim()) continue;
  91. try {
  92. const metadata = JSON.parse(line);
  93. results.push({
  94. url: metadata.webpage_url || metadata.url,
  95. title: metadata.title,
  96. duration: metadata.duration
  97. });
  98. } catch (error) {
  99. console.error(' ⚠️ Failed to parse line');
  100. }
  101. }
  102. const duration = Date.now() - startTime;
  103. const avgTime = duration / urls.length;
  104. console.log(` ✅ Fetched ${results.length}/${urls.length} videos`);
  105. console.log(` ⏱️ Total time: ${duration}ms`);
  106. console.log(` 📊 Average per video: ${avgTime.toFixed(1)}ms`);
  107. return { results, duration, avgTime };
  108. } catch (error) {
  109. console.error(' ❌ Batch fetch failed:', error.message);
  110. return { results: [], duration: 0, avgTime: 0 };
  111. }
  112. }
  113. async function main() {
  114. console.log('🧪 Batch Metadata Extraction Performance Test');
  115. console.log('============================================\n');
  116. console.log(`Testing with ${testUrls.length} YouTube URLs...\n`);
  117. try {
  118. // Test individual requests
  119. const individual = await testIndividualMetadata(testUrls);
  120. // Test batch request
  121. const batch = await testBatchMetadata(testUrls);
  122. // Compare results
  123. console.log('\n📈 Performance Comparison:');
  124. console.log('==========================');
  125. if (batch.duration > 0) {
  126. const speedup = ((individual.duration - batch.duration) / individual.duration * 100).toFixed(1);
  127. const timesFaster = (individual.duration / batch.duration).toFixed(1);
  128. console.log(`Individual: ${individual.duration}ms total (${individual.avgTime.toFixed(1)}ms avg)`);
  129. console.log(`Batch: ${batch.duration}ms total (${batch.avgTime.toFixed(1)}ms avg)`);
  130. console.log(`\n🎉 Batch is ${speedup}% faster (${timesFaster}x speedup)!`);
  131. } else {
  132. console.log('❌ Batch test failed, cannot compare');
  133. }
  134. console.log('\n✅ Test complete!');
  135. } catch (error) {
  136. console.error('❌ Test failed:', error);
  137. process.exit(1);
  138. }
  139. }
  140. main();