Split quality and frame rate into separate columns. Files now display quality and fps in separate columns for cleaner presentation.
This commit is contained in:
parent
be050b0057
commit
220cbe1e0b
@ -128,7 +128,7 @@
|
|||||||
background-color: #f8f9fa;
|
background-color: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-duration, .file-quality {
|
.file-duration, .file-quality, .file-fps {
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
color: #666;
|
color: #666;
|
||||||
min-width: 80px; /* Ensure consistent column width */
|
min-width: 80px; /* Ensure consistent column width */
|
||||||
|
|||||||
@ -71,6 +71,7 @@ function displayFiles(files) {
|
|||||||
// Use actual duration from file metadata
|
// Use actual duration from file metadata
|
||||||
const duration = file.duration || '00:00';
|
const duration = file.duration || '00:00';
|
||||||
const quality = file.quality || 'unknown';
|
const quality = file.quality || 'unknown';
|
||||||
|
const fps = file.fps || 'unknown';
|
||||||
|
|
||||||
// Add label for problematic files
|
// Add label for problematic files
|
||||||
const problemLabel = file.isProblematic ? '<span class="problematic-label">⚠️</span> ' : '';
|
const problemLabel = file.isProblematic ? '<span class="problematic-label">⚠️</span> ' : '';
|
||||||
@ -79,6 +80,7 @@ function displayFiles(files) {
|
|||||||
<div class="file-name" data-file-path="${file.path}">${problemLabel}${file.name}</div>
|
<div class="file-name" data-file-path="${file.path}">${problemLabel}${file.name}</div>
|
||||||
<div class="file-duration">${duration}</div>
|
<div class="file-duration">${duration}</div>
|
||||||
<div class="file-quality">${quality}</div>
|
<div class="file-quality">${quality}</div>
|
||||||
|
<div class="file-fps">${fps}</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Add click event to make file name editable
|
// Add click event to make file name editable
|
||||||
|
|||||||
@ -56,9 +56,12 @@ async function scanDirectory(directoryPath) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const quality = await extractVideoQuality(filePath);
|
const quality = await extractVideoQuality(filePath);
|
||||||
fileData.quality = quality;
|
fileData.quality = quality.quality;
|
||||||
|
fileData.fps = quality.fps;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to extract quality for ${filePath}:`, error.message);
|
console.warn(`Failed to extract quality for ${filePath}:`, error.message);
|
||||||
|
fileData.quality = 'unknown';
|
||||||
|
fileData.fps = 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaFiles.push(fileData);
|
mediaFiles.push(fileData);
|
||||||
@ -118,14 +121,14 @@ async function extractFileDuration(filePath) {
|
|||||||
/**
|
/**
|
||||||
* Extract video quality information using ffmpeg
|
* Extract video quality information using ffmpeg
|
||||||
* @param {string} filePath - Path to the media file
|
* @param {string} filePath - Path to the media file
|
||||||
* @returns {Promise<string>} - Quality information (e.g., "1080p30fps")
|
* @returns {Promise<Object>} - Quality and frame rate information
|
||||||
*/
|
*/
|
||||||
async function extractVideoQuality(filePath) {
|
async function extractVideoQuality(filePath) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
ffmpeg.ffprobe(filePath, (err, metadata) => {
|
ffmpeg.ffprobe(filePath, (err, metadata) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.warn(`ffprobe error for quality extraction ${filePath}:`, err.message);
|
console.warn(`ffprobe error for quality extraction ${filePath}:`, err.message);
|
||||||
resolve('unknown');
|
resolve({ quality: 'unknown', fps: 'unknown' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +137,7 @@ async function extractVideoQuality(filePath) {
|
|||||||
const videoStream = metadata.streams.find(stream => stream.codec_type === 'video');
|
const videoStream = metadata.streams.find(stream => stream.codec_type === 'video');
|
||||||
|
|
||||||
if (!videoStream) {
|
if (!videoStream) {
|
||||||
resolve('unknown');
|
resolve({ quality: 'unknown', fps: 'unknown' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +162,7 @@ async function extractVideoQuality(filePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get frame rate
|
// Get frame rate
|
||||||
let fps = '';
|
let fps = 'unknown';
|
||||||
if (videoStream.r_frame_rate) {
|
if (videoStream.r_frame_rate) {
|
||||||
// Parse frame rate like "30/1" or "25/1"
|
// Parse frame rate like "30/1" or "25/1"
|
||||||
const fpsParts = videoStream.r_frame_rate.split('/');
|
const fpsParts = videoStream.r_frame_rate.split('/');
|
||||||
@ -172,19 +175,11 @@ async function extractVideoQuality(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the quality string
|
// Return both quality and fps
|
||||||
if (quality !== 'unknown' && fps) {
|
resolve({ quality: quality, fps: fps });
|
||||||
resolve(`${quality}${fps}`);
|
|
||||||
} else if (quality !== 'unknown') {
|
|
||||||
resolve(quality);
|
|
||||||
} else if (fps) {
|
|
||||||
resolve(fps);
|
|
||||||
} else {
|
|
||||||
resolve('unknown');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Error extracting quality for ${filePath}:`, error.message);
|
console.warn(`Error extracting quality for ${filePath}:`, error.message);
|
||||||
resolve('unknown');
|
resolve({ quality: 'unknown', fps: 'unknown' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user