MP4 to SCORM Converter

Convert your video files to SCORM packages with automatic completion tracking when users watch the video.

Drag & Drop your MP4 file here

or click to browse files

How It Works

1. Upload MP4

Drag and drop your file or click to browse

2. Configure SCORM

Set completion trigger and course details

3. Download Package

Get your ready-to-use SCORM 1.2 package

Course Completed!

You can now close this window.

`; // Create SCORM API implementation const scormAPI = `function SCORM_API() { this.LMSInitialize = this.Initialize = function() { try { return "true"; } catch (e) { return "false"; } }; this.LMSFinish = this.Terminate = function() { try { return "true"; } catch (e) { return "false"; } }; this.LMSGetValue = this.GetValue = function(element) { try { return localStorage.getItem(element) || ""; } catch (e) { return ""; } }; this.LMSSetValue = this.SetValue = function(element, value) { try { localStorage.setItem(element, value); return "true"; } catch (e) { return "false"; } }; this.LMSCommit = this.Commit = function() { try { return "true"; } catch (e) { return "false"; } }; this.LMSGetLastError = this.GetLastError = function() { return "0"; }; this.LMSGetErrorString = this.GetErrorString = function() { return "No error"; }; this.LMSGetDiagnostic = this.GetDiagnostic = function() { return "No diagnostics"; }; }`; // Add all files to zip zip.file('imsmanifest.xml', manifest); zip.file('index.html', htmlContent); zip.file('scorm.js', scormAPI); // Generate the zip file zip.generateAsync({type: 'blob'}).then(content => { resolve(content); }); }); } // Dropzone functionality const dropzone = document.getElementById('dropzone'); const fileInput = document.getElementById('fileInput'); const browseBtn = document.getElementById('browseBtn'); const playerSection = document.getElementById('playerSection'); const statusSection = document.getElementById('statusSection'); const fileName = document.getElementById('fileName'); const convertBtn = document.getElementById('convertBtn'); const downloadBtn = document.getElementById('downloadBtn'); const completionTrigger = document.getElementById('completionTrigger'); const percentageContainer = document.getElementById('percentageContainer'); const percentageSlider = document.getElementById('percentageSlider'); const percentageValue = document.getElementById('percentageValue'); let videoFile = null; let downloadUrl = null; // Handle file selection browseBtn.addEventListener('click', function() { fileInput.click(); }); fileInput.addEventListener('change', function(e) { if (this.files && this.files.length) { handleFile(this.files[0]); } }); // Handle drag and drop ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropzone.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { dropzone.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { dropzone.addEventListener(eventName, unhighlight, false); }); function highlight() { dropzone.classList.add('dropzone-active'); } function unhighlight() { dropzone.classList.remove('dropzone-active'); } dropzone.addEventListener('drop', (e) => { const dt = e.dataTransfer; const file = dt.files[0]; if (file && (file.type.includes('video/') || file.name.match(/\.(mp4|MP4|mp4v|MP4V|mpg4|MPG4)$/i))) { handleFile(file); } }); // Handle the selected file function handleFile(file) { // Reset file input to allow re-selecting same file fileInput.value = ''; if (!file.type.includes('video/') && !file.name.match(/\.(mp4|MP4|mp4v|MP4V|mpg4|MPG4)$/i)) { Swal.fire({ icon: 'error', title: 'Oops...', text: 'Please select a valid MP4 video file', confirmButtonColor: '#4f46e5' }); return; } videoFile = file; fileName.textContent = file.name; playerSection.classList.remove('hidden'); statusSection.classList.add('hidden'); // Create video element for preview const videoURL = URL.createObjectURL(file); const previewVideo = document.getElementById('previewVideo'); previewVideo.src = videoURL; document.getElementById('videoPreview').classList.remove('hidden'); // Reset any previous conversion state downloadUrl = null; } // Completion trigger selection completionTrigger.addEventListener('change', (e) => { if (e.target.value === 'percentage') { percentageContainer.classList.remove('hidden'); } else { percentageContainer.classList.add('hidden'); } }); // Percentage slider percentageSlider.addEventListener('input', (e) => { percentageValue.textContent = `${e.target.value}%`; }); // Convert to SCORM convertBtn.addEventListener('click', async () => { if (!videoFile) { alert('Please select a video file first'); return; } // Show loading state convertBtn.disabled = true; convertBtn.innerHTML = ` Processing... `; try { const options = { title: document.getElementById('courseTitle').value || 'Untitled Course', trigger: document.getElementById('completionTrigger').value, percentage: document.getElementById('percentageSlider').value || 50 }; const scormPackage = await generateSCORMPackage(videoFile, options); downloadUrl = window.URL.createObjectURL(scormPackage); // Create download link and trigger download const link = document.createElement('a'); link.href = downloadUrl; link.setAttribute('download', `${options.title.replace(/[^a-z0-9]/gi, '_')}.zip`); document.body.appendChild(link); link.click(); link.parentNode.removeChild(link); // Show success section playerSection.classList.add('hidden'); statusSection.classList.remove('hidden'); } catch (error) { console.error('Error:', error); Swal.fire({ icon: 'error', title: 'Conversion Failed', text: 'Error converting file. Please try again.', confirmButtonColor: '#4f46e5' }); } finally { convertBtn.disabled = false; convertBtn.innerHTML = feather.icons.package.toSvg({class: 'inline mr-2'}) + ' Convert to SCORM'; } }); // Download SCORM package (for the success section) downloadBtn.addEventListener('click', () => { if (downloadUrl) { const link = document.createElement('a'); link.href = downloadUrl; const title = document.getElementById('courseTitle').value || 'scorm_package'; link.setAttribute('download', `${title.replace(/[^a-z0-9]/gi, '_')}.zip`); document.body.appendChild(link); link.click(); link.parentNode.removeChild(link); } }); // Initialize on load document.addEventListener('DOMContentLoaded', () => { feather.replace(); // Set default course title const defaultTitle = 'My SCORM Course - ' + new Date().toLocaleDateString(); document.getElementById('courseTitle').value = defaultTitle; }); `; }