anycoder-79d7d0e1 / index.js
Wahso's picture
Upload index.js with huggingface_hub
0e33261 verified
Raw
History Blame Contribute Delete
4.31 kB
/**
* Video Subtitle OCR Application
* Extracts hard-coded subtitles from videos using transformers.js OCR
*/
import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.0';
// Configure transformers.js
env.allowLocalModels = false;
env.useBrowserCache = true;
// ============================================
// STATE MANAGEMENT
// ============================================
const state = {
// Video
videoFile: null,
videoDuration: 0,
videoWidth: 0,
videoHeight: 0,
// Subtitle Box
subtitleBox: {
x: 10, // percentage
y: 75, // percentage
width: 80, // percentage
height: 15, // percentage
aspectRatio: 5.33
},
isDragging: false,
isResizing: false,
resizeHandle: null,
dragStart: { x: 0, y: 0, boxX: 0, boxY: 0 },
// Language
selectedLanguage: 'eng',
// Time Range
startTime: 0,
endTime: 0,
// Processing
ocrPipeline: null,
isProcessing: false,
processingCancelled: false,
// Results
subtitles: [],
currentSubtitleIndex: -1
};
// Language configurations for OCR
const LANGUAGE_CONFIGS = {
eng: { name: 'English', code: 'en' },
jpn: { name: 'Japanese', code: 'ja' },
kor: { name: 'Korean', code: 'ko' },
chi_sim: { name: 'Chinese (Simplified)', code: 'zh' },
chi_tra: { name: 'Chinese (Traditional)', code: 'zh-Hant' },
tha: { name: 'Thai', code: 'th' }
};
// ============================================
// DOM ELEMENTS
// ============================================
const elements = {
// Pages
setupPage: document.getElementById('setup-page'),
processingPage: document.getElementById('processing-page'),
resultsPage: document.getElementById('results-page'),
// Upload
uploadZone: document.getElementById('upload-zone'),
videoInput: document.getElementById('video-input'),
// Preview
previewSection: document.getElementById('preview-section'),
videoPreview: document.getElementById('video-preview'),
subtitleOverlay: document.getElementById('subtitle-overlay'),
subtitleBox: document.getElementById('subtitle-box'),
// Controls
xPosition: document.getElementById('x-position'),
yPosition: document.getElementById('y-position'),
width: document.getElementById('width'),
height: document.getElementById('height'),
xValue: document.getElementById('x-value'),
yValue: document.getElementById('y-value'),
widthValue: document.getElementById('width-value'),
heightValue: document.getElementById('height-value'),
aspectLock: document.getElementById('aspect-lock'),
resetBox: document.getElementById('reset-box'),
autoDetect: document.getElementById('auto-detect'),
// Language
languageSection: document.getElementById('language-section'),
langButtons: document.querySelectorAll('.lang-btn'),
// Time
timeSection: document.getElementById('time-section'),
startHours: document.getElementById('start-hours'),
startMinutes: document.getElementById('start-minutes'),
startSeconds: document.getElementById('start-seconds'),
startMs: document.getElementById('start-ms'),
endHours: document.getElementById('end-hours'),
endMinutes: document.getElementById('end-minutes'),
endSeconds: document.getElementById('end-seconds'),
endMs: document.getElementById('end-ms'),
setStartCurrent: document.getElementById('set-start-current'),
setEndCurrent: document.getElementById('set-end-current'),
timeRangeSlider: document.getElementById('time-range-slider'),
rangeFill: document.getElementById('range-fill'),
startThumb: document.getElementById('start-thumb'),
endThumb: document.getElementById('end-thumb'),
sliderStartTime: document.getElementById('slider-start-time'),
sliderEndTime: document.getElementById('slider-end-time'),
// Process
processSection: document.getElementById('process-section'),
processBtn: document.getElementById('process-btn'),
// Processing
progressFill: document.getElementById('progress-fill'),
progressText: document.getElementById('progress-text'),
progressPercent: document.getElementById('progress-percent'),
frames