Spaces:
Running
on
A100
Running
on
A100
File size: 4,149 Bytes
ae238b3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
// Transcription limits and thresholds
// These constants are shared across components to ensure consistency
export const TRANSCRIPTION_LIMITS = {
// Duration limits (in seconds)
MIN_DURATION: 3, // Minimum recommended duration for accuracy
MAX_DURATION: 180, // Maximum recommended duration (3 minutes)
// File size limits (in MB)
MAX_FILE_SIZE: 100, // Maximum recommended file size
} as const;
export const WARNING_MESSAGES = {
TOO_SHORT: {
title: "Media Too Short",
message: "Your media file is less than 3 seconds long. This may result in reduced transcription accuracy due to insufficient context for the AI model. For best results, use media files at least 30 seconds long.",
},
TOO_LONG: {
title: "Media Too Long",
message: "Your media file is longer than 3 minutes. This may exceed server resources and could result in processing failures or timeouts. Consider trimming your media to under 3 minutes for optimal results.",
},
VERY_LARGE_FILE: {
title: "File Too Large",
message: "Your file exceeds the recommended 100MB limit. This may cause upload failures or processing timeouts. Please use a smaller file or compress your media before uploading.",
},
} as const;
type WarningType = keyof typeof WARNING_MESSAGES;
interface MediaInfo {
file: File;
duration?: number; // Duration in seconds, may not be available immediately
}
/**
* Get the duration of a media file
* Returns a promise that resolves with the duration in seconds
*/
export const getMediaDuration = (file: File): Promise<number> => {
return new Promise((resolve, reject) => {
const url = URL.createObjectURL(file);
if (file.type.startsWith('video/')) {
const video = document.createElement('video');
video.preload = 'metadata';
video.onloadedmetadata = () => {
URL.revokeObjectURL(url);
resolve(video.duration);
};
video.onerror = () => {
URL.revokeObjectURL(url);
reject(new Error('Failed to load video metadata'));
};
video.src = url;
} else if (file.type.startsWith('audio/')) {
const audio = document.createElement('audio');
audio.preload = 'metadata';
audio.onloadedmetadata = () => {
URL.revokeObjectURL(url);
resolve(audio.duration);
};
audio.onerror = () => {
URL.revokeObjectURL(url);
reject(new Error('Failed to load audio metadata'));
};
audio.src = url;
} else {
URL.revokeObjectURL(url);
reject(new Error('Unsupported media type'));
}
});
};
/**
* Check for transcription warnings based on file size and duration
* Returns an array of warning types that should be shown to the user
*/
export const checkTranscriptionWarnings = (mediaInfo: MediaInfo): WarningType[] => {
const warnings: WarningType[] = [];
const { file, duration } = mediaInfo;
// Check file size (convert to MB)
const fileSizeMB = file.size / (1024 * 1024);
if (fileSizeMB > TRANSCRIPTION_LIMITS.MAX_FILE_SIZE) {
warnings.push('VERY_LARGE_FILE');
}
// Check duration if available
if (duration !== undefined && !isNaN(duration)) {
if (duration < TRANSCRIPTION_LIMITS.MIN_DURATION) {
warnings.push('TOO_SHORT');
} else if (duration > TRANSCRIPTION_LIMITS.MAX_DURATION) {
warnings.push('TOO_LONG');
}
}
return warnings;
};
/**
* Format file size in a human-readable format
*/
export const formatFileSize = (bytes: number): string => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
};
/**
* Format duration in a human-readable format
*/
export const formatDuration = (seconds: number): string => {
if (isNaN(seconds) || seconds < 0) return 'Unknown';
const minutes = Math.floor(seconds / 60);
const remainingSeconds = Math.floor(seconds % 60);
if (minutes === 0) {
return `${remainingSeconds}s`;
} else {
return `${minutes}m ${remainingSeconds}s`;
}
};
|